diff --git a/.gitignore b/.gitignore index 7380d5f5..85a001c9 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,5 @@ yarn-error.log* .pnp.loader.mjs yarn.lock -build-staging/ +#build-staging/ staging/ diff --git a/build-staging/404.html b/build-staging/404.html new file mode 100644 index 00000000..2e788748 --- /dev/null +++ b/build-staging/404.html @@ -0,0 +1,24 @@ + + + + + +Page Not Found | The Cwtch Handbook + + + + + + + + + + + + +
+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + + + \ No newline at end of file diff --git a/build-staging/assets/css/styles.08d53321.css b/build-staging/assets/css/styles.08d53321.css new file mode 100644 index 00000000..22953a10 --- /dev/null +++ b/build-staging/assets/css/styles.08d53321.css @@ -0,0 +1,2 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center,figcaption,figure,figure p a img{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_tbUL,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.sidebar_re4s,.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_S0QG>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q>:last-child,.footer__items{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.sidebarItemTitle_pO2u,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#8e64a5;--ifm-font-color-base:#281831;--ifm-navbar-background-color:#fdf3fc;--ifm-code-font-size:95%;--ifm-footer-background-color:#fdf3fc;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#dfb9de;--ifm-font-color-base:#fdf3fc;--ifm-navbar-background-color:#281831;--ifm-footer-background-color:#281831;--docusaurus-highlighted-code-line-bg:#0000004d}.ui-button{background-color:#fdf3fc;height:24px;width:24px}td>img{vertical-align:sub}figcaption{font-size:10px}h1[class*=" blogPostTitle"],h1[class^=blogPostTitle],h2[class^=blogPostTitle]{font-size:2rem}[data-theme=dark] +.icon{filter:invert(1)}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_b6E3,.sidebarLogo_isFc,.themedImage_ToTc,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedImage--dark_i4oU,[data-theme=light] .themedImage--light_HNdA{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docMainContainer_gTbr,.docPage__5DB{display:flex;width:100%}.docPage__5DB{flex:1 0}.docsWrapper_BCFX{display:flex;flex:1 0 auto}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.buttons_AeoN,.features_t9lD{align-items:center;display:flex}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.heroBanner_qdFl{background:url(/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg) top no-repeat;color:#fdf3fc;height:670px;overflow:hidden;padding:4rem 0;position:relative;text-align:center}.heroBanner_qdFl p{color:#fdf3fc;font-weight:700;text-shadow:-1px -1px 0 #281831,1px -1px 0 #281831,-1px 1px 0 #281831,1px 1px 0 #281831}.buttons_AeoN{justify-content:center}.button_JGCe{background-color:#8e64a5;color:#fdf3fc}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.features_t9lD{padding:2rem 0;width:100%}.featureSvg_GfXr{height:200px;width:200px}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.img_ev3q{height:auto}.admonition_LlT9{margin-bottom:1em}.admonitionHeading_tbUL{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.3rem}.admonitionHeading_tbUL code{text-transform:none}.admonitionIcon_kALy{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_kALy svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.blogPostFooterDetailsFull_mRVl{flex-direction:column}.tableOfContents_bqdL{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.searchBox_ZlJk{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_BlDH,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_m80_:focus,.expandButton_m80_:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_m80_{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_BlDH{transform:rotate(180deg)}.docSidebarContainer_b6E3{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_b3ry{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_Xe31{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_gTbr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_Uz_u{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_czyv{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:996px){.heroBanner_qdFl{padding:2rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/build-staging/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png b/build-staging/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png differ diff --git a/build-staging/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png b/build-staging/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png differ diff --git a/build-staging/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png b/build-staging/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png differ diff --git a/build-staging/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png b/build-staging/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png differ diff --git a/build-staging/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png b/build-staging/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png differ diff --git a/build-staging/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png b/build-staging/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png differ diff --git a/build-staging/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png b/build-staging/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png differ diff --git a/build-staging/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png b/build-staging/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png differ diff --git a/build-staging/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png b/build-staging/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png differ diff --git a/build-staging/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png b/build-staging/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png differ diff --git a/build-staging/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png b/build-staging/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png differ diff --git a/build-staging/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png b/build-staging/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png differ diff --git a/build-staging/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png b/build-staging/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png differ diff --git a/build-staging/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png b/build-staging/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png differ diff --git a/build-staging/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png b/build-staging/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png differ diff --git a/build-staging/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png b/build-staging/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png differ diff --git a/build-staging/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg b/build-staging/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg differ diff --git a/build-staging/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg b/build-staging/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg differ diff --git a/build-staging/assets/js/003ad223.d75008d1.js b/build-staging/assets/js/003ad223.d75008d1.js new file mode 100644 index 00000000..b37d61ed --- /dev/null +++ b/build-staging/assets/js/003ad223.d75008d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8073],{6533:e=>{e.exports=JSON.parse('{"title":"Appearance","slug":"/category/appearance","permalink":"/docs/category/appearance","navigation":{"previous":{"title":"An Introduction to Cwtch App Settings","permalink":"/docs/settings/introduction"},"next":{"title":"Change Language","permalink":"/docs/settings/appearance/change-language"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/017f0ba6.ffa97e44.js b/build-staging/assets/js/017f0ba6.ffa97e44.js new file mode 100644 index 00000000..bc523d90 --- /dev/null +++ b/build-staging/assets/js/017f0ba6.ffa97e44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9398],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),m=r,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||a;return n?i.createElement(h,o(o({ref:t},p),{},{components:n})):i.createElement(h,o({ref:t},p))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,o=new Array(a);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,o[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var i=n(7462),r=(n(7294),n(3905));const a={},o="Image Previews",s={unversionedId:"components/ui/image_previews",id:"components/ui/image_previews",title:"Image Previews",description:"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.",source:"@site/security/components/ui/image_previews.md",sourceDirName:"components/ui",slug:"/components/ui/image_previews",permalink:"/security/components/ui/image_previews",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Android Service",permalink:"/security/components/ui/android"},next:{title:"Input",permalink:"/security/components/ui/input"}},l={},c=[{value:"KnownRisks",id:"knownrisks",level:2},{value:"Other Applications and/or the OS Inferring Information from Images",id:"other-applications-andor-the-os-inferring-information-from-images",level:2},{value:"Malicious Images Crashing or otherwise Compromising Cwtch",id:"malicious-images--crashing-or-otherwise-compromising-cwtch",level:2},{value:"Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata",id:"malicious-images-rendering-differently-on-different-platforms-potentially-exposing-metadata",level:2}],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"image-previews"},"Image Previews"),(0,r.kt)("p",null,"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes."),(0,r.kt)("p",null,"For now, we only support single-image messages, and any image editing/cropping will have to be done in a separate application. As we mention in the filesharing FAQ, image files also frequently contain significant hidden metadata, and you should only share them with people you trust."),(0,r.kt)("h2",{id:"knownrisks"},"KnownRisks"),(0,r.kt)("h2",{id:"other-applications-andor-the-os-inferring-information-from-images"},"Other Applications and/or the OS Inferring Information from Images"),(0,r.kt)("p",null,"Images must be stored somewhere, and for now we have chosen to store them unencrypted on the file system. We have done this\nfor 2 reasons:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"In order to support more powerful file sharing schemes like rehosting we require the ability to efficiently\nscan files and deliver chunks - doing this through an encrypted database layer would harm performance."),(0,r.kt)("li",{parentName:"ol"},"This information always has to transit the application boundary (either via display drivers, or storing and viewing\nthe file in an external application) - there is nothing that Cwtch can do after that point in any case.")),(0,r.kt)("h2",{id:"malicious-images--crashing-or-otherwise-compromising-cwtch"},"Malicious Images Crashing or otherwise Compromising Cwtch"),(0,r.kt)("p",null,"Flutter uses Skia to render Images. While the underlying code is memory unsafe, it is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/google/skia/tree/main/fuzz"},"extensively fuzzed")," as part of regular development."),(0,r.kt)("p",null,"We also conduct our own fuzz testing of Cwtch components. In that analysis we found a single crash bug related\nto a malformed GIF file that caused the renderer to allocate a ridiculous amount of memory (and eventually be refused\nby the kernel). To prevent this from impacting Cwtch we have adopted the policy of always enabling a maximum ",(0,r.kt)("inlineCode",{parentName:"p"},"cacheWidth"),"\nand/or ",(0,r.kt)("inlineCode",{parentName:"p"},"cacheHeight")," for Image widgets."),(0,r.kt)("h2",{id:"malicious-images-rendering-differently-on-different-platforms-potentially-exposing-metadata"},"Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata"),(0,r.kt)("p",null,"Recently ",(0,r.kt)("a",{parentName:"p",href:"https://www.da.vidbuchanan.co.uk/widgets/pngdiff/"},"a bug was found in Apple's png parser")," which would cause an image to render differently on Apple devices as it would on non-Apple devices."),(0,r.kt)("p",null,"We conducted a few tests on our Mac builds and could not replicate this issue for Flutter (because all Flutter builds use Skia for rendering), however we will continue to include such cases in our testing corpus."),(0,r.kt)("p",null,"For now image previews will remain experimental and opt-in."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/01a85c17.fbcc85f1.js b/build-staging/assets/js/01a85c17.fbcc85f1.js new file mode 100644 index 00000000..ea8df306 --- /dev/null +++ b/build-staging/assets/js/01a85c17.fbcc85f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4013],{9058:(e,t,a)=>{a.d(t,{Z:()=>E});var l=a(7294),r=a(6010),n=a(7961),s=a(7524),i=a(9960),c=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function o(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,c.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function g(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function b(e){return l.createElement(u.Zo,{component:g,props:e})}function d(e){let{sidebar:t}=e;const a=(0,s.i)();return t?.items.length?"mobile"===a?l.createElement(b,{sidebar:t}):l.createElement(o,{sidebar:t}):null}function E(e){const{sidebar:t,toc:a,children:s,...i}=e,c=t&&t.items.length>0;return l.createElement(n.Z,i,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(d,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":c,"col--9 col--offset-1":!c}),itemScope:!0,itemType:"http://schema.org/Blog"},s),a&&l.createElement("div",{className:"col col--2"},a))))}},1223:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var l=a(7294),r=a(6010),n=a(5999);const s=()=>(0,n.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var i=a(1944),c=a(5281),m=a(9058),o=a(3008);const u={tag:"tag_Nnez"};function g(e){let{letterEntry:t}=e;return l.createElement("article",null,l.createElement("h2",null,t.letter),l.createElement("ul",{className:"padding--none"},t.tags.map((e=>l.createElement("li",{key:e.permalink,className:u.tag},l.createElement(o.Z,e))))),l.createElement("hr",null))}function b(e){let{tags:t}=e;const a=function(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[l]=t;return a.localeCompare(l)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}(t);return l.createElement("section",{className:"margin-vert--lg"},a.map((e=>l.createElement(g,{key:e.letter,letterEntry:e}))))}var d=a(197);function E(e){let{tags:t,sidebar:a}=e;const n=s();return l.createElement(i.FG,{className:(0,r.Z)(c.k.wrapper.blogPages,c.k.page.blogTagsListPage)},l.createElement(i.d,{title:n}),l.createElement(d.Z,{tag:"blog_tags_list"}),l.createElement(m.Z,{sidebar:a},l.createElement("h1",null,n),l.createElement(b,{tags:t})))}},3008:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(7294),r=a(6010),n=a(9960);const s={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function i(e){let{permalink:t,label:a,count:i}=e;return l.createElement(n.Z,{href:t,className:(0,r.Z)(s.tag,i?s.tagWithCount:s.tagRegular)},a,i&&l.createElement("span",null,i))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/06a743f0.61ee1f62.js b/build-staging/assets/js/06a743f0.61ee1f62.js new file mode 100644 index 00000000..f70a059b --- /dev/null +++ b/build-staging/assets/js/06a743f0.61ee1f62.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3080],{6502:s=>{s.exports=JSON.parse('{"label":"bindings","permalink":"/blog/tags/bindings","allTagsPath":"/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/081d7fe1.e8b72cc5.js b/build-staging/assets/js/081d7fe1.e8b72cc5.js new file mode 100644 index 00000000..5e0267b7 --- /dev/null +++ b/build-staging/assets/js/081d7fe1.e8b72cc5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5696],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),l=c(r),h=o,m=l["".concat(p,".").concat(h)]||l[h]||d[h]||a;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[l]="string"==typeof e?e:o,s[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},s="An Introduction to Cwtch Groups",i={unversionedId:"groups/introduction",id:"groups/introduction",title:"An Introduction to Cwtch Groups",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/introduction.md",sourceDirName:"groups",slug:"/groups/introduction",permalink:"/docs/groups/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/docs/category/groups"},next:{title:"Creating a New Group",permalink:"/docs/groups/create-group"}},p={},c=[{value:"How Groups Work Under the Hood",id:"how-groups-work-under-the-hood",level:2}],u={toc:c},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"an-introduction-to-cwtch-groups"},"An Introduction to Cwtch Groups"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Note: Metadata Resistant Group Communication is still an active research area and what is documented here\nwill likely change in the future.")),(0,o.kt)("p",null,"By default, Cwtch only supports peer-to-peer, online, chat. In order to support multi-party conversations, and offline\ndelivery, an (untrusted) third-party is required. We call these entities ",(0,o.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},'"servers"')),(0,o.kt)("p",null,"These servers can be set up by anyone and are intended to be always online. Most importantly, all communication with a\nserver is designed such that the server learns as little information as possible about the contents or metadata."),(0,o.kt)("p",null,"In many respects communication with a server is identical to communication with a regular Cwtch peer,\nall the same steps are taken however the server always acts as the inbound peer, and the outbound\npeer always uses newly generated ",(0,o.kt)("strong",{parentName:"p"},"ephemeral keypair")," - so that each server session is disconnected."),(0,o.kt)("p",null,"As such, peer-server conversations only differ in the ",(0,o.kt)("em",{parentName:"p"},"kinds")," of messages that are sent between the two parties,\nwith the server storing all messages that it receives and thus allowing any client to query for older messages."),(0,o.kt)("p",null,"The risk model associated with servers is more complicated that peer-to-peer communication, as such we currently\nrequire people who want to use servers within Cwtch to ",(0,o.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"opt-in to the Group Chat experiment"),"\nin order to add, manage and create groups on untrusted servers."),(0,o.kt)("h2",{id:"how-groups-work-under-the-hood"},"How Groups Work Under the Hood"),(0,o.kt)("p",null,"When a person wants to start a group conversation they first randomly generate a secret ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),". All group communication will be encrypted using this key."),(0,o.kt)("p",null,"Along with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),", the group creator also decides on a ",(0,o.kt)("strong",{parentName:"p"},"Cwtch Server")," to use as the host of the group.\nFor more information on how Servers authenticate themselves see ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/key_bundles.html"},"key bundles"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Identifier")," is generated using the group key and the group server and these three elements are packaged up\ninto an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections)."),(0,o.kt)("p",null,"To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts\ntheir message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and generates a cryptographic signature over the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Id"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Server"),"\nand the decrypted message (see: ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/message_formats.html"},"wire formats")," for more information)."),(0,o.kt)("p",null,"To receive message from the group, a profile connected to the server hosting the group and downloads ",(0,o.kt)("em",{parentName:"p"},"all")," messages (since\ntheir previous connection). Profiles then attempt to decrypt each message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and if successful attempt\nto verify the signature (see ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/server.html"},"Cwtch Servers")," ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/groups.html"},"Cwtch Groups")," for an overview of attacks and mitigations)."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/09058439.25ec1464.js b/build-staging/assets/js/09058439.25ec1464.js new file mode 100644 index 00000000..5083302a --- /dev/null +++ b/build-staging/assets/js/09058439.25ec1464.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4186],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||o;return a?n.createElement(m,s(s({ref:t},d),{},{components:a})):n.createElement(m,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const o={},s="Message Overlays",i={unversionedId:"components/ui/overlays",id:"components/ui/overlays",title:"Message Overlays",description:"Adapted from Notes on the Cwtch Chat API",source:"@site/security/components/ui/overlays.md",sourceDirName:"components/ui",slug:"/components/ui/overlays",permalink:"/security/components/ui/overlays",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Input",permalink:"/security/components/ui/input"},next:{title:"Deployment",permalink:"/security/deployment"}},l={},c=[{value:"Chat overlays, lists, and bulletins",id:"chat-overlays-lists-and-bulletins",level:2},{value:"Data structure",id:"data-structure",level:2},{value:"Chat Messages (Overlay 1)",id:"chat-messages-overlay-1",level:2},{value:"Invitations (Overlays 100 and 101)",id:"invitations-overlays-100-and-101",level:2},{value:"Lists / Bulletin Boards",id:"lists--bulletin-boards",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"message-overlays"},"Message Overlays"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/08-chatapi/"},"Adapted from: Discreet Log #8: Notes on the Cwtch Chat API")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note: This section covers overlay protocols on-top of the Cwtch protcol. For information on the Cwtch Protocol\nmessages themselves please see ",(0,r.kt)("a",{parentName:"strong",href:"/security/components/cwtch/message_formats"},"Message Formats"))),(0,r.kt)("p",null,"We envision Cwtch as a platform for providing an authenticated transport layer to higher-level applications.\nDevelopers are free to make their own choices about what application layer protocols to use,\nwhether they want bespoke binary message formats or just want to throw an HTTP library on top and call it a\nday. Cwtch can generate new keypairs for you (which become onion addresses; no need for any DNS registrations!)\nand you can REST assured that any data your application receives from the (anonymous communication)\nnetwork has been authenticated already."),(0,r.kt)("p",null,"For our current stack, messages are wrapped in a minimal JSON frame that adds\nsome contextual information about the message type.\nAnd because serialised JSON objects are just dictionaries, we can easily add more metadata later on as needed."),(0,r.kt)("h2",{id:"chat-overlays-lists-and-bulletins"},"Chat overlays, lists, and bulletins"),(0,r.kt)("p",null,'The original Cwtch alpha demoed "overlays": different ways of interpreting the same data channel,\ndepending on the structure of the atomic data itself. We included simple checklists and BBS/classified ads as overlays that could be viewed\nand shared with any Cwtch contact, be it a single peer or a group. The wire format looked like this:'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:1,d:"hey there!"}\n{o:2,d:"bread",l:"groceries"}\n{o:3,d:"garage sale",p:"[parent message signature]"}\n')),(0,r.kt)("p",null,"Overlay field ",(0,r.kt)("inlineCode",{parentName:"p"},"o")," determined if it was a chat (1), list (2), or bulletin (3) message.\nThe data field ",(0,r.kt)("inlineCode",{parentName:"p"},"d")," is overloaded, and lists/bulletins need additional information about what\ngroup/post they belong to. (We use message signatures in place of IDs to avoid things like message\nordering problems and maliciously crafted IDs. This is also how the Cwtch protocol communicates to the\nfront end which message is being acked.)"),(0,r.kt)("h2",{id:"data-structure"},"Data structure"),(0,r.kt)("p",null,"Implementing tree-structured data on top of a sequential message store comes with obvious\nperformance disadvantages. For example, consider the message view, which loads most-recent-messages first and only goes back far enough to fetch enough messages to fill the current viewport, in comparison with a (somewhat pathological) forum where almost every message is a child of the very first message in the history, which could have been gigs and gigs of data-ago. If the UI only displays top-level posts until the user expands them, we have to parse the entire history before we get enough info to display anything at all."),(0,r.kt)("p",null,'Another problem is that multiplexing all these overlays into one data store creates "holes" in the data that confuse ',(0,r.kt)("a",{parentName:"p",href:"https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html"},"lazy-loaded listviews")," and scrollbars. The message count may indicate there is a ton more information to display if the user simply scrolls, but when it actually gets fetched and parsed we might realize that none of it is relevant to the current overlay."),(0,r.kt)("p",null,"None of these problems are insurmountable, but they demonstrate a flaw in our initial assumptions about the nature of collaborative message flows and how we should be handling that data."),(0,r.kt)("h1",{id:"overlay-types"},"Overlay Types"),(0,r.kt)("p",null,"As stated above, overlays are specified in a very simple JSON format with the following structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'type ChatMessage struct {\n O int `json:"o"`\n D string `json:"d"`\n}\n')),(0,r.kt)("p",null,"Where O stands for ",(0,r.kt)("inlineCode",{parentName:"p"},"Overlay")," with the current supported overlays documented below:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"1: data is a chat string\n2: data is a list state/delta\n3: data is a bulletin state/delta\n100: contact suggestion; data is a peer onion address\n101: contact suggestion; data is a group invite string\n")),(0,r.kt)("h2",{id:"chat-messages-overlay-1"},"Chat Messages (Overlay 1)"),(0,r.kt)("p",null,"The most simple over is a chat message which simply contains raw, unprocessed chat message information."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:1,d:"got milk?"}\n')),(0,r.kt)("h2",{id:"invitations-overlays-100-and-101"},"Invitations (Overlays 100 and 101)"),(0,r.kt)("p",null,"Instead of receiving the invite as an incoming contact request at the profile level, new inline invites are shared with a particular contact/group, where they can be viewed and/or accepted later, even if they were initially rejected (potentially by accident)."),(0,r.kt)("p",null,"The wire format for these are equally simple:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}\n{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}\n')),(0,r.kt)("p",null,'This represents a departure from our original "overlays" thinking to a more action-oriented representation. The chat "overlay" can communicate that someone ',(0,r.kt)("em",{parentName:"p"},"did"),' something, even if it\'s paraphrased down to "added an item to a list," and the lists and bulletins and other beautifully chaotic data can have their state precomputed and stored separately. '),(0,r.kt)("h2",{id:"lists--bulletin-boards"},"Lists / Bulletin Boards"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note: Expected to be Defined in Cwtch Beta 1.5")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/0a9e402c.5921f26c.js b/build-staging/assets/js/0a9e402c.5921f26c.js new file mode 100644 index 00000000..f8980147 --- /dev/null +++ b/build-staging/assets/js/0a9e402c.5921f26c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6562],{3905:(e,t,i)=>{i.d(t,{Zo:()=>c,kt:()=>u});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var l=n.createContext({}),h=function(e){var t=n.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):r(r({},t),e)),i},c=function(e){var t=h(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=h(i),p=a,u=d["".concat(l,".").concat(p)]||d[p]||f[p]||o;return i?n.createElement(u,r(r({ref:t},c),{},{components:i})):n.createElement(u,r({ref:t},c))}));function u(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=i.length,r=new Array(o);r[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,r[1]=s;for(var h=2;h{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>f,frontMatter:()=>o,metadata:()=>s,toc:()=>h});var n=i(7462),a=(i(7294),i(3905));const o={sidebar_position:6},r="Sharing a File",s={unversionedId:"chat/share-file",id:"chat/share-file",title:"Sharing a File",description:"This feature requires Experiments Enabled and",source:"@site/docs/chat/share-file.md",sourceDirName:"chat",slug:"/chat/share-file",permalink:"/docs/chat/share-file",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-file.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Replying to a Message",permalink:"/docs/chat/reply-to-message"},next:{title:"Blocking a Contact",permalink:"/docs/chat/block-contact"}},l={},h=[{value:"How does file sharing with groups work? Are my files stored on a server somewhere?",id:"how-does-file-sharing-with-groups-work-are-my-files-stored-on-a-server-somewhere",level:2},{value:"Does that mean I have to be online to send a file?",id:"does-that-mean-i-have-to-be-online-to-send-a-file",level:2},{value:"Why are new contacts popping up in my list?",id:"why-are-new-contacts-popping-up-in-my-list",level:2},{value:"What is "SHA512"?",id:"what-is-sha512",level:2},{value:"Is there a file size limit?",id:"is-there-a-file-size-limit",level:2},{value:"What are these .manifest files?",id:"what-are-these-manifest-files",level:2},{value:"What about file metadata?",id:"what-about-file-metadata",level:2},{value:"Can I download files automatically?",id:"can-i-download-files-automatically",level:2}],c={toc:h},d="wrapper";function f(e){let{components:t,...i}=e;return(0,a.kt)(d,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"sharing-a-file"},"Sharing a File"),(0,a.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"This feature requires ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"File Sharing Experiment")," turned on."),(0,a.kt)("p",{parentName:"admonition"},"Optionally, you can enable ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," to see display shared image previews in the conversation window.")),(0,a.kt)("p",null,"In a Conversation,"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Click on the attachment icon"),(0,a.kt)("li",{parentName:"ol"},"Find the file you want to send"),(0,a.kt)("li",{parentName:"ol"},"Confirm you want to send it")),(0,a.kt)("h2",{id:"how-does-file-sharing-with-groups-work-are-my-files-stored-on-a-server-somewhere"},"How does file sharing with groups work? Are my files stored on a server somewhere?"),(0,a.kt)("p",null,"Files are sent through onion-to-onion Cwtch connections directly from the person offering the file to the person receiving it. The initial offer to send a file is posted as a standard Cwtch conversation/overlay message. For groups, this means that the initial offer (containing the filename, size, hash, and a nonce) is posted to the group server, but then each recipient connects to you individually to receive the actual file contents."),(0,a.kt)("h2",{id:"does-that-mean-i-have-to-be-online-to-send-a-file"},"Does that mean I have to be online to send a file?"),(0,a.kt)("p",null,'Yes. If the person offering the file goes offline, you will have to wait for them to come online to resume the file transfer. The underlying protocol splits the files into individually-requestable, verifiable chunks, so that in a future release you will be able to "rehost" a file posted to a group, and even download from multiple hosts at once (sort of like bittorrent).'),(0,a.kt)("h2",{id:"why-are-new-contacts-popping-up-in-my-list"},"Why are new contacts popping up in my list?"),(0,a.kt)("p",null,"This is due to how Cwtch currently handles connections from unknown addresses. Since posting a file to a group results in group members connecting to you directly, some of those members might not be in your contact list already and so their download connection to you will appear in your list as a contact request."),(0,a.kt)("h2",{id:"what-is-sha512"},'What is "SHA512"?'),(0,a.kt)("p",null,"SHA512 is a ",(0,a.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Cryptographic_hash_function"},"cryptographic hash")," that can be used to verify that the file you downloaded is a correct copy of the file that was offered. Cwtch does this verification for you automatically, but you're welcome to try it yourself! Note that we also include a random nonce with file offers, so people can't just ask you for any random hash you might have, or files from conversations they're not part of."),(0,a.kt)("h2",{id:"is-there-a-file-size-limit"},"Is there a file size limit?"),(0,a.kt)("p",null,"The current limit is 10 gigabytes per file."),(0,a.kt)("h2",{id:"what-are-these-manifest-files"},"What are these .manifest files?"),(0,a.kt)("p",null,"The .manifest files are used while downloading the file to verify that individual chunks are received correctly, and support resuming interrupted transfers. They also contain the info from the original file offer. You can safely delete them once the download is complete. On Android, the manifests are stored in the app's cache, and can be cleared through your system settings."),(0,a.kt)("h2",{id:"what-about-file-metadata"},"What about file metadata?"),(0,a.kt)("p",null,"We send the file's name as a suggestion and to help distinguish it from other file offers. The full path is stripped before sending the offer. You should be wary of hidden metadata that might be stored in the file itself, which varies depending on the file's format. For example, images might contain geolocation info and information about the camera that took them, and PDF files are notorious for containing hidden information such as the author's name or the machine they were created on. In general, you should only send and receive files with people you trust."),(0,a.kt)("h2",{id:"can-i-download-files-automatically"},"Can I download files automatically?"),(0,a.kt)("p",null,"If the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures experiment")," is enabled then Cwtch will automatically download images from accepted conversations"))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/0be9de06.e2a9d663.js b/build-staging/assets/js/0be9de06.e2a9d663.js new file mode 100644 index 00000000..d3733b53 --- /dev/null +++ b/build-staging/assets/js/0be9de06.e2a9d663.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7222],{390:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/api","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/0d64c1d9.74de1478.js b/build-staging/assets/js/0d64c1d9.74de1478.js new file mode 100644 index 00000000..e6ce936f --- /dev/null +++ b/build-staging/assets/js/0d64c1d9.74de1478.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8710],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>b});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):r(r({},t),e)),i},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(i),h=a,b=p["".concat(s,".").concat(h)]||p[h]||u[h]||o;return i?n.createElement(b,r(r({ref:t},d),{},{components:i})):n.createElement(b,r({ref:t},d))}));function b(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=i.length,r=new Array(o);r[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=i(7462),a=(i(7294),i(3905));const o={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"January 20, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"repliqate",permalink:"/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"How Cwtch Bindings are Built",id:"how-cwtch-bindings-are-built",level:2},{value:"Making libCwtch Reproducible",id:"making-libcwtch-reproducible",level:2},{value:"Linux Specific Considerations",id:"linux-specific-considerations",level:3},{value:"Windows Specific Considerations",id:"windows-specific-considerations",level:3},{value:"Android Specific Considerations",id:"android-specific-considerations",level:3},{value:"OSX Specific Considerations",id:"osx-specific-considerations",level:3},{value:"Introducing Repliqate!",id:"introducing-repliqate",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...o}=e;return(0,a.kt)(p,(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,a.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,a.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,a.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,a.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."),(0,a.kt)("h2",{id:"how-cwtch-bindings-are-built"},"How Cwtch Bindings are Built"),(0,a.kt)("p",null,"Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process."),(0,a.kt)("p",null,"When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms."),(0,a.kt)("p",null,"The Cwtch Bindings build pipeline results in four compiled libraries:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.so")," \u2013 For Linux Platforms, built using the ",(0,a.kt)("a",{parentName:"li",href:"https://hub.docker.com/_/golang"},"official golang:1.19.X Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.dll")," \u2013 For Windows Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/mingw-go"},"mingw-go Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.ld")," \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"cwtch.aar")," \u2013 For Android Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/android-go-mobile"},"Android/GoMobile Docker Image"))),(0,a.kt)("p",null,"These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI."),(0,a.kt)("h2",{id:"making-libcwtch-reproducible"},"Making libCwtch Reproducible"),(0,a.kt)("p",null,"Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Go Build ID"),": By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Build Paths and Go Environment Variables"),": By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimPath")," option, which we now specify for all bindings builds.")),(0,a.kt)("h3",{id:"linux-specific-considerations"},"Linux Specific Considerations"),(0,a.kt)("p",null,"After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against."),(0,a.kt)("p",null,"Our Drone/Docker build environments are based on ",(0,a.kt)("a",{parentName:"p",href:"https://www.debian.org/releases/bullseye/"},"Debian Bullseye")," which provides ",(0,a.kt)("a",{parentName:"p",href:"https://packages.debian.org/bullseye/i386/libc6-dev"},"libc6-dev version 2.31"),". Other development setups will likely link libc-dev 2.34+."),(0,a.kt)("p",null,"libc6-dev 2.34 is notable ",(0,a.kt)("a",{parentName:"p",href:"https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread"},"because it removed dependencies on libpthread and libdl")," \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file."),(0,a.kt)("p",null,"This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on ",(0,a.kt)("a",{parentName:"p",href:"#next-steps"},"Next Steps")," for more information)."),(0,a.kt)("h3",{id:"windows-specific-considerations"},"Windows Specific Considerations"),(0,a.kt)("p",null,"The headers of PE files technically contain a timestamp field. In recent years an ",(0,a.kt)("a",{parentName:"p",href:"https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705"},"effort has been made to use this field for other purposes"),", but by default ",(0,a.kt)("inlineCode",{parentName:"p"},"go build")," will still include the timestamp of the file when producing a DLL file (at least when using CGO)."),(0,a.kt)("p",null,"Fortunately this field can be zeroed out through passing ",(0,a.kt)("inlineCode",{parentName:"p"},"-Xlinker \u2013no-insert-timestamp")," into the ",(0,a.kt)("inlineCode",{parentName:"p"},"mingw32-gcc")," process."),(0,a.kt)("p",null,"With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment."),(0,a.kt)("h3",{id:"android-specific-considerations"},"Android Specific Considerations"),(0,a.kt)("p",null,"With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Cwtch makes use of ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/golang/mobile"},"GoMobile")," for compiling Android libraries. We pin to a specific version ",(0,a.kt)("inlineCode",{parentName:"li"},"43a0384520996c8376bfb8637390f12b44773e65")," in our Docker containers. Unlike ",(0,a.kt)("inlineCode",{parentName:"li"},"go build"),", the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimpPath")," parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized ",(0,a.kt)("inlineCode",{parentName:"li"},"/tmp/go-build*")," references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced."),(0,a.kt)("li",{parentName:"ul"},"We still use ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/releases/sdk-tools"},"sdk-tools")," instead of the new ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/command-line"},"commandline-tools"),". The latest version of sdk-tools is ",(0,a.kt)("inlineCode",{parentName:"li"},"4333796")," and available from: ",(0,a.kt)("a",{parentName:"li",href:"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"},"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"),". As part of our plans for Cwtch Stable we will be updating this dependency."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated ",(0,a.kt)("inlineCode",{parentName:"li"},"openjdk:8")," image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. ")),(0,a.kt)("p",null,"All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles."),(0,a.kt)("h3",{id:"osx-specific-considerations"},"OSX Specific Considerations"),(0,a.kt)("p",null,"Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds."),(0,a.kt)("p",null,"As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine."),(0,a.kt)("p",null,"In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1."),(0,a.kt)("p",null,"In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a ",(0,a.kt)("a",{parentName:"p",href:"https://www.apple.com/legal/sla/docs/xcode.pdf"},"proprietary SDK"),". There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware."),(0,a.kt)("p",null,"Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions."),(0,a.kt)("h2",{id:"introducing-repliqate"},"Introducing Repliqate!"),(0,a.kt)("p",null,"With all the above changes, ",(0,a.kt)("strong",{parentName:"p"},"Cwtch Bindings for Linux and Windows are fully reproducible!")),(0,a.kt)("p",null,"That alone is great, but we also want to make it easier for ",(0,a.kt)("strong",{parentName:"p"},"you")," to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team."),(0,a.kt)("p",null,"To make this process accessible we are releasing a new tool called ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate"),"."),(0,a.kt)("p",null,"Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution."),(0,a.kt)("p",null,"Repliqate runs ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script"},"build-scripts")," to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"builds.openprivacy.ca"),"."),(0,a.kt)("p",null,"We now provide ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"Repliqate build-scripts")," for reproducible both ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script"},"Linux libCwtch.so builds"),", ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script"},"Windows libCwtch.dll builds"),"!"),(0,a.kt)("p",null,"We also have a partially repeatable ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script"},"Android cwtch.aar build")," script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section."),(0,a.kt)("p",null,"You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings."),(0,a.kt)("p",null,"As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!"),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4515:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/0e384e19.73b04fc3.js b/build-staging/assets/js/0e384e19.73b04fc3.js new file mode 100644 index 00000000..e5404a1b --- /dev/null +++ b/build-staging/assets/js/0e384e19.73b04fc3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9671],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=l(r),h=a,f=d["".concat(s,".").concat(h)]||d[h]||u[h]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:a,i[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:1},i="What is Cwtch?",c={unversionedId:"intro",id:"intro",title:"What is Cwtch?",description:"Cwtch (/k\u028at\u0283/ - a Welsh word roughly translating to \u201ca hug that creates a safe place\u201d) is a decentralized, privacy-preserving, metadata resistant messaging app.",source:"@site/docs/intro.md",sourceDirName:".",slug:"/intro",permalink:"/docs/intro",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/docs/category/getting-started"}},s={},l=[],p={toc:l},d="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"what-is-cwtch"},"What is Cwtch?"),(0,a.kt)("p",null,"Cwtch (/k\u028at\u0283/ - a Welsh word roughly translating to \u201ca hug that creates a safe place\u201d) is a decentralized, privacy-preserving, metadata resistant messaging app."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Decentralized and Open"),": There is no \u201cCwtch service\u201d or \u201cCwtch network\u201d. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Privacy Preserving"),": All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Metadata Resistant"),": Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.")),(0,a.kt)("h1",{id:"security-encryption-and-safety"},"Security, Encryption and Safety"),(0,a.kt)("p",null,"For a more in depth look at the security, privacy, and underlying encryption technology used in Cwtch, please\nconsult our ",(0,a.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Security Handbook")),(0,a.kt)("h1",{id:"getting-started"},"Getting Started"),(0,a.kt)("p",null,"You can download the latest version of Cwtch from ",(0,a.kt)("a",{parentName:"p",href:"https://cwtch.im/download/"},"https://cwtch.im/download/")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/0e3e2a9e.3b8ab0bf.js b/build-staging/assets/js/0e3e2a9e.3b8ab0bf.js new file mode 100644 index 00000000..1686e07b --- /dev/null +++ b/build-staging/assets/js/0e3e2a9e.3b8ab0bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9038],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>p});var r=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;e=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var M=r.createContext({}),u=function(t){var e=r.useContext(M),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},s=function(t){var e=u(t.components);return r.createElement(M.Provider,{value:e},t.children)},L="mdxType",w={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},l=r.forwardRef((function(t,e){var n=t.components,i=t.mdxType,o=t.originalType,M=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),L=u(n),l=i,p=L["".concat(M,".").concat(l)]||L[l]||w[l]||o;return n?r.createElement(p,a(a({ref:e},s),{},{components:n})):r.createElement(p,a({ref:e},s))}));function p(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var o=n.length,a=new Array(o);a[0]=l;var c={};for(var M in e)hasOwnProperty.call(e,M)&&(c[M]=e[M]);c.originalType=t,c[L]="string"==typeof t?t:i,a[1]=c;for(var u=2;u{n.r(e),n.d(e,{assets:()=>M,contentTitle:()=>a,default:()=>w,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:10},a="Removing a Conversation",c={unversionedId:"chat/delete-contact",id:"chat/delete-contact",title:"Removing a Conversation",description:"This feature will result in irreversible deletion. This cannot be undone.",source:"@site/docs/chat/delete-contact.md",sourceDirName:"chat",slug:"/chat/delete-contact",permalink:"/docs/chat/delete-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/delete-contact.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Unblocking a Contact",permalink:"/docs/chat/unblock-contact"},next:{title:"Groups",permalink:"/docs/category/groups"}},M={},u=[],s={toc:u},L="wrapper";function w(t){let{components:e,...o}=t;return(0,i.kt)(L,(0,r.Z)({},s,o,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"removing-a-conversation"},"Removing a Conversation"),(0,i.kt)("admonition",{type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,i.kt)("strong",{parentName:"p"},"irreversible")," deletion. This ",(0,i.kt)("strong",{parentName:"p"},"cannot be undone"),".")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"In a chat with a contact, go to the conversation settings on the top right ",(0,i.kt)("span",{class:"icon"},(0,i.kt)("img",{src:n(5905).Z,width:"24",height:"24"}))),(0,i.kt)("li",{parentName:"ul"},"Scroll to the ",(0,i.kt)("strong",{parentName:"li"},"leave this conversation")," button, and press it."),(0,i.kt)("li",{parentName:"ul"},"You will be prompted to confirm if you want to leave the conversation. This action cannot be undone.")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}w.isMDXComponent=!0},5905:(t,e,n)=>{n.d(e,{Z:()=>r});const r="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyNS4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjQgMjQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJLnN0MHtmaWxsOm5vbmU7fQ0KPC9zdHlsZT4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0wLDBoMjR2MjRIMFYweiIvPg0KPGc+DQoJPHBhdGggZD0iTTEzLjYsMTMuOGMtMS0wLjItMi0wLjMtMi44LTAuM2MtMi43LDAtOCwxLjMtOCw0djJoOS44Yy0wLjMtMC42LTAuNC0xLjMtMC40LTIuMUMxMi4yLDE1LjksMTIuNywxNC43LDEzLjYsMTMuOHoiLz4NCgk8Y2lyY2xlIGN4PSIxMC44IiBjeT0iNy40IiByPSI0Ii8+DQo8L2c+DQo8cGF0aCBkPSJNMjEuMSwxNy45YzAtMC4xLDAtMC4zLDAtMC40YzAtMC4yLDAtMC4zLDAtMC40bDEtMC43YzAuMS0wLjEsMC4xLTAuMiwwLjEtMC4zbC0wLjktMS42Yy0wLjEtMC4xLTAuMi0wLjEtMC4zLTAuMWwtMS4xLDAuNQ0KCWMtMC4yLTAuMi0wLjUtMC4zLTAuOC0wLjRsLTAuMi0xLjJjMC0wLjEtMC4xLTAuMi0wLjItMC4yaC0xLjhjLTAuMSwwLTAuMiwwLjEtMC4yLDAuMmwtMC4yLDEuMmMtMC4zLDAuMS0wLjUsMC4zLTAuOCwwLjRsLTEuMS0wLjUNCgljLTAuMSwwLTAuMiwwLTAuMywwLjFMMTMuNCwxNmMtMC4xLDAuMSwwLDAuMiwwLjEsMC4zbDEsMC43YzAsMC4xLDAsMC4zLDAsMC40YzAsMC4xLDAsMC4zLDAsMC40bC0xLDAuN2MtMC4xLDAuMS0wLjEsMC4yLTAuMSwwLjMNCglsMC45LDEuNmMwLjEsMC4xLDAuMiwwLjEsMC4zLDAuMWwxLjEtMC41YzAuMiwwLjIsMC41LDAuMywwLjgsMC40bDAuMiwxLjJjMCwwLjEsMC4xLDAuMiwwLjIsMC4yaDEuOGMwLjEsMCwwLjItMC4xLDAuMi0wLjINCglsMC4yLTEuMmMwLjMtMC4xLDAuNS0wLjMsMC44LTAuNGwxLjEsMC41YzAuMSwwLDAuMiwwLDAuMy0wLjFsMC45LTEuNmMwLjEtMC4xLDAtMC4yLTAuMS0wLjNMMjEuMSwxNy45eiBNMTcuNywxOS4yDQoJYy0wLjksMC0xLjctMC44LTEuNy0xLjdjMC0wLjksMC44LTEuNywxLjctMS43YzAuOSwwLDEuNywwLjgsMS43LDEuN0MxOS40LDE4LjQsMTguNywxOS4yLDE3LjcsMTkuMnoiLz4NCjwvc3ZnPg0K"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1075f7cd.052af3ab.js b/build-staging/assets/js/1075f7cd.052af3ab.js new file mode 100644 index 00000000..893aa620 --- /dev/null +++ b/build-staging/assets/js/1075f7cd.052af3ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9899],{3905:(a,e,t)=>{t.d(e,{Zo:()=>N,kt:()=>h});var m=t(7294);function s(a,e,t){return e in a?Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[e]=t,a}function n(a,e){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var m=Object.getOwnPropertySymbols(a);e&&(m=m.filter((function(e){return Object.getOwnPropertyDescriptor(a,e).enumerable}))),t.push.apply(t,m)}return t}function p(a){for(var e=1;e=0||(s[t]=a[t]);return s}(a,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(a);for(m=0;m=0||Object.prototype.propertyIsEnumerable.call(a,t)&&(s[t]=a[t])}return s}var i=m.createContext({}),l=function(a){var e=m.useContext(i),t=e;return a&&(t="function"==typeof a?a(e):p(p({},e),a)),t},N=function(a){var e=l(a.components);return m.createElement(i.Provider,{value:e},a.children)},o="mdxType",k={inlineCode:"code",wrapper:function(a){var e=a.children;return m.createElement(m.Fragment,{},e)}},c=m.forwardRef((function(a,e){var t=a.components,s=a.mdxType,n=a.originalType,i=a.parentName,N=r(a,["components","mdxType","originalType","parentName"]),o=l(t),c=s,h=o["".concat(i,".").concat(c)]||o[c]||k[c]||n;return t?m.createElement(h,p(p({ref:e},N),{},{components:t})):m.createElement(h,p({ref:e},N))}));function h(a,e){var t=arguments,s=e&&e.mdxType;if("string"==typeof a||s){var n=t.length,p=new Array(n);p[0]=c;var r={};for(var i in e)hasOwnProperty.call(e,i)&&(r[i]=e[i]);r.originalType=a,r[o]="string"==typeof a?a:s,p[1]=r;for(var l=2;l{t.r(e),t.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>k,frontMatter:()=>n,metadata:()=>r,toc:()=>l});var m=t(7462),s=(t(7294),t(3905));const n={sidebar_position:2},p="Authentication Protocol",r={unversionedId:"components/tapir/authentication_protocol",id:"components/tapir/authentication_protocol",title:"Authentication Protocol",description:"Each peer, given an open connection $C$:",source:"@site/security/components/tapir/authentication_protocol.md",sourceDirName:"components/tapir",slug:"/components/tapir/authentication_protocol",permalink:"/security/components/tapir/authentication_protocol",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Packet Format",permalink:"/security/components/tapir/packet_format"},next:{title:"Cwtch",permalink:"/security/category/cwtch"}},i={},l=[{value:"Cryptographic Properties",id:"cryptographic-properties",level:3}],N={toc:l},o="wrapper";function k(a){let{components:e,...t}=a;return(0,s.kt)(o,(0,m.Z)({},N,t,{components:e,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"authentication-protocol"},"Authentication Protocol"),(0,s.kt)("p",null,"Each peer, given an open connection ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"C")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"C")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"))))),":"),(0,s.kt)("div",{className:"math math-display"},(0,s.kt)("span",{parentName:"div",className:"katex-display"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"p"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"h"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"m"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"r"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"P"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mi",{parentName:"msup"},"i")),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msup"},"P"),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow"},(0,s.kt)("mover",{parentName:"mo"},(0,s.kt)("mo",{parentName:"mover"},(0,s.kt)("mo",{parentName:"mo"},"=")),(0,s.kt)("mo",{parentName:"mover",stretchy:"false",lspace:"0em",rspace:"0em"},"?"))),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"L"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"e"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"I = \\mathrm{InitializeIdentity()} \\\\ I_e = \\mathrm{InitializeEphemeralIdentity()} \\\\ I,I_e \\rightarrow C \\\\ P,P_e \\leftarrow C \\\\ k = \\mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\\\ c = \\mathrm{E}(k, transcript.Commit()) \\\\ c \\rightarrow C \\\\ c_p \\leftarrow C\\\\ \\mathrm{D}(k, c_p) \\stackrel{?}{=} transcript.LatestCommit()")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeEphemeralIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.958em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P")),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8747em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"E"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},"))")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7167em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.4391em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"D"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},(0,s.kt)("span",{parentName:"span",className:"mop op-limits"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"1.153em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span"},(0,s.kt)("span",{parentName:"span",className:"mop"},"="))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.5669em",marginLeft:"0em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mclose mtight"},"?"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"L"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"a"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"es"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"tC"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")))))),(0,s.kt)("p",null,"The above represents a sketch protocol, in reality there are a few\nimplementation details worth pointing out:"),(0,s.kt)("p",null,"Once derived from the key derivation function (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\mathrm{KDF}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")))))),") the key\n(",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"k")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"k")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"))))),") is set ",(0,s.kt)("em",{parentName:"p"},"on")," the connection, meaning the authentication app doesn't\ndo the encryption or decryption explicitly."),(0,s.kt)("p",null,"The concatenation of parts of the 3DH exchange is strictly ordered:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"DH of the Long term identity of the outbound connection by the ephemeral\nkey of the inbound connection."),(0,s.kt)("li",{parentName:"ul"},"DH of the Long term identity of the inbound connection by the ephemeral\nkey of the outbound connection."),(0,s.kt)("li",{parentName:"ul"},"DH of the two ephemeral identities of the inbound and outbound connections.")),(0,s.kt)("p",null,"This strict ordering ensures both sides of the connection derive the ",(0,s.kt)("em",{parentName:"p"},"same"),"\nsession key. "),(0,s.kt)("h3",{id:"cryptographic-properties"},"Cryptographic Properties"),(0,s.kt)("p",null,"During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come\nfrom their peer (or at least, someone with possession of their peers secret key as it related to their onion address)."),(0,s.kt)("p",null,"Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and\nall encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant\nrepudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied\nthat a single message in the transcript must have originated from a peer, there is no way of linking any other message to\nthe session."),(0,s.kt)("p",null,"Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the\nsession key is made public it can be used to forge new messages in the transcript - and as such, any standalone\ntranscript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation."))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1252ef76.288a11c6.js b/build-staging/assets/js/1252ef76.288a11c6.js new file mode 100644 index 00000000..602d1cc9 --- /dev/null +++ b/build-staging/assets/js/1252ef76.288a11c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[815],{5566:e=>{e.exports=JSON.parse('{"label":"developer-documentation","permalink":"/blog/tags/developer-documentation","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/13bbad87.9e7d5b62.js b/build-staging/assets/js/13bbad87.9e7d5b62.js new file mode 100644 index 00000000..128bba35 --- /dev/null +++ b/build-staging/assets/js/13bbad87.9e7d5b62.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7531],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},y=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=c(n),y=o,h=p["".concat(l,".").concat(y)]||p[y]||d[y]||i;return n?r.createElement(h,s(s({ref:t},u),{},{components:n})):r.createElement(h,s({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,s=new Array(i);s[0]=y;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:o,s[1]=a;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},s="Key Bundles",a={unversionedId:"components/cwtch/key_bundles",id:"components/cwtch/key_bundles",title:"Key Bundles",description:"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary",source:"@site/security/components/cwtch/key_bundles.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/key_bundles",permalink:"/security/components/cwtch/key_bundles",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Message Formats",permalink:"/security/components/cwtch/message_formats"},next:{title:"Groups",permalink:"/security/components/cwtch/groups"}},l={},c=[{value:"Verifying Key Bundles",id:"verifying-key-bundles",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"key-bundles"},"Key Bundles"),(0,o.kt)("p",null,"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary\nto make Cwtch group communication secure and metadata resistant."),(0,o.kt)("p",null,"At the time of writing, key bundles are expected to contain 3 keys:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"A Tor v3 Onion Service Public Key for the Token Board (ed25519)- used to connect to the service over Tor to post and\nreceive messages."),(0,o.kt)("li",{parentName:"ol"},"A Tor v3 Onion Service Public Key for the Token Service (ed25519) - used to acquire tokens to post on the service via\na small proof-of-work exercise."),(0,o.kt)("li",{parentName:"ol"},"A Privacy Pass Public Key - used in the token acquisition process (a ristretto curve point) . See: ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"OPTR2019-01"))),(0,o.kt)("p",null,"The key bundle is signed and can be verified via the first v3 onion service key, thus binding it to that particular oninon\naddress."),(0,o.kt)("h2",{id:"verifying-key-bundles"},"Verifying Key Bundles"),(0,o.kt)("p",null,"Profiles who import server key bundles verify them using the following trust-on-first-use (TOFU) algorithm:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Verify the attached signature using the v3 onion address of the server. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"Check that every key type exists. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"If the profile has imported the server key bundle previously, assert that all the keys are the same. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"Save the keys to the servers contact entry.")),(0,o.kt)("p",null,"In the future this algorithm will likely be altered to allow the addition of new public keys (e.g. to allow\ntokens to be acquired via a Zcash address.)"),(0,o.kt)("p",null,'Technically, at steps (2) and (3() the server can be assumed to be malicious, having signed a valid key bundle that\ndoes not conform to the specifications. When groups are moved from "experimental" to "stable" such an action will\nresult in a warning being communicated to the profile.'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/141cdfa9.9bc9258c.js b/build-staging/assets/js/141cdfa9.9bc9258c.js new file mode 100644 index 00000000..96dd195f --- /dev/null +++ b/build-staging/assets/js/141cdfa9.9bc9258c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7293],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(a),m=n,h=u["".concat(c,".").concat(m)]||u[m]||f[m]||i;return a?r.createElement(h,o(o({ref:t},p),{},{components:a})):r.createElement(h,o({ref:t},p))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=a.length,o=new Array(i);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const i={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"April 6, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/blog/cwtch-stable-roadmap-update"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},u="wrapper";function f(e){let{components:t,...a}=e;return(0,n.kt)(u,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,n.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,n.kt)("p",null,"The Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/142f86d0.3d7e3bf1.js b/build-staging/assets/js/142f86d0.3d7e3bf1.js new file mode 100644 index 00000000..03a84306 --- /dev/null +++ b/build-staging/assets/js/142f86d0.3d7e3bf1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7538],{959:a=>{a.exports=JSON.parse('{"label":"autobindings","permalink":"/blog/tags/autobindings","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/14eb3368.5ac78d9e.js b/build-staging/assets/js/14eb3368.5ac78d9e.js new file mode 100644 index 00000000..b466bfa7 --- /dev/null +++ b/build-staging/assets/js/14eb3368.5ac78d9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9817],{1310:(e,t,a)=>{a.d(t,{Z:()=>E});var n=a(7462),r=a(7294),i=a(6010),l=a(5281),s=a(2802),c=a(8596),o=a(9960),m=a(5999),d=a(4996);function u(e){return r.createElement("svg",(0,n.Z)({viewBox:"0 0 24 24"},e),r.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const h={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,d.Z)("/");return r.createElement("li",{className:"breadcrumbs__item"},r.createElement(o.Z,{"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},r.createElement(u,{className:h.breadcrumbHomeIcon})))}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g(e){let{children:t,href:a,isLast:n}=e;const i="breadcrumbs__link";return n?r.createElement("span",{className:i,itemProp:"name"},t):a?r.createElement(o.Z,{className:i,href:a,itemProp:"item"},r.createElement("span",{itemProp:"name"},t)):r.createElement("span",{className:i},t)}function p(e){let{children:t,active:a,index:l,addMicrodata:s}=e;return r.createElement("li",(0,n.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,i.Z)("breadcrumbs__item",{"breadcrumbs__item--active":a})}),t,r.createElement("meta",{itemProp:"position",content:String(l+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?r.createElement("nav",{className:(0,i.Z)(l.k.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},r.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&r.createElement(b,null),e.map(((t,a)=>{const n=a===e.length-1;return r.createElement(p,{key:a,active:n,index:a,addMicrodata:!!t.href},r.createElement(g,{href:t.href,isLast:n},t.label))})))):null}},4228:(e,t,a)=>{a.r(t),a.d(t,{default:()=>y});var n=a(7294),r=a(1944),i=a(2802),l=a(4996),s=a(6010),c=a(9960),o=a(3919),m=a(5999);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:a}=e;return n.createElement(c.Z,{href:t,className:(0,s.Z)("card padding--lg",d.cardContainer)},a)}function h(e){let{href:t,icon:a,title:r,description:i}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,s.Z)("text--truncate",d.cardTitle),title:r},a," ",r),i&&n.createElement("p",{className:(0,s.Z)("text--truncate",d.cardDescription),title:i},i))}function b(e){let{item:t}=e;const a=(0,i.Wl)(t);return a?n.createElement(h,{href:a,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,m.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const a=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return n.createElement(h,{href:t.href,icon:a,title:t.label,description:t.description??r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(v,{item:t});case"category":return n.createElement(b,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function p(e){let{className:t}=e;const a=(0,i.jA)();return n.createElement(E,{items:a.items,className:t})}function E(e){const{items:t,className:a}=e;if(!t)return n.createElement(p,e);const r=(0,i.MN)(t);return n.createElement("section",{className:(0,s.Z)("row",a)},r.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}var f=a(49),N=a(3120),Z=a(4364),k=a(1310),_=a(2503);const L={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function T(e){let{categoryGeneratedIndex:t}=e;return n.createElement(r.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,l.Z)(t.image)})}function x(e){let{categoryGeneratedIndex:t}=e;const a=(0,i.jA)();return n.createElement("div",{className:L.generatedIndexPage},n.createElement(N.Z,null),n.createElement(k.Z,null),n.createElement(Z.Z,null),n.createElement("header",null,n.createElement(_.Z,{as:"h1",className:L.title},t.title),t.description&&n.createElement("p",null,t.description)),n.createElement("article",{className:"margin-top--lg"},n.createElement(E,{items:a.items,className:L.list})),n.createElement("footer",{className:"margin-top--lg"},n.createElement(f.Z,{previous:t.navigation.previous,next:t.navigation.next})))}function y(e){return n.createElement(n.Fragment,null,n.createElement(T,e),n.createElement(x,e))}},49:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7462),r=a(7294),i=a(5999),l=a(2244);function s(e){const{previous:t,next:a}=e;return r.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,i.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&r.createElement(l.Z,(0,n.Z)({},t,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),a&&r.createElement(l.Z,(0,n.Z)({},a,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,a)=>{a.d(t,{Z:()=>c});var n=a(7294),r=a(6010),i=a(5999),l=a(5281),s=a(4477);function c(e){let{className:t}=e;const a=(0,s.E)();return a.badge?n.createElement("span",{className:(0,r.Z)(t,l.k.docs.docVersionBadge,"badge badge--secondary")},n.createElement(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:a.label}},"Version: {versionLabel}")):null}},3120:(e,t,a)=>{a.d(t,{Z:()=>g});var n=a(7294),r=a(6010),i=a(2263),l=a(9960),s=a(5999),c=a(143),o=a(5281),m=a(373),d=a(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function h(e){const t=u[e.versionMetadata.banner];return n.createElement(t,e)}function b(e){let{versionLabel:t,to:a,onClick:r}=e;return n.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:n.createElement("b",null,n.createElement(l.Z,{to:a,onClick:r},n.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function v(e){let{className:t,versionMetadata:a}=e;const{siteConfig:{title:l}}=(0,i.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,m.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:v}=(0,c.Jo)(s),g=u??(p=v).docs.find((e=>e.id===p.mainDocId));var p;return n.createElement("div",{className:(0,r.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},n.createElement("div",null,n.createElement(h,{siteTitle:l,versionMetadata:a})),n.createElement("div",{className:"margin-top--md"},n.createElement(b,{versionLabel:v.label,to:g.path,onClick:()=>d(v.name)})))}function g(e){let{className:t}=e;const a=(0,d.E)();return a.banner?n.createElement(v,{className:t,versionMetadata:a}):null}},2503:(e,t,a)=>{a.d(t,{Z:()=>m});var n=a(7462),r=a(7294),i=a(6010),l=a(5999),s=a(6668),c=a(9960);const o={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function m(e){let{as:t,id:a,...m}=e;const{navbar:{hideOnScroll:d}}=(0,s.L)();if("h1"===t||!a)return r.createElement(t,(0,n.Z)({},m,{id:void 0}));const u=(0,l.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof m.children?m.children:a});return r.createElement(t,(0,n.Z)({},m,{className:(0,i.Z)("anchor",d?o.anchorWithHideOnScrollNavbar:o.anchorWithStickyNavbar,m.className),id:a}),m.children,r.createElement(c.Z,{className:"hash-link",to:`#${a}`,"aria-label":u,title:u},"\u200b"))}},2244:(e,t,a)=>{a.d(t,{Z:()=>l});var n=a(7294),r=a(6010),i=a(9960);function l(e){const{permalink:t,title:a,subLabel:l,isNext:s}=e;return n.createElement(i.Z,{className:(0,r.Z)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},l&&n.createElement("div",{className:"pagination-nav__sublabel"},l),n.createElement("div",{className:"pagination-nav__label"},a))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/15b89b76.0decb8fe.js b/build-staging/assets/js/15b89b76.0decb8fe.js new file mode 100644 index 00000000..82961d7c --- /dev/null +++ b/build-staging/assets/js/15b89b76.0decb8fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8392],{9610:s=>{s.exports=JSON.parse('{"label":"testing","permalink":"/blog/tags/testing","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/15d993af.c6cf4653.js b/build-staging/assets/js/15d993af.c6cf4653.js new file mode 100644 index 00000000..7d3e8759 --- /dev/null +++ b/build-staging/assets/js/15d993af.c6cf4653.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1174],{3170:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/cwtch","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/blog/tags/cwtch/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/16838ca5.676b1124.js b/build-staging/assets/js/16838ca5.676b1124.js new file mode 100644 index 00000000..435d3090 --- /dev/null +++ b/build-staging/assets/js/16838ca5.676b1124.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4704],{4674:a=>{a.exports=JSON.parse('{"label":"cwtch","permalink":"/blog/tags/cwtch","allTagsPath":"/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/17896441.27340309.js b/build-staging/assets/js/17896441.27340309.js new file mode 100644 index 00000000..d1e2980a --- /dev/null +++ b/build-staging/assets/js/17896441.27340309.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7918],{1310:(e,t,n)=>{n.d(t,{Z:()=>E});var a=n(7462),l=n(7294),o=n(6010),r=n(5281),s=n(2802),c=n(8596),i=n(9960),d=n(5999),m=n(4996);function u(e){return l.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},e),l.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const v={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,m.Z)("/");return l.createElement("li",{className:"breadcrumbs__item"},l.createElement(i.Z,{"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},l.createElement(u,{className:v.breadcrumbHomeIcon})))}const p={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function h(e){let{children:t,href:n,isLast:a}=e;const o="breadcrumbs__link";return a?l.createElement("span",{className:o,itemProp:"name"},t):n?l.createElement(i.Z,{className:o,href:n,itemProp:"item"},l.createElement("span",{itemProp:"name"},t)):l.createElement("span",{className:o},t)}function f(e){let{children:t,active:n,index:r,addMicrodata:s}=e;return l.createElement("li",(0,a.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,o.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n})}),t,l.createElement("meta",{itemProp:"position",content:String(r+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?l.createElement("nav",{className:(0,o.Z)(r.k.docs.docBreadcrumbs,p.breadcrumbsContainer),"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},l.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&l.createElement(b,null),e.map(((t,n)=>{const a=n===e.length-1;return l.createElement(f,{key:n,active:a,index:n,addMicrodata:!!t.href},l.createElement(h,{href:t.href,isLast:a},t.label))})))):null}},5154:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});var a=n(7294),l=n(1944),o=n(902);const r=a.createContext(null);function s(e){let{children:t,content:n}=e;const l=function(e){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return a.createElement(r.Provider,{value:l},t)}function c(){const e=(0,a.useContext)(r);if(null===e)throw new o.i6("DocProvider");return e}function i(){const{metadata:e,frontMatter:t,assets:n}=c();return a.createElement(l.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var d=n(6010),m=n(7524),u=n(49);function v(){const{metadata:e}=c();return a.createElement(u.Z,{previous:e.previous,next:e.next})}var b=n(3120),p=n(4364),h=n(5281),f=n(5999);function E(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:a.createElement("b",null,a.createElement("time",{dateTime:new Date(1e3*t).toISOString()},n))}}," on {date}")}function g(e){let{lastUpdatedBy:t}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:a.createElement("b",null,t)}}," by {user}")}function L(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:l}=e;return a.createElement("span",{className:h.k.common.lastUpdated},a.createElement(f.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?a.createElement(E,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:l?a.createElement(g,{lastUpdatedBy:l}):""}},"Last updated{atDate}{byUser}"),!1)}var C=n(4881),N=n(1526);const Z={lastUpdated:"lastUpdated_vwxv"};function k(e){return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterTagsRow,"row margin-bottom--sm")},a.createElement("div",{className:"col"},a.createElement(N.Z,e)))}function _(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:l,formattedLastUpdatedAt:o}=e;return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterEditMetaRow,"row")},a.createElement("div",{className:"col"},t&&a.createElement(C.Z,{editUrl:t})),a.createElement("div",{className:(0,d.Z)("col",Z.lastUpdated)},(n||l)&&a.createElement(L,{lastUpdatedAt:n,formattedLastUpdatedAt:o,lastUpdatedBy:l})))}function x(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:l,lastUpdatedBy:o,tags:r}=e,s=r.length>0,i=!!(t||n||o);return s||i?a.createElement("footer",{className:(0,d.Z)(h.k.docs.docFooter,"docusaurus-mt-lg")},s&&a.createElement(k,{tags:r}),i&&a.createElement(_,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:o,formattedLastUpdatedAt:l})):null}var T=n(6043),H=n(3743),U=n(7462);const y={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function A(e){let{collapsed:t,...n}=e;return a.createElement("button",(0,U.Z)({type:"button"},n,{className:(0,d.Z)("clean-btn",y.tocCollapsibleButton,!t&&y.tocCollapsibleButtonExpanded,n.className)}),a.createElement(f.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component"},"On this page"))}const w={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function M(e){let{toc:t,className:n,minHeadingLevel:l,maxHeadingLevel:o}=e;const{collapsed:r,toggleCollapsed:s}=(0,T.u)({initialState:!0});return a.createElement("div",{className:(0,d.Z)(w.tocCollapsible,!r&&w.tocCollapsibleExpanded,n)},a.createElement(A,{collapsed:r,onClick:s}),a.createElement(T.z,{lazy:!0,className:w.tocCollapsibleContent,collapsed:r},a.createElement(H.Z,{toc:t,minHeadingLevel:l,maxHeadingLevel:o})))}const I={tocMobile:"tocMobile_ITEo"};function B(){const{toc:e,frontMatter:t}=c();return a.createElement(M,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,d.Z)(h.k.docs.docTocMobile,I.tocMobile)})}var O=n(9407);function S(){const{toc:e,frontMatter:t}=c();return a.createElement(O.Z,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:h.k.docs.docTocDesktop})}var V=n(2503),P=n(1506);function D(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return a.createElement("div",{className:(0,d.Z)(h.k.docs.docMarkdown,"markdown")},n&&a.createElement("header",null,a.createElement(V.Z,{as:"h1"},n)),a.createElement(P.Z,null,t))}var R=n(1310);const F={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function z(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),l=e.hide_table_of_contents,o=!l&&t.length>0;return{hidden:l,mobile:o?a.createElement(B,null):void 0,desktop:!o||"desktop"!==n&&"ssr"!==n?void 0:a.createElement(S,null)}}();return a.createElement("div",{className:"row"},a.createElement("div",{className:(0,d.Z)("col",!n.hidden&&F.docItemCol)},a.createElement(b.Z,null),a.createElement("div",{className:F.docItemContainer},a.createElement("article",null,a.createElement(R.Z,null),a.createElement(p.Z,null),n.mobile,a.createElement(D,null,t),a.createElement(x,null)),a.createElement(v,null))),n.desktop&&a.createElement("div",{className:"col col--3"},n.desktop))}function j(e){const t=`docs-doc-id-${e.content.metadata.unversionedId}`,n=e.content;return a.createElement(s,{content:e.content},a.createElement(l.FG,{className:t},a.createElement(i,null),a.createElement(z,null,a.createElement(n,null))))}},49:(e,t,n)=>{n.d(t,{Z:()=>s});var a=n(7462),l=n(7294),o=n(5999),r=n(2244);function s(e){const{previous:t,next:n}=e;return l.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,o.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&l.createElement(r.Z,(0,a.Z)({},t,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),n&&l.createElement(r.Z,(0,a.Z)({},n,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,n)=>{n.d(t,{Z:()=>c});var a=n(7294),l=n(6010),o=n(5999),r=n(5281),s=n(4477);function c(e){let{className:t}=e;const n=(0,s.E)();return n.badge?a.createElement("span",{className:(0,l.Z)(t,r.k.docs.docVersionBadge,"badge badge--secondary")},a.createElement(o.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label}},"Version: {versionLabel}")):null}},3120:(e,t,n)=>{n.d(t,{Z:()=>h});var a=n(7294),l=n(6010),o=n(2263),r=n(9960),s=n(5999),c=n(143),i=n(5281),d=n(373),m=n(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function v(e){const t=u[e.versionMetadata.banner];return a.createElement(t,e)}function b(e){let{versionLabel:t,to:n,onClick:l}=e;return a.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:a.createElement("b",null,a.createElement(r.Z,{to:n,onClick:l},a.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function p(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:r}}=(0,o.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:m}=(0,d.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:p}=(0,c.Jo)(s),h=u??(f=p).docs.find((e=>e.id===f.mainDocId));var f;return a.createElement("div",{className:(0,l.Z)(t,i.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},a.createElement("div",null,a.createElement(v,{siteTitle:r,versionMetadata:n})),a.createElement("div",{className:"margin-top--md"},a.createElement(b,{versionLabel:p.label,to:h.path,onClick:()=>m(p.name)})))}function h(e){let{className:t}=e;const n=(0,m.E)();return n.banner?a.createElement(p,{className:t,versionMetadata:n}):null}},9407:(e,t,n)=>{n.d(t,{Z:()=>d});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",i="table-of-contents__link--active";function d(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(s.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:i})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>b});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function s(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=s({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function m(e){const t=(0,l.useRef)(void 0),n=d();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=i(s,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===d)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const v=l.memo(u);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:d,maxHeadingLevel:u,...b}=e;const p=(0,o.L)(),h=d??p.tableOfContents.minHeadingLevel,f=u??p.tableOfContents.maxHeadingLevel,E=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>s({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:h,maxHeadingLevel:f});return m((0,l.useMemo)((()=>{if(c&&i)return{linkClassName:c,linkActiveClassName:i,minHeadingLevel:h,maxHeadingLevel:f}}),[c,i,h,f])),l.createElement(v,(0,a.Z)({toc:E,className:n,linkClassName:c},b))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1944a0c9.67f57568.js b/build-staging/assets/js/1944a0c9.67f57568.js new file mode 100644 index 00000000..d4e32216 --- /dev/null +++ b/build-staging/assets/js/1944a0c9.67f57568.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9140],{2796:a=>{a.exports=JSON.parse('{"label":"security-handbook","permalink":"/blog/tags/security-handbook","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1a25c548.ad39b6db.js b/build-staging/assets/js/1a25c548.ad39b6db.js new file mode 100644 index 00000000..f6aad51d --- /dev/null +++ b/build-staging/assets/js/1a25c548.ad39b6db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5732],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=r,u=h["".concat(c,".").concat(m)]||h[m]||g[m]||o;return a?n.createElement(u,i(i({ref:t},p),{},{components:a})):n.createElement(u,i({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const o={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"January 6, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,r.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,r.kt)("strong",{parentName:"p"},"Beta")," to ",(0,r.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,r.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}g.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1af46bd3.2c226ae2.js b/build-staging/assets/js/1af46bd3.2c226ae2.js new file mode 100644 index 00000000..daa3c061 --- /dev/null +++ b/build-staging/assets/js/1af46bd3.2c226ae2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[962],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,f=u["".concat(s,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>a,metadata:()=>c,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:3},i="UI columns",c={unversionedId:"settings/appearance/ui-columns",id:"settings/appearance/ui-columns",title:"UI columns",description:"1. Press the settings icon",source:"@site/docs/settings/appearance/ui-columns.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/ui-columns",permalink:"/docs/settings/appearance/ui-columns",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/ui-columns.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Light/Dark and themes Breakdown",permalink:"/docs/settings/appearance/light-dark-mode"},next:{title:"Streamer/Presentation Mode",permalink:"/docs/settings/appearance/streamer-mode"}},s={},p=[],l={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"ui-columns"},"UI columns"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Press the settings icon"),(0,o.kt)("li",{parentName:"ol"},"Click on single"),(0,o.kt)("li",{parentName:"ol"},"Select the configuration of columns you want to use")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1b4ba274.735f448d.js b/build-staging/assets/js/1b4ba274.735f448d.js new file mode 100644 index 00000000..35dea7ed --- /dev/null +++ b/build-staging/assets/js/1b4ba274.735f448d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4052],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>b});var o=n(7294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}function a(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var l=o.createContext({}),s=function(t){var e=o.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},p=function(t){var e=s(t.components);return o.createElement(l.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return o.createElement(o.Fragment,{},e)}},y=o.forwardRef((function(t,e){var n=t.components,r=t.mdxType,i=t.originalType,l=t.parentName,p=c(t,["components","mdxType","originalType","parentName"]),u=s(n),y=r,b=u["".concat(l,".").concat(y)]||u[y]||f[y]||i;return n?o.createElement(b,a(a({ref:e},p),{},{components:n})):o.createElement(b,a({ref:e},p))}));function b(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var i=n.length,a=new Array(i);a[0]=y;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[u]="string"==typeof t?t:r,a[1]=c;for(var s=2;s{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:2},a="Notification policy",c={unversionedId:"settings/behaviour/notification-policy",id:"settings/behaviour/notification-policy",title:"Notification policy",description:"1. Go to settings",source:"@site/docs/settings/behaviour/notification-policy.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-policy",permalink:"/docs/settings/behaviour/notification-policy",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-policy.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Block Unknown Connections",permalink:"/docs/settings/behaviour/block-unknown-connections"},next:{title:"Notification Content",permalink:"/docs/settings/behaviour/notification-content"}},l={},s=[],p={toc:s},u="wrapper";function f(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"notification-policy"},"Notification policy"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Go to settings"),(0,r.kt)("li",{parentName:"ol"},"Scroll to behaviour"),(0,r.kt)("li",{parentName:"ol"},"The notification policy controls the notification behaviour"),(0,r.kt)("li",{parentName:"ol"},"Click on Default all to change the behaviour to opt in or to mute all\nnotifications"),(0,r.kt)("li",{parentName:"ol"},"Pick your preferred notification Policy")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1be78505.c2da882e.js b/build-staging/assets/js/1be78505.c2da882e.js new file mode 100644 index 00000000..fb0a6ec0 --- /dev/null +++ b/build-staging/assets/js/1be78505.c2da882e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9514,4972],{9963:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ge});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),c=n(3320),i=n(2802),s=n(4477),d=n(1116),m=n(7961),u=n(5999),b=n(2466),p=n(5936);const h={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};function E(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,l]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:r,cancelScroll:c}=(0,b.Ct)();return(0,b.RF)(((e,n)=>{let{scrollY:a}=e;const r=n?.scrollY;r&&(o.current?o.current=!1:a>=r?(c(),l(!1)):a{e.location.hash&&(o.current=!0,l(!1))})),{shown:n,scrollToTop:()=>r(0)}}({threshold:300});return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,l.Z)("clean-btn",r.k.common.backToTopButton,h.backToTopButton,e&&h.backToTopButtonShow),type:"button",onClick:t})}var f=n(1442),g=n(6550),k=n(7524),_=n(6668),v=n(1327),C=n(7462);function S(e){return a.createElement("svg",(0,C.Z)({width:"20",height:"20","aria-hidden":"true"},e),a.createElement("g",{fill:"#7a7a7a"},a.createElement("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),a.createElement("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})))}const I={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function N(e){let{onClick:t}=e;return a.createElement("button",{type:"button",title:(0,u.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,l.Z)("button button--secondary button--outline",I.collapseSidebarButton),onClick:t},a.createElement(S,{className:I.collapseSidebarButtonIcon}))}var T=n(9689),Z=n(902);const x=Symbol("EmptyContext"),B=a.createContext(x);function y(e){let{children:t}=e;const[n,l]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:l})),[n]);return a.createElement(B.Provider,{value:o},t)}var w=n(6043),L=n(8596),A=n(9960),M=n(2389);function F(e){let{categoryLabel:t,onClick:n}=e;return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel",message:"Toggle the collapsible sidebar category '{label}'",description:"The ARIA label to toggle the collapsible sidebar category"},{label:t}),type:"button",className:"clean-btn menu__caret",onClick:n})}function H(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{items:m,label:u,collapsible:b,className:p,href:h}=t,{docs:{sidebar:{autoCollapseCategories:E}}}=(0,_.L)(),f=function(e){const t=(0,M.Z)();return(0,a.useMemo)((()=>e.href?e.href:!t&&e.collapsible?(0,i.Wl)(e):void 0),[e,t])}(t),g=(0,i._F)(t,o),k=(0,L.Mg)(h,o),{collapsed:v,setCollapsed:S}=(0,w.u)({initialState:()=>!!b&&(!g&&t.collapsed)}),{expandedItem:I,setExpandedItem:N}=function(){const e=(0,a.useContext)(B);if(e===x)throw new Z.i6("DocSidebarItemsExpandedStateProvider");return e}(),T=function(e){void 0===e&&(e=!v),N(e?null:s),S(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:l}=e;const o=(0,Z.D9)(t);(0,a.useEffect)((()=>{t&&!o&&n&&l(!1)}),[t,o,n,l])}({isActive:g,collapsed:v,updateCollapsed:T}),(0,a.useEffect)((()=>{b&&null!=I&&I!==s&&E&&S(!0)}),[b,I,s,S,E]),a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemCategory,r.k.docs.docSidebarItemCategoryLevel(c),"menu__list-item",{"menu__list-item--collapsed":v},p)},a.createElement("div",{className:(0,l.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":k})},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!h&&b,"menu__link--active":g}),onClick:b?e=>{n?.(t),h?T(!1):(e.preventDefault(),T())}:()=>{n?.(t)},"aria-current":k?"page":void 0,"aria-expanded":b?!v:void 0,href:b?f??"#":f},d),u),h&&b&&a.createElement(F,{categoryLabel:u,onClick:e=>{e.preventDefault(),T()}})),a.createElement(w.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:v},a.createElement(j,{items:m,tabIndex:v?-1:0,onItemClick:n,activePath:o,level:c+1})))}var P=n(3919),W=n(9471);const D={menuExternalLink:"menuExternalLink_NmtK"};function R(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{href:m,label:u,className:b,autoAddBaseUrl:p}=t,h=(0,i._F)(t,o),E=(0,P.Z)(m);return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(c),"menu__list-item",b),key:u},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",!E&&D.menuExternalLink,{"menu__link--active":h}),autoAddBaseUrl:p,"aria-current":h?"page":void 0,to:m},E&&{onClick:n?()=>n(t):void 0},d),u,!E&&a.createElement(W.Z,null)))}const V={menuHtmlItem:"menuHtmlItem_M9Kj"};function z(e){let{item:t,level:n,index:o}=e;const{value:c,defaultStyle:i,className:s}=t;return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(n),i&&[V.menuHtmlItem,"menu__list-item"],s),key:o,dangerouslySetInnerHTML:{__html:c}})}function U(e){let{item:t,...n}=e;switch(t.type){case"category":return a.createElement(H,(0,C.Z)({item:t},n));case"html":return a.createElement(z,(0,C.Z)({item:t},n));default:return a.createElement(R,(0,C.Z)({item:t},n))}}function K(e){let{items:t,...n}=e;return a.createElement(y,null,t.map(((e,t)=>a.createElement(U,(0,C.Z)({key:t,item:e,index:t},n)))))}const j=(0,a.memo)(K),G={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:o}=e;const c=function(){const{isActive:e}=(0,T.nT)(),[t,n]=(0,a.useState)(e);return(0,b.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return a.createElement("nav",{"aria-label":(0,u.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,l.Z)("menu thin-scrollbar",G.menu,c&&G.menuWithAnnouncementBar,o)},a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:n,activePath:t,level:1})))}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",X="sidebarHidden_VK0M",J="sidebarLogo_isFc";function Q(e){let{path:t,sidebar:n,onCollapse:o,isHidden:r}=e;const{navbar:{hideOnScroll:c},docs:{sidebar:{hideable:i}}}=(0,_.L)();return a.createElement("div",{className:(0,l.Z)(q,c&&O,r&&X)},c&&a.createElement(v.Z,{tabIndex:-1,className:J}),a.createElement(Y,{path:t,sidebar:n}),i&&a.createElement(N,{onClick:o}))}const $=a.memo(Q);var ee=n(3102),te=n(2961);const ne=e=>{let{sidebar:t,path:n}=e;const o=(0,te.e)();return a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&o.toggle(),"link"===e.type&&o.toggle()},level:1}))};function ae(e){return a.createElement(ee.Zo,{component:ne,props:e})}const le=a.memo(ae);function oe(e){const t=(0,k.i)(),n="desktop"===t||"ssr"===t,l="mobile"===t;return a.createElement(a.Fragment,null,n&&a.createElement($,e),l&&a.createElement(le,e))}const re={expandButton:"expandButton_m80_",expandButtonIcon:"expandButtonIcon_BlDH"};function ce(e){let{toggleSidebar:t}=e;return a.createElement("div",{className:re.expandButton,title:(0,u.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t},a.createElement(S,{className:re.expandButtonIcon}))}const ie={docSidebarContainer:"docSidebarContainer_b6E3",docSidebarContainerHidden:"docSidebarContainerHidden_b3ry",sidebarViewport:"sidebarViewport_Xe31"};function se(e){let{children:t}=e;const n=(0,d.V)();return a.createElement(a.Fragment,{key:n?.name??"noSidebar"},t)}function de(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}=e;const{pathname:c}=(0,g.TH)(),[i,s]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{i&&s(!1),!i&&(0,f.n)()&&s(!0),o((e=>!e))}),[o,i]);return a.createElement("aside",{className:(0,l.Z)(r.k.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&s(!0)}},a.createElement(se,null,a.createElement("div",{className:(0,l.Z)(ie.sidebarViewport,i&&ie.sidebarViewportHidden)},a.createElement(oe,{sidebar:t,path:c,onCollapse:d,isHidden:i}),i&&a.createElement(ce,{toggleSidebar:d}))))}const me={docMainContainer:"docMainContainer_gTbr",docMainContainerEnhanced:"docMainContainerEnhanced_Uz_u",docItemWrapperEnhanced:"docItemWrapperEnhanced_czyv"};function ue(e){let{hiddenSidebarContainer:t,children:n}=e;const o=(0,d.V)();return a.createElement("main",{className:(0,l.Z)(me.docMainContainer,(t||!o)&&me.docMainContainerEnhanced)},a.createElement("div",{className:(0,l.Z)("container padding-top--md padding-bottom--lg",me.docItemWrapper,t&&me.docItemWrapperEnhanced)},n))}const be={docPage:"docPage__5DB",docsWrapper:"docsWrapper_BCFX"};function pe(e){let{children:t}=e;const n=(0,d.V)(),[l,o]=(0,a.useState)(!1);return a.createElement(m.Z,{wrapperClassName:be.docsWrapper},a.createElement(E,null),a.createElement("div",{className:be.docPage},n&&a.createElement(de,{sidebar:n.items,hiddenSidebarContainer:l,setHiddenSidebarContainer:o}),a.createElement(ue,{hiddenSidebarContainer:l},t)))}var he=n(4972),Ee=n(197);function fe(e){const{versionMetadata:t}=e;return a.createElement(a.Fragment,null,a.createElement(Ee.Z,{version:t.version,tag:(0,c.os)(t.pluginId,t.version)}),a.createElement(o.d,null,t.noIndex&&a.createElement("meta",{name:"robots",content:"noindex, nofollow"})))}function ge(e){const{versionMetadata:t}=e,n=(0,i.hI)(e);if(!n)return a.createElement(he.default,null);const{docElement:c,sidebarName:m,sidebarItems:u}=n;return a.createElement(a.Fragment,null,a.createElement(fe,e),a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.docsPages,r.k.page.docsDocPage,e.versionMetadata.className)},a.createElement(s.q,{version:t},a.createElement(d.b,{name:m,items:u},a.createElement(pe,null,c)))))}},4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});var a=n(7294),l=n(5999),o=n(1944),r=n(7961);function c(){return a.createElement(a.Fragment,null,a.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/1ebd8798.da59dcf0.js b/build-staging/assets/js/1ebd8798.da59dcf0.js new file mode 100644 index 00000000..3d2b3138 --- /dev/null +++ b/build-staging/assets/js/1ebd8798.da59dcf0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4788],{3905:(e,t,n)=>{n.d(t,{Zo:()=>g,kt:()=>d});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},g=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,g=c(e,["components","mdxType","originalType","parentName"]),p=s(n),u=i,d=p["".concat(l,".").concat(u)]||p[u]||h[u]||r;return n?a.createElement(d,o(o({ref:t},g),{},{components:n})):a.createElement(d,o({ref:t},g))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>s});var a=n(7462),i=(n(7294),n(3905));const r={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"February 24, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"autobindings",permalink:"/blog/tags/autobindings"},{label:"libcwtch",permalink:"/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/blog/cwtch-testing-ii"}},l={authorsImageUrls:[void 0]},s=[],g={toc:s},p="wrapper";function h(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,a.Z)({},g,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,i.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,i.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/22069e6c.c353e095.js b/build-staging/assets/js/22069e6c.c353e095.js new file mode 100644 index 00000000..aeed13a7 --- /dev/null +++ b/build-staging/assets/js/22069e6c.c353e095.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2852],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>f});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||s;return t?n.createElement(f,a(a({ref:r},p),{},{components:t})):n.createElement(f,a({ref:r},p))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var s=t.length,a=new Array(s);a[0]=m;var i={};for(var c in r)hasOwnProperty.call(r,c)&&(i[c]=r[c]);i.originalType=e,i[u]="string"==typeof e?e:o,a[1]=i;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const s={sidebar_position:6},a="How to Unlock a server",i={unversionedId:"servers/unlock-server",id:"servers/unlock-server",title:"How to Unlock a server",description:"This feature requires Experiments Enabled and",source:"@site/docs/servers/unlock-server.md",sourceDirName:"servers",slug:"/servers/unlock-server",permalink:"/docs/servers/unlock-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/unlock-server.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"How to share your Server Key Bundle",permalink:"/docs/servers/share-key"},next:{title:"Settings",permalink:"/docs/category/settings"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-to-unlock-a-server"},"How to Unlock a server"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," turned on.")),(0,o.kt)("p",null,"If you protected your server with a password, it will need to be unlocked each time you restart the application."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to the server Icon"),(0,o.kt)("li",{parentName:"ol"},"Click on the pink unlock icon"),(0,o.kt)("li",{parentName:"ol"},"Input the password of your server"),(0,o.kt)("li",{parentName:"ol"},"Press Unlock")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/238b6b00.1d778162.js b/build-staging/assets/js/238b6b00.1d778162.js new file mode 100644 index 00000000..56bac2f2 --- /dev/null +++ b/build-staging/assets/js/238b6b00.1d778162.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[129],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>b});var n=r(7294);function A(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(A[r]=e[r]);return A}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(A[r]=e[r])}return A}var o=n.createContext({}),p=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(o.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,A=e.mdxType,l=e.originalType,o=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),c=p(r),m=A,b=c["".concat(o,".").concat(m)]||c[m]||u[m]||l;return r?n.createElement(b,a(a({ref:t},s),{},{components:r})):n.createElement(b,a({ref:t},s))}));function b(e,t){var r=arguments,A=t&&t.mdxType;if("string"==typeof e||A){var l=r.length,a=new Array(l);a[0]=m;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i[c]="string"==typeof e?e:A,a[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var n=r(7462),A=(r(7294),r(3905));const l={sidebar_position:5},a="Clickable Links Experiment",i={unversionedId:"settings/experiments/clickable-links",id:"settings/experiments/clickable-links",title:"Clickable Links Experiment",description:"This feature, if enabled, presents a deanonymization risk.",source:"@site/docs/settings/experiments/clickable-links.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/clickable-links",permalink:"/docs/settings/experiments/clickable-links",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/clickable-links.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Image Previews and Profile Pictures",permalink:"/docs/settings/experiments/image-previews-and-profile-pictures"},next:{title:"Message Formatting",permalink:"/docs/settings/experiments/message-formatting"}},o={},p=[{value:"Risks",id:"risks",level:2}],s={toc:p},c="wrapper";function u(e){let{components:t,...l}=e;return(0,A.kt)(c,(0,n.Z)({},s,l,{components:t,mdxType:"MDXLayout"}),(0,A.kt)("h1",{id:"clickable-links-experiment"},"Clickable Links Experiment"),(0,A.kt)("admonition",{type:"danger"},(0,A.kt)("p",{parentName:"admonition"},"This feature, if enabled, presents a ",(0,A.kt)("strong",{parentName:"p"},"deanonymization")," risk."),(0,A.kt)("p",{parentName:"admonition"},"Do ",(0,A.kt)("strong",{parentName:"p"},"not")," open URLs from people you do not trust. Links sent via Cwtch are opened via the ",(0,A.kt)("strong",{parentName:"p"},"default"),"\nbrowser on the system. Most web browsers cannot provide anonymity.")),(0,A.kt)("h1",{id:"enable-the-clickable-links-experiment"},"Enable the Clickable Links Experiment"),(0,A.kt)("p",null,"Clickable links are ",(0,A.kt)("strong",{parentName:"p"},"not")," enabled by default. To allow Cwtch to open links in messages:"),(0,A.kt)("ol",null,(0,A.kt)("li",{parentName:"ol"},"Go to Settings"),(0,A.kt)("li",{parentName:"ol"},"Enable Experiments"),(0,A.kt)("li",{parentName:"ol"},"Enable the ",(0,A.kt)("inlineCode",{parentName:"li"},"Clickable Links")," Experiment")),(0,A.kt)("p",null,(0,A.kt)("img",{src:r(1302).Z,width:"1243",height:"58"})),(0,A.kt)("h2",{id:"risks"},"Risks"),(0,A.kt)("p",null,"Clickable links in messages are a very useful feature however there are risks you should be aware of if you\nchoose to enable this feature. "),(0,A.kt)("p",null,"To prevent accidental triggering, after clicking on a link in a message, Cwtch will first open an additional prompt with two options:"),(0,A.kt)("p",null,(0,A.kt)("img",{src:r(6004).Z,width:"1274",height:"192"})),(0,A.kt)("ol",null,(0,A.kt)("li",{parentName:"ol"},"Copy the URL to the Clipboard"),(0,A.kt)("li",{parentName:"ol"},"Open the URL in the ",(0,A.kt)("strong",{parentName:"li"},"default web browser"))),(0,A.kt)("p",null,"You can use the back button on your device, or click away from this prompt to avoid selecting either option."),(0,A.kt)("p",null,(0,A.kt)("strong",{parentName:"p"},"Cwtch cannot protect you if you open malicious links"),". "),(0,A.kt)("p",null,"The URL is opened in the ",(0,A.kt)("strong",{parentName:"p"},"default web browser")," which will likely, at a minimum, expose your IP address to the server hosting the URL. Web pages may also use other browser vulnerabilities to gather additional information, or further exploit your computer."))}u.isMDXComponent=!0},6004:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png"},1302:(e,t,r)=>{r.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABNsAAAA6CAIAAAAGIMiyAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO3de1yM6f8/8GumdFCrViRZpbZVSbRbNklYpSSklmgplXNC+aLNSiJMRC1bDkmxkkOlROkcHWw1HTQdhlqsY6VaNoNQ8/vj/n3uzzw6TBmSz3o9/5q57muu08w1j3nPdd/XzRg2bBgRSlpaWngGAAAAAAAAABEw+7oBAAAAAAAA8JlCRAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfQMRKQAAAAAAAPQNRKQAAAAAAADQNxCRAgAAAAAAQN/47CJSFotV3UFCQoLIBXI4HBaL1emhzMzMqKiody1w+PDhoaGhmZmZHA6noqIiLy8vNDSUOnTz5k0fHx/q8YkTJ86ePSukHBcXl+rqaktLy55XLaQvglX3BIvFunnzZsd0BQWF5OTkgICA92kMAAAAAAD8O4j3dQP6AJ/P9/PzE0xpamrqq8a0Y2tru2HDBgkJifz8/Dt37rS1tamoqMjJyXXMOXjw4P79+3/8Fr4nJSWlQYMGDR48uK8bAgAAAAAAPcLn89ulMBiMD1X4R4pIlZSU6Me1tbWdpnw0fD7/5MmTH7PGnnN1dX3x4sXKlSvLysqE55wxY8bHadKHVVFRoa+v39etAAAAAACAblCB6I8//jh16lRdXd0hQ4YQQurq6jgcTkZGRkxMDPkQoWnvRqSenp7Tpk0bMmSIlJQUnWhiYkIIyc7OplNevXpVV1eXkpKyZ8+eXm3PJ27z5s1fffXVli1bug1HAQAAAAAAeg+fz//xxx/XrVunrKwsmK6srKysrGxhYbFu3bpff/01JibmPYPSXryONCIiYunSpaqqqhISEi8FUEcFUyQkJFRVVZctWxYeHt577emWi4tLSUnJgQMH8vPzq6qqrl+/7unpSR0yMzM7d+4cm83mcrklJSW///674BrvqFGj/vjjD+ol7c4HFrRp06bs7OzKyko2m33o0KGOGbS1tRsaGqKjo3vS2ri4uCtXrtBPvb29c3JyqqqqSktLO64Am5ubs9ls6m+M5cuXJyYmlpaWcrncgoICf39/wZwfqi9CsNns4OBg6jGHwwkMDMzKyqqsrCwuLqbTBSkoKFy5ciUvL8/AwIAQsmPHjry8vKqqqpKSkpSUFC0trXeqHQAAAAAAhOPz+T4+Pv7+/u3CUUHKysr+/v4+Pj4dz+l9J721Rvp///d/xsbGr1+/TkxMDAsL43K57TKMGTOGfqylpbVkyRIrKytjY+P169fv37+/l1pFYTKZ1dXVgimBgYEhISGEEFlZWXV19XPnzjU3N8+ZM2fx4sVU2PPy5cs3b94kJyffv39fQ0NjxowZPj4+q1atol4+ZMiQhISExsbGyZMnz58//+3bt9u2bWtXqYeHh4uLS3x8fElJiba2to2NzYEDB9auXSuYR1FR8e+//xahR35+fjY2Nunp6WVlZSNGjGj3L4WRkZGvr299ff3y5csJIZKSknV1ddevX29sbDQ0NLSxsbl79y4dVX6ovvScoaFhSkrKvXv3JkyYYG5uvmXLlnaRcFhYmIKCgqenJ5vNXrZsmZ2dXVpaWmFhoby8/NChQzt+tAAAAAAAoB1lMmBRm95kvpo6f6B4ZwuTfMLnE8In/FZ+G/E1kXAY25NiHRwc+Hz+9u3bRV4p7a2I1MLCghBy6dIleplRCC6Xu3Hjxra2NltbWwsLi96OSDvubFRUVEQ/Dg4OTkpKIoQ0NTXt3r174sSJKSkpubm5ubm5dB41NbWvv/6afpqZmUkVeOjQocuXL0+bNq1jFDdz5szq6mp6NIYNG6anp9cuT79+/UTr0fTp069du9ZpTCgrK+vl5fXy5cvVq1c3NjYSQg4ePEgfDQkJYbPZgi35UH3puWvXrlFVHD9+vKioSFdXV/BoVFSUqqqqr69vRkYGIURDQ4PP58fHx6ekpIhcIwAAAADAZ8WOr+vbatZpICqICkf5czUlF/coHKU4OjqWl5fHxsaKFpT2VkSqqKjY2tp6+PBhOoXL5XZsIp/Pp8+6PHz4sLW1taKiYi81SbDSnuxsFB0dvXXrVhkZGeqpvb399OnTVVRUpKSkBgwYUF9f3+mrOBzOnDlzZGRkeDyeYLqCgsKwYcOqqqqopwwGo+NyaENDg5qa2rt2Z8qUKXJyciUlJZ0edXNzk5eXd3R0vHPnDp24fv36CRMmDBo0SFpaWlZWVkJC4oP3RTR1dXXS0tL0UyMjI2Vl5X379sXFxVEpSUlJU6ZMCQwM/Ouvv0pKSg4fPnz//v0PUjUAAAAAwL+SHV93Z6u58Dz/f4GUT96SNqn1hu9ahbu7e2xsLJ/PFyEo/ezuRyoaBweHX375hRBy6tSpDRs2cDicrnK+fv26tbW1XQhHCGlpaSksLNT+Dy0tLSMjo3Z5/vrrL3l5+U2bNr1T24YOHUoIYTI7fytv3LghJSW1cuVKOoXFYjk7O9+/f//QoUOurq5C7nzzPn35IGpqal6+fGlra0v/L5CVlWVoaHjixImXL1/OmjUrPj7e2tq6N6oGAAAAAPgXUCYDfFvNepKTT/htpI0xV4upPOCda1FWtrW1fffWEdJ7EWl9fb2YmJhgIKSlpaXZgeC2NCtXrhQTE+tq7bFvGRkZvXnzZvHixWFhYbm5ue0u3hX8J0BbW/vJkycdS6itrdXW1tbQ0BBSy759+xobG+fOnTtr1qyety0nJ6e1tbWr82aTkpIyMjKmTp3q4+NDpXz77bd379718PA4e/as4OnKH7YvH8STJ0/CwsJUVFSOHTsmmL5nz54ff/zR2dm5X79+5ubd/N8DAAAAAPDZWtSm1+3JurRWwmeavfM5mxRTU1PRXthbZ+2mpKSsWLFi5syZDAbj+PHjwref0dLScnFxsbKy4vP5H+H6QAaDYW9vL5jy9OlT6trRrjQ2NsrKyh47diwvL09bW1tHR4e6JpMybdq0lpaW27dvT5gwQVdX9+jRo1T6s2fPhg4dam5unpKScurUqR07doSEhJw5c+bu3buGhoYNDQ2hoaGCtdTW1oaHh69cuXLXrl2zZ8+urq5+8eKFqqqqvLz8smXLCCHPnz/X0NAwNDTMz8+nX3X//v3S0lITExN/f//s7GwdHZ3+/fvT8SchZOXKlTExMQsWLHj8+PHRo0efPXumo6Ozc+fOO3fuGBsbDxw4ULANXfVFsOqe9IUaZxcXF/opn88XYS/lX3/9VUlJae7cuYGBgR4eHqtWrdLV1S0rK6uvrzcyMpKUlHzw4MG7lgkAAAAA8JmYzO8+wqRP2W3lt0noDhGtIl1dXWrd7l1P3O2tiDQgIEBXV3fChAk2NjbW1tYtLS30IWpRSzDylJSUpE46zc3N3bdvXy81icZgMLZv3y6YwuVyhUek3t7eX3/99ffffz9+/PjHjx8XFRWNGDGCPlpeXm5lZdW/f//Gxsbw8HB6Z6bExEQnJ6eAgABPT8/z589LS0s7ODi4u7v369fv77//vnTpUseKjhw5UlZWtm7dulGjRk2cOPHNmzdPnz69ceMGdTQtLc3c3Nzf33/KlCmCr9qyZcvWrVtNTU2tra2fP3/e8ZrS1atXR0ZGurq6PnjwIDg4ePPmzTY2Nm/evKmpqampqRHM2VVfBKvuYV8YDIaXlxf9tLW1VbS7+3h5eSkqKs6YMePx48ctLS2ampoTJ06UkJB4/vx5amrq7t27RSgTAAAAAOBzoM4f2H0mQgghbaStlbSJKX0hWkVDhogYyjKGDRsmPIfgTjPvytPT09zcXFFRUUpKik40MTEhhGRnZ9Mpr169qq+vT0lJaXdvTAAAAAAAABBZ1VuPnmyxyyfkLb/1Bf+1/G0PIibKlrmtra0jR45kMBjvukbauxEpTUlJiX5cW1vbaQoAAAAAAAB8QJdbF4/kDxKeRzAilc1bIj5MToSKHj16ZGJiIkJE2ltn7bbTMeZEFAoAAAAAANCrrjLudBuR0hiE8arskaxIEWlZWZkIryK4+wsAAAAAAMC/1Slm6VvS1pOcTMJkEsar1D9Fqyg9PV20FyIiBQAAAAAA+Hd6RP7xEUsTnodBGAxCGAwixmC+ja58/fDpu9by8OHDmJgYEU7ZJYhIAQAAAAAA/sXOMTi/iKX0ZKVUnDAlGGKNAVfftYrAwECRmkYIIlJaTExMZGTkBykqISGhh7c5YbPZW7Zs6UnOrprX87oCAwMzMzN7kpMQYmlpWV1draWl1cP8nyfBIe35G/HvYG9vf/PmzZ7kZLFYubm5vd2ej6/nk1c0Z8+ePXv2bO+VDwAAAJ+VcwyOqXhYKLPwFqOhq9CUQRhMwpRkiPNjuPXh13teeEREBLVAKlrbPtLORp+IK1eufP311+0SW1tbey/0KigoKCgocHNz66XyRRMTEyMlJWVlZdXXDRHFpzmknzN/f/9p06ZZW1vfv3//o1W6du3aFStW6OjoCCZyudxdu3adPHlSX1//zJkzVOLbt28bGhri4+MDAgIIIdShDRs2xMfHf7TWfij48AMAAIDIHpF/9jCv7SHXhGfj8/l8Pr/V99A2xjYnJ6dui42IiNi2bZuYmJhop+ySzy0iXbhwYb9+/Qghvr6+mpqaCxYs6O0aS0pKKisre7uWd1VeXi54h9j/Lb06pAcPHtTQ0LC0tOyl8j8Rly9fvnv37urVqz9IaVwuV1FR8WOGoz3k5eWVk5MzduzYRYsWLVmypKamJi4urq8b9V4+ze8TAAAA+Dehokomk7lt2zYOh7N+/fqubhf68OHD/fv3x8TEMJlMkcNR8rlFpI2NjdSDtrY2Pp//Ee5As2LFit6uQgQ+Pj593QTR9eqQMplMMTGx3iv/EyEmJsZkfrAz9sPDwz/NM5bfvHlTW1tbW1ubnJxcXFxsZGT0vx6RfprfJwAAAPAvw2AwqCAzNjb2/Pnzc+fONTMzGzt2rJKSEiGktrb2xo0baWlp0dHRYmJi77M6SsF1pP81dOjQa9euVVVV5efnb9iwgUpUUFAIDw8vLi7mcDgXLlzQ09Nr96p58+alpqaWl5cXFhaGhIS0O5qXl7dz507qsaenZ25ubmVlZU5Ojqenp2A2Dw+PsrIyV1dXfX39CxculJSUcLncvLw8d3d3Os9XX32Vn59fVVV17dq1Tn+YmpiYJCQklJWVlZSUHDlyREhPo6KioqOjCSGWlpZsNjsqKqq0tLS8vDw2Nnb48OHtMh85cqSgoGDy5MkKCgqRkZGlpaUVFRW5ubmOjo6C2ToOlIyMTGZmZlRUFJXh6NGjOTk5w4cPj4mJiYqKysrKqqysvH79+vr164UMNYvFSkxMPH/+PIfDOXnypOCQslis1NTUK1eulJeXs9lsf3//gIAAaogyMjJmzpxJFevs7JyVlVVRUZGfn+/l5UUlxsTEnDt3rt3bvXPnTlNT0xEjRlRVVZ06dUqwd6GhoYWFhVwut6ioqNvrto2MjGJjY2/cuFFWVhYXF2dsbEwISUhIoE8TXbNmDZfL9fPzo54eO3YsISGBELJ3797CwsKqqqqCgoJdu3bRBTo6Ot66dcvCwoJ66u7uXlJSIiMjIyMjc+TIETabXVlZmZGRQb8j6enpBw4coB57eHgUFxcLNu/cuXPq6uo//PBDVVWVt7c3IaSrcgQFBwez2ezy8vL09HR6bCk+Pj4FBQXUYz09vejo6NLS0hs3brQ7LVZJSSk5OTkhIUFGRkYwfcuWLXl5eVVVVX/88cfWrVupROrNTUpKKi8vLy0t/e2334SPebfa2tpev34tJENXg08IMTc3T0pK4nA4HA4nPT1dQUGBSh83bhz1koyMjDlz5hBCupq/MTExx48fT01Nrays/OWXXwgh27dvz8/Pr6ioyMjIoE/WcHJyouZFQUFBx5lIOnz4hYzP+8wONze3a9euVVZWlpSUUJevdzr3u5oUO3bsyM/Pr6yszMrKyszM3L59O5XescvCv1IAAACgD1FBJpPJFBcXv3DhwqpVq4yMjNTU1NTU1IyMjFatWnXhwgVxcfH3XB2lICL9L0lJyfDw8DVr1vz111+Ojo7U72YWi6Wuru7h4bFy5Up5efl2kaSOjo6Xl9etW7cWL14cGBhYWFjYVeFLlixZtGhRQkLCggULIiMjORwOfWjp0qXOzs6nTp0KCQnhcrl37tw5ePDg5s2bHz58KHjqdr9+/YKCgpYvX/7gwYPVq1cbGRm1q8LHx4fH49na2u7Zs2f8+PFUsNEtOTm5R48eLV26NCwsTENDo10HAwICDAwMtm/ffvXq1c2bN2tqavr5+c2cOTMiIoIOQigdB4rH4wUFBY0ePdrd3d3JyWn8+PFBQUHUuZ0jRoyIjIx0dHTkcDhLly41MzMTMtQaGhrPnj3bvXv38ePH2zV+yJAhqampS5Ysyc/Pt7W1VVNT8/X19fPzExcXp4J2Q0NDDw+P7OzsSZMmXbp0ycHBgY7rhg4deuzYMcG3+5dffklPT7979662tvaiRYsEK3r48GFkZOTatWuzsrKsrKwWLlwoZEh9fX2ZTObatWt37do1cOBAKgIpKChQU1Ojgplx48bxeLyxY8dS+TU1Ndls9vz582fNmnXmzJkffvhh//792dnZdIEnT55sbGycPn069dTQ0JDL5fJ4vH379unq6gYEBLi6ujY1Nbm7u7e7rrJTdnZ2t2/fzszM1NbW3rFjByGk23IOHDjw3XffHThwwMnJKTk5mc1md1X4rl27JCUlN23atGnTpnY7aR0+fJjJZLq6uvJ4PDrR1dXVzs4uNjbW3t4+Ly/vp59+WrJkCXVoyJAhGRkZTk5OqampFhYWLi4u3XatUwYGBocPH2YwGOfPn+8qj5DBJ4S4ubm1tbWtWbPG2dn5zJkz9KkWfD5/69atfn5+TCaT+rwJmb9U+Orj4xMXF7dmzZo5c+YEBwfPnDnz4cOHa9euJYTo6+uvX7++vLzcwcEhPDxcQkJCeL+6HR+RZ4eLi0tlZeW8efN+/vnny5cvE0I6nfudTgqqa7GxsT/99FN2djb1Tyqd3q7Lwr9SAAAAoG/RQSkVl7ZDpb9/OEo+t7N2hbt79y598uGhQ4csLCxiY2MNDAwuXrx49epVQkhOTo65ubngSxwdHV+8eEFdj1dUVCSkcCsrqxs3brBYLEJIWVkZna6kpDR37ty4uLg9e/YQQng8Hr1mWFdXFxERYW5unpKSQgi5c+cOtd5YXFx89erVOXPmXL/+3y2w5s2bN3z4cBaLVVNTU1NTY2NjM2bMmB52PDQ0lMvlstlsY2NjwZUZBwcHMzMzf3//S5cuEUL69evHZDJVVVUzMzNDQ0PbFdLpQMXHx0+YMGHRokWvX7++ePEitTBLCLl9+zZVApvNzsvLmzFjRlpaWldD/eTJk6VLl3ba8ubm5n379hFCysvLJ06cWFZWlpiYSAgZO3bsDz/8QAiZP38+j8ejgvMdO3ZYWVmZmJgkJycTQu7du0ctuhKBt7urIdq2bRv1ICUlxdjYWEjgZ2trq6KiYmdnR73LYmJi27Zt09fXj4iIsLOzc3BwCAoK0tDQiImJsbe3V1BQ0NfXl5eXj4yMnDBhAoPBUFRUVFJSonfloZWXl48ePZp6PHLkyKNHjxJCvv/++9OnT1OZuVxuUlKSra1tRUVFV23rSrflTJgwITY2lhouIeHorFmz1NXVFy5cSM0Fapwpp0+fHjhwoJubW7vLTS0sLEpKSqg9h0pLS0eOHGlmZhYWFkYIaW5u3rt3L1Xj5MmTR40a9a792rt37549exgMRkNDw/r16wXnXTuSkpJCBl9MTExKSkpFReXkyZOC3Wez2UlJSYSQUaNGUdceC5m/HA5n8+bN1CEWi1VVVUWN54kTJ0JCQqZMmTJjxoynT59SuxYVFRVNmTJFeO+6HR+RZ4e4uPiAAQO++uor+h3sdO53OinMzMxKSkr8/f0JIaWlpdOmTaPymJubd+yy8K8UAAAA6HNUtMlgMPh8frvI8/0DURoi0k6kpaW1tbVJSkoqKSnJysrOmjWL3pa2ublZMKeSktLTpz26gayCgsK9e/c6po8dO5bBYFy79t89r7y9vSdNmiQlJUW9zdLS0u1ewuPxnjx5MnDgQMFEdXV1BoNBRbyUqqqqnjRMUHNz86BBg+inkyZNamxspH5PE0L27t0rLS1tb2/v5ORUVla2f/9+OggXMlCenp7Z2dl8Pr+rW2U0NTXJycl1O9TC8Xi8ly9f0peANjU1UaM3aNAgOTk5wSiitbW13Wvpt1tI+Y6OjvPmzRs4cGBbW9uAAQPExbucON988w2Px6ODn8jISG9vb01NzaKiops3b44bN446YXLXrl02NjaOjo7Dhw+/ffs29T/CyJEjJ02aZG1tXV1dffr0afqEZ0LI5cuXWSyWvr7+d999x+fzjxw5Qo3Y7du3qQy1tbVNTU30CaU91205SkpKAwYMuHv3brdFaWtrt7S0dPxrRlJSUldXt6CgoGNM+OWXX1ZXV9NPHz9+PHTo0I4l83i8dtf3trS0iImJycjI0CuuMjIyDAbj+fPndJ6NGzfGx8fv3bvXwsJC+Cm7J0+eFDL4v/32m7Oz88aNG9esWXP9+nVqfU9QQ0MDfV1uV/OXz+fT+eXk5FRVVemP5T///NO/f39FRcVnz54JaaQQHcen3dF3mh0hISHW1ta//vprbW1tUlKSv79/p3O/00khJyf3559/dmxDp10W8pUCAAAAn5QPGH92hLN2hamtrX3x4kViYqLBf1BrCzQej/fll1/2pKhXr14NHjy4Y3pqampdXZ2Pj4+GhgYhxNnZed68eUePHjUxMZk4cWJXpcnJydXV1QmmUEtPmzdvppvq4ODQk4YJERgY+OWXX9KXqN2/f3/ZsmUGBgb79u1TV1cXvMZVyEBt2LBBWlp6wIAB1MmrFMFtdeTl5evr67sdatE0NTU1NzcbCBBhVycZGZkNGzYUFBQYGxubmJjU19cLyfzo0SMZGRnq2lFCiKWlJYPBoE5HzMnJGTlypKmp6a1btwghXC7XwMBAR0cnPz+fyrxly5ZJkyZ5eHjw+XxXV1fBYuPi4urr621sbCZOnEitXtbW1r569UpwtVZOTu7x48eEECpCEN4p+mtFSDl0htevX6urqwsvkBDS1NQkJSVlYGDQLr2lpeX48ePGxsb0qhqtublZWVmZfjpw4MCmpqZuKyKE5OfnM5lMwQ/5/PnzW1tbBRdmKdu2bXv+/HnHMLIdIYOflJRkZ2c3bdq0mJgYU1NT+nrLjno4f//555+bN28KfiwTExOfPn0qwh8K76Or2XH48GFLS8sFCxZUVFQ4Ozvr6+t3nPtdTYrm5uZO/1PotMtCvlIAAADg84GItBvFxcXTp0+nrtGaOXMmtX8J7erVqwoKCkFBQUpKSpaWltTv41evXnWMB0pLS8eOHUv95Fq4cCF9f5G2tjYvLy9xcXFqaxBFRUUJCYnBgwfr6OjQO99QvvnmG2dnZx0dnZCQECkpKWoNh67r9OnTDx8+3Lhxo5mZmYyMjKOjo6GhoeDLeTyejIzMO/3kraysPHDgwJgxY6i2OTs7r1ixQklJ6ebNmy0tLT0ZqKlTpy5cuPDs2bPnz5+3s7ObOnUqlVlXV9fLy0tHRycwMFBWVvbs2bPdDrVo4uLipKWlT548qaGhoaam1u1Wpc3NzYqKitQ2TnTiiBEjJCUlFRQUtLS03Nzc5OXlqXTBIaXfiNjY2IaGhi1btpiZmU2dOtXd3b2srKympoYQEhQUJCYmZmRklJubSwjJycnR1NQcPHjw77//TgiZMmWKp6enjo5OdXV1p2tl1EdIS0srLS2NSuFwOLNnz3Z2dh4zZkxYWNjbt29PnDhBCHn8+PHo0aNdXFyMjIz09fU7FsXj8dTV1enrWrsqh1ZdXT1jxow5c+YMHz589erVw4cPf/LkCYPBaHebnOTk5H/++cfb21tPT09fX3/VqlX0ocDAwPj4eDs7u+XLlwu+5Pr163p6et7e3hoaGt7e3iNHjuzhdrilpaVlZWUuLi4eHh5GRkaurq5Lly7Nzc0VvEiV7mxsbOy33377008/0Yn9+/fX+g8lJSXhg79hw4a5c+fW1tbW1NRQ23R31Soh81dQVlaWrq6ur6+vjIyMoaEhtaNPUlKSvLz8sWPH9PT07O3tVVRUejIO76Or2eHj4zN58uTq6mpqN/LW1taOc7+rSZGXl6enp0f9xbZx48YvvvhCSJeFf6UAAADAZwIRaTe8vLxKSkpcXV3Lyso2bdo0btw4waNnz549derU+PHj09PTd+3aRe02lJaWpqqqmpqaKpjT09MzLy/PwcGhoqJi3bp19DWBhJCioiIWi6WiohIeHv7bb79xOJzVq1dHRUVpamoK/jiur693c3M7d+6cpqZmQEAAtVAmWJevr+/z588DAgJycnIcHBwEqyCEREdHv3jxIi0tbfLkyT3vfkRERGRkpKWl5aZNm9TV1Z2cnNLT048ePfrixYt223t2OlA///zzrVu39u7du3PnzpqaGnqzooaGhjlz5pw/f/7bb7/dv39/aWlpt0MtmqysrKCgoGHDhlFbV8+aNUv43j8RERF1dXXBwcGCtzOpqKhITEycMmVKTEzM7Nmz6eUgwSGl3wgej8disRgMRlBQ0L59+5qamgS3mKqsrJSQkKAumTty5AiDwbhz5w61vq2iomJpaXnmzJn4+HhVVdWO91OJi4tTV1dvbW2lIlhCyI4dO2pqatatWxcZGamsrOzn50eFEMHBwU+ePNm4cePBgwdbW1s7RlDR0dGysrIXL16kFi27KofGYrHq6uq2b9+emJhoZ2enq6ublpZWWlrKYrHoayMJIffv3w8KCvriiy9OnToVHh4+Y8YMwUI8PT0LCwtdXfZp1doAAAHqSURBVF0F0/38/JKSkqytrS9evGhubh4aGirkat52fv7556qqqoULF4aHhy9evJjNZne1yBYQEHDv3j3BfYa2b9+e8B9+fn7CB3/06NFeXl6VlZXe3t7FxcWC58a3I2T+tmvPmTNnpk2bdv369aCgIFNTU0JIcnLy0aNHR40aFRUV5ebm9uDBgx6Og8g6nR1qamrjx48/ePBgYWHh7Nmzz58/X1pa2nHudzUpdu/efeXKlVmzZsXHx5uamra0tFAfv067LPwrBQAAAD4TjK5ueErreB0jwPuIiYl59eqV8O1qoVPZ2dlcLnfZsmV93RCAHikuLg4LCwsODu7rhgAAAMCnC2ukAP8b9PT0Bg0aRG80BfCJmzx5cv/+/cvLy/u6IQAAAPBJw167AP8b7O3t//77byE31QT4FPj7+ycnJz979szd3f3mzZvU/ZwAAAAAuoKIFOB/g4GBgQh39AH4yEaPHm1lZdXW1vbnn38KXkQNAAAA0ClcRwoAAAAAAAB9A9eRAgAAAAAAQN9ARAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfeP/AQclJUZgqx9hAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/2853a99a.dbc78f5b.js b/build-staging/assets/js/2853a99a.dbc78f5b.js new file mode 100644 index 00000000..18178cff --- /dev/null +++ b/build-staging/assets/js/2853a99a.dbc78f5b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6297],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=c(r),m=o,f=l["".concat(s,".").concat(m)]||l[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:o,i[1]=p;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:6},i="How to Leave a Group",p={unversionedId:"groups/leave-group",id:"groups/leave-group",title:"How to Leave a Group",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/leave-group.md",sourceDirName:"groups",slug:"/groups/leave-group",permalink:"/docs/groups/leave-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/leave-group.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Accepting a Group Invite",permalink:"/docs/groups/accept-group-invite"},next:{title:"Editing a Group Name",permalink:"/docs/groups/edit-group-name"}},s={},c=[],u={toc:c},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-to-leave-a-group"},"How to Leave a Group"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,o.kt)("strong",{parentName:"p"},"irreversible")," deletion of key material. This ",(0,o.kt)("strong",{parentName:"p"},"cannot be undone"),".")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On the chat pane go to settings"),(0,o.kt)("li",{parentName:"ol"},"Scroll down on the settings pane"),(0,o.kt)("li",{parentName:"ol"},"Press on leave conversation"),(0,o.kt)("li",{parentName:"ol"},"Confirm you want to leave")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Leave.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/2c8522e6.59a45b23.js b/build-staging/assets/js/2c8522e6.59a45b23.js new file mode 100644 index 00000000..0e8e5d05 --- /dev/null +++ b/build-staging/assets/js/2c8522e6.59a45b23.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7499],{712:e=>{e.exports=JSON.parse('{"title":"Experiments","slug":"/category/experiments","permalink":"/docs/category/experiments","navigation":{"previous":{"title":"Notification Content","permalink":"/docs/settings/behaviour/notification-content"},"next":{"title":"Groups Experiment","permalink":"/docs/settings/experiments/group-experiment"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/2ffd7dc7.c74ecef6.js b/build-staging/assets/js/2ffd7dc7.c74ecef6.js new file mode 100644 index 00000000..f6d49e1c --- /dev/null +++ b/build-staging/assets/js/2ffd7dc7.c74ecef6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2073],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>b});var r=n(7294);function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;e=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}var s=r.createContext({}),l=function(t){var e=r.useContext(s),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},p=function(t){var e=l(t.components);return r.createElement(s.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},m=r.forwardRef((function(t,e){var n=t.components,o=t.mdxType,i=t.originalType,s=t.parentName,p=c(t,["components","mdxType","originalType","parentName"]),u=l(n),m=o,b=u["".concat(s,".").concat(m)]||u[m]||f[m]||i;return n?r.createElement(b,a(a({ref:e},p),{},{components:n})):r.createElement(b,a({ref:e},p))}));function b(t,e){var n=arguments,o=e&&e.mdxType;if("string"==typeof t||o){var i=n.length,a=new Array(i);a[0]=m;var c={};for(var s in e)hasOwnProperty.call(e,s)&&(c[s]=e[s]);c.originalType=t,c[u]="string"==typeof t?t:o,a[1]=c;for(var l=2;l{n.r(e),n.d(e,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},a="Notification Content",c={unversionedId:"settings/behaviour/notification-content",id:"settings/behaviour/notification-content",title:"Notification Content",description:"1. Go to settings",source:"@site/docs/settings/behaviour/notification-content.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-content",permalink:"/docs/settings/behaviour/notification-content",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-content.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Notification policy",permalink:"/docs/settings/behaviour/notification-policy"},next:{title:"Experiments",permalink:"/docs/category/experiments"}},s={},l=[],p={toc:l},u="wrapper";function f(t){let{components:e,...n}=t;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:e,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"notification-content"},"Notification Content"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to settings"),(0,o.kt)("li",{parentName:"ol"},"Scroll to behaviour"),(0,o.kt)("li",{parentName:"ol"},"The notification content controls the contents of notifications",(0,o.kt)("ol",{parentName:"li"},(0,o.kt)("li",{parentName:"ol"},'Plain Event: "New Message" only'),(0,o.kt)("li",{parentName:"ol"},'Conversation Information: "New Message from XXXXX"')))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/3152febb.21d88be4.js b/build-staging/assets/js/3152febb.21d88be4.js new file mode 100644 index 00000000..58342fae --- /dev/null +++ b/build-staging/assets/js/3152febb.21d88be4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[225],{3492:t=>{t.exports=JSON.parse('{"title":"Getting started","slug":"/category/getting-started","permalink":"/docs/category/getting-started","navigation":{"previous":{"title":"What is Cwtch?","permalink":"/docs/intro"},"next":{"title":"Supported Platforms","permalink":"/docs/getting-started/supported_platforms"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/34cd4dc6.57acc729.js b/build-staging/assets/js/34cd4dc6.57acc729.js new file mode 100644 index 00000000..ae623157 --- /dev/null +++ b/build-staging/assets/js/34cd4dc6.57acc729.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3429],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",y={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=o,f=u["".concat(c,".").concat(d)]||u[d]||y[d]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>y,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:4},i="Saving Conversation History",s={unversionedId:"chat/save-conversation-history",id:"chat/save-conversation-history",title:"Saving Conversation History",description:"By default, for privacy, Cwtch does not preserve conversation history between sessions.",source:"@site/docs/chat/save-conversation-history.md",sourceDirName:"chat",slug:"/chat/save-conversation-history",permalink:"/docs/chat/save-conversation-history",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/save-conversation-history.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Sharing Cwtch Addresses",permalink:"/docs/chat/share-address-with-friends"},next:{title:"Message Formatting",permalink:"/docs/chat/message-formatting"}},c={},l=[],p={toc:l},u="wrapper";function y(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"saving-conversation-history"},"Saving Conversation History"),(0,o.kt)("p",null,"By default, for privacy, Cwtch does not preserve conversation history between sessions. "),(0,o.kt)("p",null,"To enable history for a specific conversation: "),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On a conversation window go to Settings"),(0,o.kt)("li",{parentName:"ol"},"Go to Save History"),(0,o.kt)("li",{parentName:"ol"},"Click the dropdown menu"),(0,o.kt)("li",{parentName:"ol"},"Pick Save History"),(0,o.kt)("li",{parentName:"ol"},"Now your history will be saved")),(0,o.kt)("p",null,'Conversation history can be turned off at any point by selecting "Delete History" from the drop down menu.'))}y.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/38f00f86.2fc26296.js b/build-staging/assets/js/38f00f86.2fc26296.js new file mode 100644 index 00000000..9ecfa717 --- /dev/null +++ b/build-staging/assets/js/38f00f86.2fc26296.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9667],{2686:a=>{a.exports=JSON.parse('{"label":"documentation","permalink":"/blog/tags/documentation","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/39c54b43.3f984fa7.js b/build-staging/assets/js/39c54b43.3f984fa7.js new file mode 100644 index 00000000..fb790afe --- /dev/null +++ b/build-staging/assets/js/39c54b43.3f984fa7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8793],{4990:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/cwtch/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/blog/tags/cwtch","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/3a109bd3.e6ac824e.js b/build-staging/assets/js/3a109bd3.e6ac824e.js new file mode 100644 index 00000000..774381de --- /dev/null +++ b/build-staging/assets/js/3a109bd3.e6ac824e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7782],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>g});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),p=s(n),h=a,g=p["".concat(l,".").concat(h)]||p[h]||u[h]||o;return n?r.createElement(g,i(i({ref:t},m),{},{components:n})):r.createElement(g,i({ref:t},m))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:a,i[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(7462),a=(n(7294),n(3905));const o={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"March 10, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/blog/tags/documentation"},{label:"security-handbook",permalink:"/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/blog/autobindings-ii"}},l={authorsImageUrls:[void 0]},s=[],m={toc:s},p="wrapper";function u(e){let{components:t,...o}=e;return(0,a.kt)(p,(0,r.Z)({},m,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/3b599162.4579cba4.js b/build-staging/assets/js/3b599162.4579cba4.js new file mode 100644 index 00000000..8acd4b42 --- /dev/null +++ b/build-staging/assets/js/3b599162.4579cba4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7294],{2159:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/libcwtch","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/3ce57273.f5cb4514.js b/build-staging/assets/js/3ce57273.f5cb4514.js new file mode 100644 index 00000000..1c164811 --- /dev/null +++ b/build-staging/assets/js/3ce57273.f5cb4514.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6972],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),f=l(n),m=i,d=f["".concat(c,".").concat(m)]||f[m]||u[m]||a;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[f]="string"==typeof e?e:i,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:3},o="File Sharing",s={unversionedId:"settings/experiments/file-sharing",id:"settings/experiments/file-sharing",title:"File Sharing",description:'These setting enables Cwtch filesharing functionality. This reveals the "Share File" option in the conversation pane, and allows you to download files from conversations.',source:"@site/docs/settings/experiments/file-sharing.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/file-sharing",permalink:"/docs/settings/experiments/file-sharing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/file-sharing.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Server Hosting",permalink:"/docs/settings/experiments/server-hosting"},next:{title:"Image Previews and Profile Pictures",permalink:"/docs/settings/experiments/image-previews-and-profile-pictures"}},c={},l=[],p={toc:l},f="wrapper";function u(e){let{components:t,...n}=e;return(0,i.kt)(f,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"file-sharing"},"File Sharing"),(0,i.kt)("p",null,"These setting enables Cwtch ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/share-file"},"filesharing functionality"),'. This reveals the "Share File" option in the conversation pane, and allows you to download files from conversations.'),(0,i.kt)("p",null,"Optionally, you can enable ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," to download image files automatically, view image previews in the conversation window, and enable the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profile Pictures")," feature;"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/3db42865.27ab3fca.js b/build-staging/assets/js/3db42865.27ab3fca.js new file mode 100644 index 00000000..c1f2d599 --- /dev/null +++ b/build-staging/assets/js/3db42865.27ab3fca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7139],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/3e7ae638.2d4495ca.js b/build-staging/assets/js/3e7ae638.2d4495ca.js new file mode 100644 index 00000000..74e34f3f --- /dev/null +++ b/build-staging/assets/js/3e7ae638.2d4495ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9595],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=s(r),f=o,m=u["".concat(p,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(m,i(i({ref:t},l),{},{components:r})):n.createElement(m,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Packet Format",c={unversionedId:"components/tapir/packet_format",id:"components/tapir/packet_format",title:"Packet Format",description:"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message,",source:"@site/security/components/tapir/packet_format.md",sourceDirName:"components/tapir",slug:"/components/tapir/packet_format",permalink:"/security/components/tapir/packet_format",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Tapir",permalink:"/security/category/tapir"},next:{title:"Authentication Protocol",permalink:"/security/components/tapir/authentication_protocol"}},p={},s=[],l={toc:s},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"packet-format"},"Packet Format"),(0,o.kt)("p",null,"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message,\n",(0,o.kt)("inlineCode",{parentName:"p"},"len")," bytes of data, and the rest zero padded:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|\n")),(0,o.kt)("p",null,"Once encrypted, the entire 8192 byte data packet is encrypted using ",(0,o.kt)("a",{parentName:"p",href:"https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox"},"libsodium secretbox")," using the standard structure (\nnote in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)"),(0,o.kt)("p",null,"For information on how the secret key is derived see the ",(0,o.kt)("a",{parentName:"p",href:"/security/components/tapir/authentication_protocol"},"authentication protocol")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/414c86b4.d09cba17.js b/build-staging/assets/js/414c86b4.d09cba17.js new file mode 100644 index 00000000..03caa00a --- /dev/null +++ b/build-staging/assets/js/414c86b4.d09cba17.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[730],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=s(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:o,a[1]=p;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:5},a="Accepting a Group Invite",p={unversionedId:"groups/accept-group-invite",id:"groups/accept-group-invite",title:"Accepting a Group Invite",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/accept-group-invite.md",sourceDirName:"groups",slug:"/groups/accept-group-invite",permalink:"/docs/groups/accept-group-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/accept-group-invite.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Sending Invites to a Group",permalink:"/docs/groups/send-invite"},next:{title:"How to Leave a Group",permalink:"/docs/groups/leave-group"}},c={},s=[],u={toc:s},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accepting-a-group-invite"},"Accepting a Group Invite"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"If a friend sends you a group request"),(0,o.kt)("li",{parentName:"ol"},"Choose if you want or not to join this group"),(0,o.kt)("li",{parentName:"ol"},"Now the group is on your contact list")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_acceptinvite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/41c638ee.bf4c73bb.js b/build-staging/assets/js/41c638ee.bf4c73bb.js new file mode 100644 index 00000000..4a66856e --- /dev/null +++ b/build-staging/assets/js/41c638ee.bf4c73bb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8266],{8129:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/nightly","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/43521719.fff4da5d.js b/build-staging/assets/js/43521719.fff4da5d.js new file mode 100644 index 00000000..a6103e25 --- /dev/null +++ b/build-staging/assets/js/43521719.fff4da5d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9376],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(n),d=i,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(f,o(o({ref:t},p),{},{components:n})):r.createElement(f,o({ref:t},p))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:i,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:4.5},o="Message Formatting",s={unversionedId:"chat/message-formatting",id:"chat/message-formatting",title:"Message Formatting",description:"This feature requires Experiments Enabled and",source:"@site/docs/chat/message-formatting.md",sourceDirName:"chat",slug:"/chat/message-formatting",permalink:"/docs/chat/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/message-formatting.md",tags:[],version:"current",sidebarPosition:4.5,frontMatter:{sidebar_position:4.5},sidebar:"tutorialSidebar",previous:{title:"Saving Conversation History",permalink:"/docs/chat/save-conversation-history"},next:{title:"Accessing Conversation Settings",permalink:"/docs/chat/conversation-settings"}},c={},l=[],p={toc:l},m="wrapper";function u(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"message-formatting"},"Message Formatting"),(0,i.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"This feature requires ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/message-formatting"},"Message Formatting Experiment")," turned on."),(0,i.kt)("p",{parentName:"admonition"},"Optionally, you can enable ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/clickable-links"},"Clickable Links")," to\nmake URLs in messages clickable in Cwtch.")),(0,i.kt)("p",null,"Cwtch currently supports the following formatting markdown for messages:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"**bold**")," which will render ",(0,i.kt)("strong",{parentName:"li"},"bold")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"*italic*")," which will render ",(0,i.kt)("em",{parentName:"li"},"italic")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"code")," which will render ",(0,i.kt)("inlineCode",{parentName:"li"},"code")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"^superscript^")," which will render ",(0,i.kt)("sup",null,"superscript")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"_subscript_")," which will render ",(0,i.kt)("sub",null,"subscript")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"~~strikthrough~~")," which will render ",(0,i.kt)("del",null,"strikethrough"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/437de1b1.df91c06b.js b/build-staging/assets/js/437de1b1.df91c06b.js new file mode 100644 index 00000000..8e110763 --- /dev/null +++ b/build-staging/assets/js/437de1b1.df91c06b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2562],{4785:t=>{t.exports=JSON.parse('{"title":"Cwtch","slug":"/category/cwtch","permalink":"/security/category/cwtch","navigation":{"previous":{"title":"Authentication Protocol","permalink":"/security/components/tapir/authentication_protocol"},"next":{"title":"Message Formats","permalink":"/security/components/cwtch/message_formats"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/43b107c1.0fa4ee7a.js b/build-staging/assets/js/43b107c1.0fa4ee7a.js new file mode 100644 index 00000000..ce5ad433 --- /dev/null +++ b/build-staging/assets/js/43b107c1.0fa4ee7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9200],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),d=i,g=c["".concat(l,".").concat(d)]||c[d]||h[d]||r;return n?a.createElement(g,o(o({ref:t},u),{},{components:n})):a.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"February 3, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"support",permalink:"/blog/tags/support"},{label:"testing",permalink:"/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/blog/cwtch-platform-support"}},l={authorsImageUrls:[void 0]},p=[{value:"Current Limitations of Flutter Gherkin",id:"current-limitations-of-flutter-gherkin",level:2},{value:"Integrating Tests into the Pipeline",id:"integrating-tests-into-the-pipeline",level:2},{value:"Catching Bugs!",id:"catching-bugs",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},c="wrapper";function h(e){let{components:t,...r}=e;return(0,i.kt)(c,(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"We first ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,i.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})),(0,i.kt)("h2",{id:"current-limitations-of-flutter-gherkin"},"Current Limitations of Flutter Gherkin"),(0,i.kt)("p",null,"The original ",(0,i.kt)("a",{parentName:"p",href:"https://pub.dev/packages/flutter_gherkin"},"flutter_gherkin")," is under semi-active development; however, the latest published versions don't support using it with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Test")," was originally intended to run single widget/unit tests for a Flutter project."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Drive")," was originally intended to run integration tests ",(0,i.kt)("em",{parentName:"li"},"on a device or an emulator"),".")),(0,i.kt)("p",null,"However, in recent releases these lines have become blurred. The new ",(0,i.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/testing/integration-tests"},"integration_test")," package that comes built into newer Flutter releases has support for both ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),". This was a great change because it decreases the required overhead to run larger integration tests (",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," sets up a host-controller model that requires a dedicated control channel to be setup, whereas ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible)."),(0,i.kt)("p",null,"There is thankfully code in the ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter_gherkin")," repository that supports running tests with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", however this code currently has a few issues:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The test code generation produces code that doesn't compile without minor changes."),(0,i.kt)("li",{parentName:"ul"},'Certain functionality like "take a screenshot" does not work on desktop.')),(0,i.kt)("p",null,"Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test."),(0,i.kt)("li",{parentName:"ul"},"Certain Flutter widgets like ",(0,i.kt)("inlineCode",{parentName:"li"},"DropdownButton")," are not compatible with built-in steps like ",(0,i.kt)("inlineCode",{parentName:"li"},"tap")," because they internally contain multiple copies of the same widget.")),(0,i.kt)("p",null,"Because of the above issues we have chosen to ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/flutter_gherkin"},"fork flutter_gherkin")," to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing."),(0,i.kt)("h2",{id:"integrating-tests-into-the-pipeline"},"Integrating Tests into the Pipeline"),(0,i.kt)("p",null,"One of the major limitations of ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display."),(0,i.kt)("p",null,"Thankfully it is possible to use ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Xvfb"},"Xfvb")," to create a virtual framebuffer, and set ",(0,i.kt)("inlineCode",{parentName:"p"},"DISPLAY")," to render to that buffer:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"export DISPLAY=:99\nXvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\n")),(0,i.kt)("p",null,"This allows us to neutralize our main issue with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", and efficiently run tests in our pipeline."),(0,i.kt)("h2",{id:"catching-bugs"},"Catching Bugs!"),(0,i.kt)("p",null,"This small amount of integration work has already caught its first bug."),(0,i.kt)("p",null,"Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature"},"02_save_load.feature")," simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment."),(0,i.kt)("p",null,"The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory ",(0,i.kt)("inlineCode",{parentName:"p"},"$USER_HOME/Downloads")," didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available."),(0,i.kt)("p",null,"As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!"),(0,i.kt)("h2",{id:"next-steps"},"Next Steps"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More automated tests:")," We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More platforms:")," Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/getting-started/supported_platforms"},"our target platforms"),". We expect to start this work soon; expect more news in a future Cwtch Testing update!")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More steps:")," One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the ",(0,i.kt)("inlineCode",{parentName:"p"},"expect to see the message")," step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"send a file")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"set profile picture"),"."))),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/442b4cb8.f90518cc.js b/build-staging/assets/js/442b4cb8.f90518cc.js new file mode 100644 index 00000000..fd284cbb --- /dev/null +++ b/build-staging/assets/js/442b4cb8.f90518cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6971],{3157:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/bindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/44fbbcc6.1ad2a97d.js b/build-staging/assets/js/44fbbcc6.1ad2a97d.js new file mode 100644 index 00000000..0df6b0e6 --- /dev/null +++ b/build-staging/assets/js/44fbbcc6.1ad2a97d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1088],{3905:(e,t,r)=>{r.d(t,{Zo:()=>f,kt:()=>m});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function a(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var p=o.createContext({}),c=function(e){var t=o.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},f=function(e){var t=c(e.components);return o.createElement(p.Provider,{value:t},e.children)},s="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,p=e.parentName,f=l(e,["components","mdxType","originalType","parentName"]),s=c(r),d=n,m=s["".concat(p,".").concat(d)]||s[d]||u[d]||i;return r?o.createElement(m,a(a({ref:t},f),{},{components:r})):o.createElement(m,a({ref:t},f))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,a=new Array(i);a[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[s]="string"==typeof e?e:n,a[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var o=r(7462),n=(r(7294),r(3905));const i={sidebar_position:10},a="Backup or Exporting a Profile",l={unversionedId:"profiles/exporting-profile",id:"profiles/exporting-profile",title:"Backup or Exporting a Profile",description:"On the Profile Management Screen:",source:"@site/docs/profiles/exporting-profile.md",sourceDirName:"profiles",slug:"/profiles/exporting-profile",permalink:"/docs/profiles/exporting-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/exporting-profile.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Deleting a Profile",permalink:"/docs/profiles/delete-profile"},next:{title:"Importing a Profile",permalink:"/docs/profiles/importing-a-profile"}},p={},c=[],f={toc:c},s="wrapper";function u(e){let{components:t,...r}=e;return(0,n.kt)(s,(0,o.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"backup-or-exporting-a-profile"},"Backup or Exporting a Profile"),(0,n.kt)("p",null,"On the Profile Management Screen:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Select the pencil next to the profile you want to edit"),(0,n.kt)("li",{parentName:"ol"},"Scroll down to the bottom of the screen"),(0,n.kt)("li",{parentName:"ol"},'Select "Export Profile"'),(0,n.kt)("li",{parentName:"ol"},"Choose a location, and a file name"),(0,n.kt)("li",{parentName:"ol"},"Confirm")),(0,n.kt)("p",null,"Once confirmed, Cwtch will place a copy of the profile at the given location. This file is encrypted to the same\nlevel that the profile is. See ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"A note on Password Protected (Encrypted) Profiles")," for more information on encrypted\nprofiles."),(0,n.kt)("p",null,"This file can be ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/importing-a-profile"},"imported")," into another instance of Cwtch on any device."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/48119dbc.2ba7a442.js b/build-staging/assets/js/48119dbc.2ba7a442.js new file mode 100644 index 00000000..337df25e --- /dev/null +++ b/build-staging/assets/js/48119dbc.2ba7a442.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4998],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?n.createElement(v,i(i({ref:r},l),{},{components:t})):n.createElement(v,i({ref:r},l))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:2},i="How to create a server",s={unversionedId:"servers/create-server",id:"servers/create-server",title:"How to create a server",description:"This feature requires Experiments Enabled and",source:"@site/docs/servers/create-server.md",sourceDirName:"servers",slug:"/servers/create-server",permalink:"/docs/servers/create-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/create-server.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Servers Introduction",permalink:"/docs/servers/introduction"},next:{title:"How to edit a server",permalink:"/docs/servers/edit-server"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-to-create-a-server"},"How to create a server"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," turned on.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to the server icon"),(0,o.kt)("li",{parentName:"ol"},"Press the + action button to make a new server"),(0,o.kt)("li",{parentName:"ol"},"Choose a name for your server"),(0,o.kt)("li",{parentName:"ol"},"Select a password for your server"),(0,o.kt)("li",{parentName:"ol"},"Click on \u201cAdd Server\u201d")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_New.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4912a2e0.20d5fd1e.js b/build-staging/assets/js/4912a2e0.20d5fd1e.js new file mode 100644 index 00000000..57104aaa --- /dev/null +++ b/build-staging/assets/js/4912a2e0.20d5fd1e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1598],{5814:a=>{a.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable","allTagsPath":"/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4972.486cf118.js b/build-staging/assets/js/4972.486cf118.js new file mode 100644 index 00000000..4e318acc --- /dev/null +++ b/build-staging/assets/js/4972.486cf118.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4972],{4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});var a=n(7294),o=n(5999),l=n(1944),r=n(7961);function i(){return a.createElement(a.Fragment,null,a.createElement(l.d,{title:(0,o.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/49ced744.7145707c.js b/build-staging/assets/js/49ced744.7145707c.js new file mode 100644 index 00000000..96461da9 --- /dev/null +++ b/build-staging/assets/js/49ced744.7145707c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5006],{592:e=>{e.exports=JSON.parse('{"title":"Cwtch Components","slug":"/category/cwtch-components","permalink":"/security/category/cwtch-components","navigation":{"previous":{"title":"Risk Model","permalink":"/security/risk"},"next":{"title":"Cwtch Technical Basics","permalink":"/security/components/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4aa555c3.21c48443.js b/build-staging/assets/js/4aa555c3.21c48443.js new file mode 100644 index 00000000..1dc6e38c --- /dev/null +++ b/build-staging/assets/js/4aa555c3.21c48443.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7797],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),u=n,f=h["".concat(c,".").concat(u)]||h[u]||m[u]||o;return a?r.createElement(f,i(i({ref:t},p),{},{components:a})):r.createElement(f,i({ref:t},p))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"June 16, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"release",permalink:"/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/blog/cwtch-nightly-v.11-74"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function m(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(159).Z,width:"1004",height:"480"})))}m.isMDXComponent=!0},159:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4bb443f0.64d3db4a.js b/build-staging/assets/js/4bb443f0.64d3db4a.js new file mode 100644 index 00000000..bf3aa467 --- /dev/null +++ b/build-staging/assets/js/4bb443f0.64d3db4a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4078],{9731:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/testing","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4d27f429.42bfc139.js b/build-staging/assets/js/4d27f429.42bfc139.js new file mode 100644 index 00000000..405b1901 --- /dev/null +++ b/build-staging/assets/js/4d27f429.42bfc139.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[788],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=i.createContext({}),s=function(e){var t=i.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},p="mdxType",b={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(r),d=n,h=p["".concat(c,".").concat(d)]||p[d]||b[d]||a;return r?i.createElement(h,o(o({ref:t},u),{},{components:r})):i.createElement(h,o({ref:t},u))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>b,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"January 20, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"repliqate",permalink:"/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],u={toc:s},p="wrapper";function b(e){let{components:t,...r}=e;return(0,n.kt)(p,(0,i.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,n.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,n.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,n.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,n.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4e8da046.a5a18258.js b/build-staging/assets/js/4e8da046.a5a18258.js new file mode 100644 index 00000000..e263d3c4 --- /dev/null +++ b/build-staging/assets/js/4e8da046.a5a18258.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6368],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),f=s(r),d=o,h=f["".concat(l,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(h,a(a({ref:t},p),{},{components:r})):n.createElement(h,a({ref:t},p))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[f]="string"==typeof e?e:o,a[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},a="An Introduction to Cwtch Profiles",c={unversionedId:"profiles/introduction",id:"profiles/introduction",title:"An Introduction to Cwtch Profiles",description:"With Cwtch you can create one of more Profiles. Each profile generates a random ed25519 key pair compatible with",source:"@site/docs/profiles/introduction.md",sourceDirName:"profiles",slug:"/profiles/introduction",permalink:"/docs/profiles/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Profiles",permalink:"/docs/category/profiles"},next:{title:"Creating a New Profile",permalink:"/docs/profiles/create-a-profile"}},l={},s=[{value:"Manage Profiles",id:"manage-profiles",level:2}],p={toc:s},f="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(f,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"an-introduction-to-cwtch-profiles"},"An Introduction to Cwtch Profiles"),(0,o.kt)("p",null,"With Cwtch you can create one of more ",(0,o.kt)("strong",{parentName:"p"},"Profiles"),". Each profile generates a random ed25519 key pair compatible with\nthe Tor Network."),(0,o.kt)("p",null,"This is the identifier that you can give out to people and that they can use to contact you via Cwtch."),(0,o.kt)("p",null,"Cwtch allows you to create and manage multiple, separate profiles. Each profile is associated with a different\nkey pair which launches a different onion service."),(0,o.kt)("h2",{id:"manage-profiles"},"Manage Profiles"),(0,o.kt)("p",null,"On start up Cwtch will launch the Manage Profiles screen. From this screen you can:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/create-a-profile"},"Create a New Profile")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/unlock-profile"},"Unlock Existing Encrypted Profiles")),(0,o.kt)("li",{parentName:"ul"},"Manage Loaded Profiles",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-name/"},"Changing The Display Name of a Profile")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-password/"},"Changing the Password of a Profile")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/delete-profile"},"Deleting a Profile")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-profile-image/"},"Changing a Profile Image"))))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4e96e24f.ebb3805a.js b/build-staging/assets/js/4e96e24f.ebb3805a.js new file mode 100644 index 00000000..0c7cb741 --- /dev/null +++ b/build-staging/assets/js/4e96e24f.ebb3805a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9726],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>m});var r=n(7294);function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function c(t){for(var e=1;e=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}var l=r.createContext({}),p=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):c(c({},e),t)),n},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},u="mdxType",d={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},f=r.forwardRef((function(t,e){var n=t.components,o=t.mdxType,a=t.originalType,l=t.parentName,s=i(t,["components","mdxType","originalType","parentName"]),u=p(n),f=o,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(m,c(c({ref:e},s),{},{components:n})):r.createElement(m,c({ref:e},s))}));function m(t,e){var n=arguments,o=e&&e.mdxType;if("string"==typeof t||o){var a=n.length,c=new Array(a);c[0]=f;var i={};for(var l in e)hasOwnProperty.call(e,l)&&(i[l]=e[l]);i.originalType=t,i[u]="string"==typeof t?t:o,c[1]=i;for(var p=2;p{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:7},c="Blocking a Contact",i={unversionedId:"chat/block-contact",id:"chat/block-contact",title:"Blocking a Contact",description:"1. On a conversation window",source:"@site/docs/chat/block-contact.md",sourceDirName:"chat",slug:"/chat/block-contact",permalink:"/docs/chat/block-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/block-contact.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Sharing a File",permalink:"/docs/chat/share-file"},next:{title:"Unblocking a Contact",permalink:"/docs/chat/unblock-contact"}},l={},p=[],s={toc:p},u="wrapper";function d(t){let{components:e,...n}=t;return(0,o.kt)(u,(0,r.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"blocking-a-contact"},"Blocking a Contact"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On a conversation window"),(0,o.kt)("li",{parentName:"ol"},"Go to Settings"),(0,o.kt)("li",{parentName:"ol"},"Scroll down to Block Contact"),(0,o.kt)("li",{parentName:"ol"},"Move the switch to Block Contact")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/4f68bcc6.d9b156bf.js b/build-staging/assets/js/4f68bcc6.d9b156bf.js new file mode 100644 index 00000000..e5eed984 --- /dev/null +++ b/build-staging/assets/js/4f68bcc6.d9b156bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3516],{4289:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-security"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/53cc4802.52e4a8c3.js b/build-staging/assets/js/53cc4802.52e4a8c3.js new file mode 100644 index 00000000..07d40820 --- /dev/null +++ b/build-staging/assets/js/53cc4802.52e4a8c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7594],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,d=u["".concat(s,".").concat(m)]||u[m]||g[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"February 3, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"support",permalink:"/blog/tags/support"},{label:"testing",permalink:"/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/blog/cwtch-platform-support"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},u="wrapper";function g(e){let{components:t,...i}=e;return(0,a.kt)(u,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"We first ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,a.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5420a7ba.5c51bc2c.js b/build-staging/assets/js/5420a7ba.5c51bc2c.js new file mode 100644 index 00000000..ecbacfe4 --- /dev/null +++ b/build-staging/assets/js/5420a7ba.5c51bc2c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6515],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},m=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,m=a(e,["components","mdxType","originalType","parentName"]),l=p(r),u=o,f=l["".concat(c,".").concat(u)]||l[u]||g[u]||s;return r?n.createElement(f,i(i({ref:t},m),{},{components:r})):n.createElement(f,i({ref:t},m))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,i=new Array(s);i[0]=u;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[l]="string"==typeof e?e:o,i[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>s,metadata:()=>a,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const s={sidebar_position:6},i="Message Formatting",a={unversionedId:"settings/experiments/message-formatting",id:"settings/experiments/message-formatting",title:"Message Formatting",description:"When enabled, this experiment changes the conversation compose box to add message formatting UX.",source:"@site/docs/settings/experiments/message-formatting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/message-formatting",permalink:"/docs/settings/experiments/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/message-formatting.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Clickable Links Experiment",permalink:"/docs/settings/experiments/clickable-links"},next:{title:"QR Codes",permalink:"/docs/settings/experiments/qrcodes"}},c={},p=[],m={toc:p},l="wrapper";function g(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"message-formatting"},"Message Formatting"),(0,o.kt)("p",null,"When enabled, this experiment changes the conversation compose box to add ",(0,o.kt)("a",{parentName:"p",href:"/docs/chat/message-formatting"},"message formatting")," UX."),(0,o.kt)("p",null,"This experiment is now enabled by default."))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/553b7761.097b3d41.js b/build-staging/assets/js/553b7761.097b3d41.js new file mode 100644 index 00000000..1ab414c4 --- /dev/null +++ b/build-staging/assets/js/553b7761.097b3d41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[732],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>g});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),d=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},u=function(t){var e=d(t.components);return n.createElement(o.Provider,{value:e},t.children)},m="mdxType",s={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},k=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,u=p(t,["components","mdxType","originalType","parentName"]),m=d(a),k=r,g=m["".concat(o,".").concat(k)]||m[k]||s[k]||l;return a?n.createElement(g,i(i({ref:e},u),{},{components:a})):n.createElement(g,i({ref:e},u))}));function g(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=k;var p={};for(var o in e)hasOwnProperty.call(e,o)&&(p[o]=e[o]);p.originalType=t,p[m]="string"==typeof t?t:r,i[1]=p;for(var d=2;d{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var n=a(7462),r=(a(7294),a(3905));const l={},i="Supported Platforms",p={unversionedId:"getting-started/supported_platforms",id:"getting-started/supported_platforms",title:"Supported Platforms",description:"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).",source:"@site/docs/getting-started/supported_platforms.md",sourceDirName:"getting-started",slug:"/getting-started/supported_platforms",permalink:"/docs/getting-started/supported_platforms",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/getting-started/supported_platforms.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/docs/category/getting-started"},next:{title:"Profiles",permalink:"/docs/category/profiles"}},o={},d=[],u={toc:d},m="wrapper";function s(t){let{components:e,...a}=t;return(0,r.kt)(m,(0,n.Z)({},u,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"supported-platforms"},"Supported Platforms"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023)."),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. If you are interested in testing Cwtch on a specific platform, or want to volunteer to help us official support a platform\nnot listed here, then check out ",(0,r.kt)("a",{parentName:"p",href:"/docs/category/contribute"},"Contibuting to Cwtch"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/55d4c988.a6931ed9.js b/build-staging/assets/js/55d4c988.a6931ed9.js new file mode 100644 index 00000000..b3192457 --- /dev/null +++ b/build-staging/assets/js/55d4c988.a6931ed9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6946],{9048:a=>{a.exports=JSON.parse('{"label":"cwtch","permalink":"/blog/tags/cwtch","allTagsPath":"/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5a3f34f2.64523ca8.js b/build-staging/assets/js/5a3f34f2.64523ca8.js new file mode 100644 index 00000000..ff21b6f2 --- /dev/null +++ b/build-staging/assets/js/5a3f34f2.64523ca8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7143],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>f});var o=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function c(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);n&&(o=o.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,o)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=o.createContext({}),l=function(e){var n=o.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=l(e.components);return o.createElement(s.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return o.createElement(o.Fragment,{},n)}},h=o.forwardRef((function(e,n){var t=e.components,r=e.mdxType,c=e.originalType,s=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=l(t),h=r,f=p["".concat(s,".").concat(h)]||p[h]||d[h]||c;return t?o.createElement(f,i(i({ref:n},u),{},{components:t})):o.createElement(f,i({ref:n},u))}));function f(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var c=t.length,i=new Array(c);i[0]=h;var a={};for(var s in n)hasOwnProperty.call(n,s)&&(a[s]=n[s]);a.originalType=e,a[p]="string"==typeof e?e:r,i[1]=a;for(var l=2;l{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var o=t(7462),r=(t(7294),t(3905));const c={sidebar_position:1},i="Block Unknown Connections",a={unversionedId:"settings/behaviour/block-unknown-connections",id:"settings/behaviour/block-unknown-connections",title:"Block Unknown Connections",description:"By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. You can change this behaviour through the Block Unknown Connections",source:"@site/docs/settings/behaviour/block-unknown-connections.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/block-unknown-connections",permalink:"/docs/settings/behaviour/block-unknown-connections",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/block-unknown-connections.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Behaviour",permalink:"/docs/category/behaviour"},next:{title:"Notification policy",permalink:"/docs/settings/behaviour/notification-policy"}},s={},l=[],u={toc:l},p="wrapper";function d(e){let{components:n,...t}=e;return(0,r.kt)(p,(0,o.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"block-unknown-connections"},"Block Unknown Connections"),(0,r.kt)("p",null,"By default, Cwtch interprets connections from unknown Cwtch addresses as ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/chat/accept-deny-new-conversation"},"Contact Requests"),". You can change this behaviour through the Block Unknown Connections\nsetting."),(0,r.kt)("p",null,"If enabled, Cwtch will auto close all connections from Cwtch addresses that you have not added to your conversation\nlist. This will prevent people who have your Cwtch address from contacting you unless you also add them."),(0,r.kt)("p",null,"To enable:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Go to Settings"),(0,r.kt)("li",{parentName:"ol"},"Toggle on Block Unknown Contacts")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5a5e3510.d3615000.js b/build-staging/assets/js/5a5e3510.d3615000.js new file mode 100644 index 00000000..66ebfdb5 --- /dev/null +++ b/build-staging/assets/js/5a5e3510.d3615000.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1315],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=n.createContext({}),c=function(e){var r=n.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},l=function(e){var r=c(e.components);return n.createElement(p.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},f=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(t),f=o,m=u["".concat(p,".").concat(f)]||u[f]||d[f]||a;return t?n.createElement(m,i(i({ref:r},l),{},{components:t})):n.createElement(m,i({ref:r},l))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=f;var s={};for(var p in r)hasOwnProperty.call(r,p)&&(s[p]=r[p]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var c=2;c{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:3},i="Changing Your Password",s={unversionedId:"profiles/change-password",id:"profiles/change-password",title:"Changing Your Password",description:"1. Press the pencil next to the profile you want to edit",source:"@site/docs/profiles/change-password.md",sourceDirName:"profiles",slug:"/profiles/change-password",permalink:"/docs/profiles/change-password",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-password.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Changing Your Display Name",permalink:"/docs/profiles/change-name"},next:{title:"Changing Your Profile Image",permalink:"/docs/profiles/change-profile-image"}},p={},c=[],l={toc:c},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"changing-your-password"},"Changing Your Password"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Press the pencil next to the profile you want to edit"),(0,o.kt)("li",{parentName:"ol"},"Go to current password and input your current password"),(0,o.kt)("li",{parentName:"ol"},"Go to new password and input your new password"),(0,o.kt)("li",{parentName:"ol"},"Re enter your password"),(0,o.kt)("li",{parentName:"ol"},"Click Save profile")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5b041459.73b0c096.js b/build-staging/assets/js/5b041459.73b0c096.js new file mode 100644 index 00000000..7db4c005 --- /dev/null +++ b/build-staging/assets/js/5b041459.73b0c096.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7710],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),h=c(n),p=o,m=h["".concat(l,".").concat(p)]||h[p]||d[p]||i;return n?a.createElement(m,r(r({ref:t},u),{},{components:n})):a.createElement(m,r({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[h]="string"==typeof e?e:o,r[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var a=n(7462),o=(n(7294),n(3905));const i={sidebar_position:2},r="Risk Model",s={unversionedId:"risk",id:"risk",title:"Risk Model",description:"Communications metadata is known to be exploited by various adversaries to",source:"@site/security/risk.md",sourceDirName:".",slug:"/risk",permalink:"/security/risk",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch Security Handbook",permalink:"/security/intro"},next:{title:"Cwtch Components",permalink:"/security/category/cwtch-components"}},l={},c=[{value:"Threat Model",id:"threat-model",level:2},{value:"Active Attacks",id:"active-attacks",level:3},{value:"Misrepresentation Attacks",id:"misrepresentation-attacks",level:4},{value:"A note on Physical Attacks",id:"a-note-on-physical-attacks",level:2}],u={toc:c},h="wrapper";function d(e){let{components:t,...i}=e;return(0,o.kt)(h,(0,a.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"risk-model"},"Risk Model"),(0,o.kt)("p",null,"Communications metadata is known to be exploited by various adversaries to\nundermine the security of systems, to track victims\nand to conduct large scale social network analysis to feed mass surveillance.\nMetadata resistant tools are in their infancy and research into the construction\nand user experience of such tools is lacking."),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(5448).Z,width:"1920",height:"1080"})),(0,o.kt)("p",null,"Cwtch was originally conceived as an extension of the metadata resistant protocol\nRicochet to support asynchronous, multi-peer group communications through the\nuse of discardable, untrusted, anonymous infrastructure."),(0,o.kt)("p",null,"Since then, Cwtch has evolved into a protocol in its own right, this section\nwill outline the various known risks that Cwtch attempts to mitigate and will\nbe heavily referenced throughout the rest of the document when discussing the\nvarious sub-components of the Cwtch Architecture."),(0,o.kt)("h2",{id:"threat-model"},"Threat Model"),(0,o.kt)("p",null,"It is important to identify and understand that metadata is ubiquitous in\ncommunication protocols, it is indeed necessary for such protocols to\nfunction efficiently and at scale. However, information that is useful to\nfacilitating peers and servers is also highly relevant to adversaries\nwishing to exploit such information."),(0,o.kt)("p",null,"For our problem definition, we will assume that the content of a communication is\nencrypted in such a way that an adversary is practically unable to break\n(see ",(0,o.kt)("a",{parentName:"p",href:"/security/category/tapir"},"tapir")," and ",(0,o.kt)("a",{parentName:"p",href:"security/category/cwtch"},"cwtch")," for details on the\nencryption that we use, a\nand as such we will focus to the context to the communication metadata."),(0,o.kt)("p",null,"We seek to protect the following communication contexts:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Who is involved in a communication? It may be possible to identify\npeople or simply device or network identifiers. E.g., \u201cthis communication involves Alice, a journalist, and Bob a government employee.\u201d."),(0,o.kt)("li",{parentName:"ul"},"Where are the participants of the conversation? E.g., \u201cduring this\ncommunication Alice was in France and Bob was in Canada.\u201d"),(0,o.kt)("li",{parentName:"ul"},"When did a conversation take place? The timing and length of communication\ncan reveal a large amount about the nature of a call, e.g., \u201cBob a government employee, talked to Alice on the phone for an hour yesterday evening. This is the first time they have communicated.\u201d\n*How was the conversation mediated? Whether a conversation took place over an\nencrypted or unencrypted email can provide useful intelligence. E.g., \u201cAlice sent an encrypted email to Bob yesterday, whereas they usually only send plaintext emails to each other.\u201d"),(0,o.kt)("li",{parentName:"ul"},"What is the conversation about? Even if the content of the communication is\nencrypted it is sometimes possible to derive a probable context of a conversation without knowing exactly what is said, e.g. \u201ca person called a pizza store at dinner time\u201d or \u201csomeone called a known suicide hotline number at 3am.\u201d")),(0,o.kt)("p",null,"Beyond individual conversations, we also seek to defend against context correlation attacks, whereby multiple conversations are analyzed to derive higher level information:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Relationships: Discovering social relationships between a pair of entities\nby analyzing the frequency and length of their communications over a period of time. E.g. Carol and Eve call each other every single day for multiple hours at a time."),(0,o.kt)("li",{parentName:"ul"},"Cliques: Discovering social relationships between a group of entities that\nall interact with each other. E.g. Alice, Bob and Eve all communicate with each other."),(0,o.kt)("li",{parentName:"ul"},"Loosely Connected Cliques and Bridge Individuals: Discovering groups that\ncommunicate to each other through intermediaries by analyzing communication chains (e.g. everytime Alice talks to Bob she talks to Carol almost immediately after; Bob and Carol never communicate.)"),(0,o.kt)("li",{parentName:"ul"},"Pattern of Life: Discovering which communications are cyclical and\npredictable. E.g. Alice calls Eve every Monday evening for around an hour.")),(0,o.kt)("h3",{id:"active-attacks"},"Active Attacks"),(0,o.kt)("h4",{id:"misrepresentation-attacks"},"Misrepresentation Attacks"),(0,o.kt)("p",null,"Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks\nbased around misrepresentation i.e. people pretending to be other people:"),(0,o.kt)("p",null,"A basic flow of one of these attacks is as follows, although other flows also exist:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Alice has a friend named Bob and another called Eve"),(0,o.kt)("li",{parentName:"ul"},"Eve finds out Alice has a friend named Bob"),(0,o.kt)("li",{parentName:"ul"},"Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)"),(0,o.kt)("li",{parentName:"ul"},'Eve calls this new account "Eve New Account" and adds Alice as a friend.'),(0,o.kt)("li",{parentName:"ul"},'Eve then changes her name on "Eve New Account" to "Bob"'),(0,o.kt)("li",{parentName:"ul"},'Alice sends messages intended for "Bob" to Eve\'s fake Bob account')),(0,o.kt)("p",null,"Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them\nis for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply ",(0,o.kt)("em",{parentName:"p"},"won't-happen"),"."),(0,o.kt)("p",null,"As such we aim to provide some user-experience hints in the ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," to guide people in making choices around whether\nto trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users."),(0,o.kt)("h2",{id:"a-note-on-physical-attacks"},"A note on Physical Attacks"),(0,o.kt)("p",null,"Cwtch does not consider attacks that require physical access (or equivalent) to\nthe users machine as practically defendable. However, in the interests of good\nsecurity engineering, throughout this document we will still\nrefer to attacks or conditions that require such privilege and point out\nwhere any mitigations we have put in place will fail."))}d.isMDXComponent=!0},5448:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/4-698e941dd333a7200cddec8d926e9ca9.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5b4e4bee.56fd8448.js b/build-staging/assets/js/5b4e4bee.56fd8448.js new file mode 100644 index 00000000..476cbbaa --- /dev/null +++ b/build-staging/assets/js/5b4e4bee.56fd8448.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3171],{8340:e=>{e.exports=JSON.parse('{"title":"Connectivity & Tor","slug":"/category/connectivity--tor","permalink":"/security/category/connectivity--tor","navigation":{"previous":{"title":"Component Ecosystem Overview","permalink":"/security/components/ecosystem-overview"},"next":{"title":"Connectivity","permalink":"/security/components/connectivity/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5beee875.70ab5e61.js b/build-staging/assets/js/5beee875.70ab5e61.js new file mode 100644 index 00000000..2a03ad11 --- /dev/null +++ b/build-staging/assets/js/5beee875.70ab5e61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9444],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(n),m=r,g=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return n?a.createElement(g,i(i({ref:t},s),{},{components:n})):a.createElement(g,i({ref:t},s))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"June 7, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/blog/cwtch-developer-documentation"}},c={authorsImageUrls:[void 0]},p=[{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,r.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(9964).Z,width:"1005",height:"481"})),(0,r.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,r.kt)("p",null,"There is a ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,r.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/"},"2023-06-05-17-36-v1.11.0-74-g0406"),"."),(0,r.kt)("p",null,"This version has a large number of improvements and bug fixes including:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A new Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor."),(0,r.kt)("li",{parentName:"ul"},"Updated UI font styles"),(0,r.kt)("li",{parentName:"ul"},"Dependency updates, including a new base of Flutter 3.10."),(0,r.kt)("li",{parentName:"ul"},"A fix for stuck file downloading notifications on Android"),(0,r.kt)("li",{parentName:"ul"},"A fix for missing profile images in certain edge cases on Android"),(0,r.kt)("li",{parentName:"ul"},"Japanese, Swedish, and Swahili translation options"),(0,r.kt)("li",{parentName:"ul"},"A new retry peer connection button for prompting Cwtch to prioritize specific connections"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails support"))),(0,r.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9964:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5cb298ca.ec2236e7.js b/build-staging/assets/js/5cb298ca.ec2236e7.js new file mode 100644 index 00000000..3d864ade --- /dev/null +++ b/build-staging/assets/js/5cb298ca.ec2236e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2909],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(r),m=n,d=h["".concat(l,".").concat(m)]||h[m]||u[m]||o;return r?a.createElement(d,i(i({ref:t},s),{},{components:r})):a.createElement(d,i({ref:t},s))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"April 28, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/blog/availability-status-profile-attributes"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5dc151e9.3afedfb7.js b/build-staging/assets/js/5dc151e9.3afedfb7.js new file mode 100644 index 00000000..5b1415cd --- /dev/null +++ b/build-staging/assets/js/5dc151e9.3afedfb7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[923],{3905:(t,e,a)=>{a.d(e,{Zo:()=>s,kt:()=>g});var r=a(7294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,r)}return a}function i(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var d=r.createContext({}),p=function(t){var e=r.useContext(d),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},s=function(t){var e=p(t.components);return r.createElement(d.Provider,{value:e},t.children)},u="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},m=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,l=t.originalType,d=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(a),m=n,g=u["".concat(d,".").concat(m)]||u[m]||c[m]||l;return a?r.createElement(g,i(i({ref:e},s),{},{components:a})):r.createElement(g,i({ref:e},s))}));function g(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var d in e)hasOwnProperty.call(e,d)&&(o[d]=e[d]);o.originalType=t,o[u]="string"==typeof t?t:n,i[1]=o;for(var p=2;p{a.r(e),a.d(e,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const l={sidebar_position:1},i="Release and Packaging Process",o={unversionedId:"release",id:"release",title:"Release and Packaging Process",description:"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.",source:"@site/developing/release.md",sourceDirName:".",slug:"/release",permalink:"/developing/release",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Introduction to Cwtch Development",permalink:"/developing/intro"},next:{title:"Building a Cwtch App",permalink:"/developing/category/building-a-cwtch-app"}},d={},p=[{value:"Automated Testing",id:"automated-testing",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"UI Nightly Builds",id:"ui-nightly-builds",level:2},{value:"Official Releases",id:"official-releases",level:2},{value:"Reproducible Builds",id:"reproducible-builds",level:3}],s={toc:p},u="wrapper";function c(t){let{components:e,...a}=t;return(0,n.kt)(u,(0,r.Z)({},s,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member."),(0,n.kt)("h2",{id:"automated-testing"},"Automated Testing"),(0,n.kt)("p",null,"Drone carries out a suite of automated tests at various stages of the release pipeline."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Test Suite"),(0,n.kt)("th",{parentName:"tr",align:null},"Repository"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"A full exercise of peer-to-peer and group messaging")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"File Sharing Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that file sharing and image downloading work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Automated Download Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that automated image downloading (e.g. profile pictures) work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"UI Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch-ui"),(0,n.kt)("td",{parentName:"tr",align:null},"A suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings")))),(0,n.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,n.kt)("p",null,"Drone produces the following build artifacts for all Cwtch autobindings builds."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch-sources.jar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"gomobile derived source code for the Android Cwtch library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch.aar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android Cwtch library. Supports arm, arm64, and amd64.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.so"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.dll"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 bit shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.arm64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"Arm64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.x64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")))),(0,n.kt)("h2",{id:"ui-nightly-builds"},"UI Nightly Builds"),(0,n.kt)("p",null,"We make unreleased versions of Cwtch available for testing as ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"Cwtch Nightlies"),"."),(0,n.kt)("p",null,"Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.apk"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Supports arm, arm64, and amd64. Can be sideloaded.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.aab"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android App Bundle for publishing to appstores")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Cwtch-VERSION.dmg"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.tar.gz"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"Contains the code, libs, and assets in addition to install scripts for various devices")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.zip"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-installer-VERSION.exe"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"NSIS powered installation wizard")))),(0,n.kt)("p",null,"Nightly builds are regularly purged from the system"),(0,n.kt)("h2",{id:"official-releases"},"Official Releases"),(0,n.kt)("p",null,"The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps."),(0,n.kt)("p",null,"When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. ",(0,n.kt)("inlineCode",{parentName:"p"},"v.1.12.0"),". The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder."),(0,n.kt)("h3",{id:"reproducible-builds"},"Reproducible Builds"),(0,n.kt)("p",null,"We use ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate")," to provide ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"reproducible build scripts for Cwtch"),"."),(0,n.kt)("p",null,"We update the ",(0,n.kt)("inlineCode",{parentName:"p"},"repliqate-scripts")," repository with scripts for all official releases. Currently only Cwtch bindings are reproducible"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5e5faacc.56cc8faf.js b/build-staging/assets/js/5e5faacc.56cc8faf.js new file mode 100644 index 00000000..240fcc55 --- /dev/null +++ b/build-staging/assets/js/5e5faacc.56cc8faf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8192],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>h});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function o(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function l(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=n.createContext({}),p=function(t){var e=n.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},u=function(t){var e=p(t.components);return n.createElement(s.Provider,{value:e},t.children)},d="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,o=t.originalType,s=t.parentName,u=i(t,["components","mdxType","originalType","parentName"]),d=p(a),m=r,h=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return a?n.createElement(h,l(l({ref:e},u),{},{components:a})):n.createElement(h,l({ref:e},u))}));function h(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var o=a.length,l=new Array(o);l[0]=m;var i={};for(var s in e)hasOwnProperty.call(e,s)&&(i[s]=e[s]);i.originalType=t,i[d]="string"==typeof t?t:r,l[1]=i;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const o={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"January 27, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"support",permalink:"/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/blog/cwtch-bindings-reproducible"}},s={authorsImageUrls:[void 0]},p=[{value:"Constraints on support",id:"constraints-on-support",level:2},{value:"Limitations on general-purpose computing",id:"limitations-on-general-purpose-computing",level:3},{value:"Constraints introduced by the Flutter SDK",id:"constraints-introduced-by-the-flutter-sdk",level:3},{value:"Constraints introduced by Appstore Policy",id:"constraints-introduced-by-appstore-policy",level:3},{value:"CPU Architecture and Cwtch Bindings",id:"cpu-architecture-and-cwtch-bindings",level:3},{value:"Testing and official support",id:"testing-and-official-support",level:3},{value:"End-of-life platforms",id:"end-of-life-platforms",level:3},{value:"How we decide to officially support a platform",id:"how-we-decide-to-officially-support-a-platform",level:2},{value:"Summary of official support",id:"summary-of-official-support",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},d="wrapper";function c(t){let{components:e,...o}=t;return(0,r.kt)(d,(0,n.Z)({},u,o,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"One of the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,r.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,r.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,r.kt)("p",null,"The questions we aim to answer in this post are: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,r.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,r.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,r.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,r.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6149).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraints-on-support"},"Constraints on support"),(0,r.kt)("p",null,"From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. "),(0,r.kt)("p",null,"In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms."),(0,r.kt)("h3",{id:"limitations-on-general-purpose-computing"},"Limitations on general-purpose computing"),(0,r.kt)("p",null,"In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to ",(0,r.kt)("em",{parentName:"p"},"other")," onion services). "),(0,r.kt)("p",null,"On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, ",(0,r.kt)("strong",{parentName:"p"},"blocked entirely"),". "),(0,r.kt)("p",null,"This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind."),(0,r.kt)("p",null,"While we expect that ",(0,r.kt)("a",{parentName:"p",href:"https://gitlab.torproject.org/tpo/core/arti"},"Arti")," will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. "),(0,r.kt)("p",null,"As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable."),(0,r.kt)("p",null,"We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device."),(0,r.kt)("h3",{id:"constraints-introduced-by-the-flutter-sdk"},"Constraints introduced by the Flutter SDK"),(0,r.kt)("p",null,"The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms"},"platforms that are supported by the Flutter SDK"),"."),(0,r.kt)("p",null,"To summarize, as of writing this document those platforms are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Android API 16 and above (arm, arm64, and amd64)"),(0,r.kt)("li",{parentName:"ul"},"Debian-based Linux Distributions (64-bit only)"),(0,r.kt)("li",{parentName:"ul"},"macOS El Capitan (10.11) and above"),(0,r.kt)("li",{parentName:"ul"},"Windows 7 & above (64-bit only)")),(0,r.kt)("p",null,"To put it plainly, without porting Cwtch UI to a different UI platform ",(0,r.kt)("strong",{parentName:"p"},"we cannot support a 32-bit desktop version"),"."),(0,r.kt)("h3",{id:"constraints-introduced-by-appstore-policy"},"Constraints introduced by Appstore Policy"),(0,r.kt)("p",null,"As of writing, ",(0,r.kt)("a",{parentName:"p",href:"https://developer.android.com/google/play/requirements/target-sdk"},"Google is pushing applications to target API 31 or above"),". This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality."),(0,r.kt)("h3",{id:"cpu-architecture-and-cwtch-bindings"},"CPU Architecture and Cwtch Bindings"),(0,r.kt)("p",null,"We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for."),(0,r.kt)("p",null,"It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Architecture / Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Windows"),(0,r.kt)("th",{parentName:"tr",align:null},"Linux"),(0,r.kt)("th",{parentName:"tr",align:null},"macOS"),(0,r.kt)("th",{parentName:"tr",align:null},"Android"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"x86-64 / amd64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")))),(0,r.kt)("p",null,'"\ud83d\udfe1" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).'),(0,r.kt)("h3",{id:"testing-and-official-support"},"Testing and official support"),(0,r.kt)("p",null,"As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers")," to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues."),(0,r.kt)("p",null,"We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances."),(0,r.kt)("h3",{id:"end-of-life-platforms"},"End-of-life platforms"),(0,r.kt)("p",null,"Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. ",(0,r.kt)("a",{parentName:"p",href:"https://www.microsoft.com/en-us/windows/end-of-support"},"Windows 7 fell out of support on January 14, 2020"),", Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025."),(0,r.kt)("p",null,"Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also."),(0,r.kt)("p",null,"The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations"},"Cwtch currently requires libc 2.31+"),"."),(0,r.kt)("p",null,"Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers groups")," to help us understand the limitations of Android support across different API versions."),(0,r.kt)("h2",{id:"how-we-decide-to-officially-support-a-platform"},"How we decide to officially support a platform"),(0,r.kt)("p",null,"To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform needs to be officially supported by our development tools")," - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target operating system needs to be supported by the Vendor")," - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform must be backwards compatible with the most recent version in general use")," - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch ",(0,r.kt)("em",{parentName:"li"},"may")," run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"People want to use Cwtch on that platform")," - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!")),(0,r.kt)("h2",{id:"summary-of-official-support"},"Summary of official support"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). "),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. A version of this table will be ",(0,r.kt)("a",{parentName:"p",href:"/docs/getting-started/supported_platforms"},"maintained as part of the Cwtch Handbook"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607"},"Known Issues. Specific changes to Cwtch are required for support."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}c.isMDXComponent=!0},6149:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/5f6192c8.8175778b.js b/build-staging/assets/js/5f6192c8.8175778b.js new file mode 100644 index 00000000..f2e9c501 --- /dev/null +++ b/build-staging/assets/js/5f6192c8.8175778b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7479],{8271:t=>{t.exports=JSON.parse('{"title":"Tapir","slug":"/category/tapir","permalink":"/security/category/tapir","navigation":{"previous":{"title":"Connectivity","permalink":"/security/components/connectivity/intro"},"next":{"title":"Packet Format","permalink":"/security/components/tapir/packet_format"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6015355d.bdad9d73.js b/build-staging/assets/js/6015355d.bdad9d73.js new file mode 100644 index 00000000..20e5dfdb --- /dev/null +++ b/build-staging/assets/js/6015355d.bdad9d73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[198],{4978:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/cwtch-stable/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/blog/tags/cwtch-stable","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6048.9165c150.js b/build-staging/assets/js/6048.9165c150.js new file mode 100644 index 00000000..9bdd9013 --- /dev/null +++ b/build-staging/assets/js/6048.9165c150.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6048],{9058:(e,t,a)=>{a.d(t,{Z:()=>p});var l=a(7294),r=a(6010),n=a(7961),o=a(7524),s=a(9960),i=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function c(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,i.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function d(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function g(e){return l.createElement(u.Zo,{component:d,props:e})}function h(e){let{sidebar:t}=e;const a=(0,o.i)();return t?.items.length?"mobile"===a?l.createElement(g,{sidebar:t}):l.createElement(c,{sidebar:t}):null}function p(e){const{sidebar:t,toc:a,children:o,...s}=e,i=t&&t.items.length>0;return l.createElement(n.Z,s,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(h,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":i,"col--9 col--offset-1":!i}),itemScope:!0,itemType:"http://schema.org/Blog"},o),a&&l.createElement("div",{className:"col col--2"},a))))}},1286:(e,t,a)=>{a.d(t,{Z:()=>A});var l=a(7294),r=a(6010),n=a(9460),o=a(4996);function s(e){let{children:t,className:a}=e;const{frontMatter:r,assets:s}=(0,n.C)(),{withBaseUrl:i}=(0,o.C)(),m=s.image??r.image;return l.createElement("article",{className:a,itemProp:"blogPost",itemScope:!0,itemType:"http://schema.org/BlogPosting"},m&&l.createElement("meta",{itemProp:"image",content:i(m,{absolute:!0})}),t)}var i=a(9960);const m={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,n.C)(),{permalink:s,title:c}=a,u=o?"h1":"h2";return l.createElement(u,{className:(0,r.Z)(m.title,t),itemProp:"headline"},o?c:l.createElement(i.Z,{itemProp:"url",to:s},c))}var u=a(5999),d=a(8824);const g={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,d.c)();return t=>{const a=Math.ceil(t);return e(a,(0,u.I)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return l.createElement(l.Fragment,null,a(t))}function p(e){let{date:t,formattedDate:a}=e;return l.createElement("time",{dateTime:t,itemProp:"datePublished"},a)}function b(){return l.createElement(l.Fragment,null," \xb7 ")}function E(e){let{className:t}=e;const{metadata:a}=(0,n.C)(),{date:o,formattedDate:s,readingTime:i}=a;return l.createElement("div",{className:(0,r.Z)(g.container,"margin-vert--md",t)},l.createElement(p,{date:o,formattedDate:s}),void 0!==i&&l.createElement(l.Fragment,null,l.createElement(b,null),l.createElement(h,{readingTime:i})))}function f(e){return e.href?l.createElement(i.Z,e):l.createElement(l.Fragment,null,e.children)}function v(e){let{author:t,className:a}=e;const{name:n,title:o,url:s,imageURL:i,email:m}=t,c=s||m&&`mailto:${m}`||void 0;return l.createElement("div",{className:(0,r.Z)("avatar margin-bottom--sm",a)},i&&l.createElement(f,{href:c,className:"avatar__photo-link"},l.createElement("img",{className:"avatar__photo",src:i,alt:n})),n&&l.createElement("div",{className:"avatar__intro",itemProp:"author",itemScope:!0,itemType:"https://schema.org/Person"},l.createElement("div",{className:"avatar__name"},l.createElement(f,{href:c,itemProp:"url"},l.createElement("span",{itemProp:"name"},n))),o&&l.createElement("small",{className:"avatar__subtitle",itemProp:"description"},o)))}const P={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function N(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,n.C)();if(0===a.length)return null;const s=a.every((e=>{let{name:t}=e;return!t}));return l.createElement("div",{className:(0,r.Z)("margin-top--md margin-bottom--sm",s?P.imageOnlyAuthorRow:"row",t)},a.map(((e,t)=>l.createElement("div",{className:(0,r.Z)(!s&&"col col--6",s?P.imageOnlyAuthorCol:P.authorCol),key:t},l.createElement(v,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})))))}function _(){return l.createElement("header",null,l.createElement(c,null),l.createElement(E,null),l.createElement(N,null))}var k=a(8780),Z=a(1506);function I(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,n.C)();return l.createElement("div",{id:o?k.blogPostContainerID:void 0,className:(0,r.Z)("markdown",a),itemProp:"articleBody"},l.createElement(Z.Z,null,t))}var C=a(4881),w=a(1526),T=a(7462);function y(){return l.createElement("b",null,l.createElement(u.Z,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts"},"Read More"))}function F(e){const{blogPostTitle:t,...a}=e;return l.createElement(i.Z,(0,T.Z)({"aria-label":(0,u.I)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t})},a),l.createElement(y,null))}const L={blogPostFooterDetailsFull:"blogPostFooterDetailsFull_mRVl"};function B(){const{metadata:e,isBlogPostPage:t}=(0,n.C)(),{tags:a,title:o,editUrl:s,hasTruncateMarker:i}=e,m=!t&&i,c=a.length>0;return c||m||s?l.createElement("footer",{className:(0,r.Z)("row docusaurus-mt-lg",t&&L.blogPostFooterDetailsFull)},c&&l.createElement("div",{className:(0,r.Z)("col",{"col--9":m})},l.createElement(w.Z,{tags:a})),t&&s&&l.createElement("div",{className:"col margin-top--sm"},l.createElement(C.Z,{editUrl:s})),m&&l.createElement("div",{className:(0,r.Z)("col text--right",{"col--3":c})},l.createElement(F,{blogPostTitle:o,to:e.permalink}))):null}function A(e){let{children:t,className:a}=e;const o=function(){const{isBlogPostPage:e}=(0,n.C)();return e?void 0:"margin-bottom--xl"}();return l.createElement(s,{className:(0,r.Z)(o,a)},l.createElement(_,null),l.createElement(I,null,t),l.createElement(B,null))}},9460:(e,t,a)=>{a.d(t,{C:()=>s,n:()=>o});var l=a(7294),r=a(902);const n=l.createContext(null);function o(e){let{children:t,content:a,isBlogPostPage:r=!1}=e;const o=function(e){let{content:t,isBlogPostPage:a}=e;return(0,l.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:r});return l.createElement(n.Provider,{value:o},t)}function s(){const e=(0,l.useContext)(n);if(null===e)throw new r.i6("BlogPostProvider");return e}},8824:(e,t,a)=>{a.d(t,{c:()=>m});var l=a(7294),r=a(2263);const n=["zero","one","two","few","many","other"];function o(e){return n.filter((t=>e.includes(t)))}const s={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function i(){const{i18n:{currentLocale:e}}=(0,r.Z)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:o(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),s}}),[e])}function m(){const e=i();return{selectMessage:(t,a)=>function(e,t,a){const l=e.split("|");if(1===l.length)return l[0];l.length>a.pluralForms.length&&console.error(`For locale=${a.locale}, a maximum of ${a.pluralForms.length} plural forms are expected (${a.pluralForms.join(",")}), but the message contains ${l.length}: ${e}`);const r=a.select(t),n=a.pluralForms.indexOf(r);return l[Math.min(n,l.length-1)]}(a,t,e)}}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/61794344.9d788f2d.js b/build-staging/assets/js/61794344.9d788f2d.js new file mode 100644 index 00000000..fb37b1ca --- /dev/null +++ b/build-staging/assets/js/61794344.9d788f2d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6232],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(a),u=o,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||r;return a?n.createElement(m,i(i({ref:t},p),{},{components:a})):n.createElement(m,i({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"June 30, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/blog/cwtch-nightly-1-12"}},s={authorsImageUrls:[void 0]},c=[{value:"Update on the Cwtch Stable Roadmap",id:"update-on-the-cwtch-stable-roadmap",level:2},{value:"Next Steps, Refinements, Additional Work",id:"next-steps-refinements-additional-work",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(h,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,o.kt)("p",null,"This post ",(0,o.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h2",{id:"update-on-the-cwtch-stable-roadmap"},"Update on the Cwtch Stable Roadmap"),(0,o.kt)("p",null,"Back in March we extended and updated several goals from ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"our January roadmap")," that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing."),(0,o.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/#official-releases"},"Release Process")),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/"},"Packaging Documentation")),(0,o.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new ",(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"documentation style guide"),", and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/category/building-a-cwtch-app"},"Building a Cwtch App")),(0,o.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. "))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"An implementation of ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")," \ud83d\udfe1 - currently in ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518"},"active development")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information \u2705 - released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")),(0,o.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")," \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12"),". We now believe these changes will be complete in Cwtch Beta 1.13."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks."),(0,o.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below)."),(0,o.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,o.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")," \ud83d\udfe1 - we have already launched an environment for testing ",(0,o.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails"),". Other platforms are underway."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable."),(0,o.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,o.kt)("h2",{id:"next-steps-refinements-additional-work"},"Next Steps, Refinements, Additional Work"),(0,o.kt)("p",null,"As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. "),(0,o.kt)("p",null,"Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like."),(0,o.kt)("p",null,"However, ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")," featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing."),(0,o.kt)("p",null,"The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup."),(0,o.kt)("p",null,"We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards."),(0,o.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,o.kt)("h2",{id:"get-involved"},"Get Involved"),(0,o.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,o.kt)("p",null,"We also also updated our guides on ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,o.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,o.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,o.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6275ceb4.9ce4f8c9.js b/build-staging/assets/js/6275ceb4.9ce4f8c9.js new file mode 100644 index 00000000..9ed0d80b --- /dev/null +++ b/build-staging/assets/js/6275ceb4.9ce4f8c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6555],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),d=a,m=h["".concat(s,".").concat(d)]||h[d]||u[d]||r;return n?o.createElement(m,i(i({ref:t},p),{},{components:n})):o.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,i[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const r={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"March 10, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/blog/tags/documentation"},{label:"security-handbook",permalink:"/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/blog/autobindings-ii"}},s={authorsImageUrls:[void 0]},c=[{value:"Cwtch Secure Development Handbook",id:"cwtch-secure-development-handbook",level:2},{value:"Volunteer Development",id:"volunteer-development",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(h,(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"cwtch-secure-development-handbook"},"Cwtch Secure Development Handbook"),(0,a.kt)("p",null,"One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions."),(0,a.kt)("p",null,"We have ",(0,a.kt)("a",{parentName:"p",href:"/security/intro"},"now ported the the handbook to this documentation site"),", along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. "),(0,a.kt)("h2",{id:"volunteer-development"},"Volunteer Development"),(0,a.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,a.kt)("p",null,"We also also updated our guides on ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,a.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,a.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"We still have more work to do on the documentation front:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Ensuring all pages ",(0,a.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"implement the new documentation style guide"),", and include appropriate screenshots and descriptions."),(0,a.kt)("li",{parentName:"ul"},"Expanding the security handbook to provide information on ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"reproducible builds"),", ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"the new Cwtch Stable API")," and upcoming improvements around fuzz testing."),(0,a.kt)("li",{parentName:"ul"},"Creating new documentation sections on the ",(0,a.kt)("a",{parentName:"li",href:"/blog/autobindings"},"libCwtch autobindings API")," and building applications on top of Cwtch.")),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/628b3074.b8e971a6.js b/build-staging/assets/js/628b3074.b8e971a6.js new file mode 100644 index 00000000..f22843eb --- /dev/null +++ b/build-staging/assets/js/628b3074.b8e971a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3478],{827:e=>{e.exports=JSON.parse('{"title":"Contribute","slug":"/category/contribute","permalink":"/docs/category/contribute","navigation":{"previous":{"title":"Tor","permalink":"/docs/tor"},"next":{"title":"Developing Cwtch","permalink":"/docs/contribute/developing"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6575cef9.c5f6ea1e.js b/build-staging/assets/js/6575cef9.c5f6ea1e.js new file mode 100644 index 00000000..8b3b0c8f --- /dev/null +++ b/build-staging/assets/js/6575cef9.c5f6ea1e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8588],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(r),d=i,b=p["".concat(s,".").concat(d)]||p[d]||f[d]||o;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));function b(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:i,a[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:10},a="Stickers",c={unversionedId:"contribute/stickers",id:"contribute/stickers",title:"Stickers",description:"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email erinn@openprivacy.ca with details and an address for us to mail stickers to.",source:"@site/docs/contribute/stickers.md",sourceDirName:"contribute",slug:"/contribute/stickers",permalink:"/docs/contribute/stickers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/stickers.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Documentation Style Guide",permalink:"/docs/contribute/documentation"},next:{title:"Platforms",permalink:"/docs/category/platforms"}},s={},l=[],u={toc:l},p="wrapper";function f(e){let{components:t,...o}=e;return(0,i.kt)(p,(0,n.Z)({},u,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"stickers"},"Stickers"),(0,i.kt)("p",null,"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email ",(0,i.kt)("a",{parentName:"p",href:"mailto:erinn@openprivacy.ca"},"erinn@openprivacy.ca")," with details and an address for us to mail stickers to."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:r(4515).Z,width:"1024",height:"768"})))}f.isMDXComponent=!0},4515:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/663d5f0b.43de0547.js b/build-staging/assets/js/663d5f0b.43de0547.js new file mode 100644 index 00000000..42e8a1d2 --- /dev/null +++ b/build-staging/assets/js/663d5f0b.43de0547.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7992],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>g});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,g=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?n.createElement(g,s(s({ref:r},l),{},{components:t})):n.createElement(g,s({ref:r},l))}));function g(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,s=new Array(a);s[0]=m;var i={};for(var c in r)hasOwnProperty.call(r,c)&&(i[c]=r[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var p=2;p{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:7},s="Managing Servers",i={unversionedId:"groups/manage-known-servers",id:"groups/manage-known-servers",title:"Managing Servers",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/manage-known-servers.md",sourceDirName:"groups",slug:"/groups/manage-known-servers",permalink:"/docs/groups/manage-known-servers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/manage-known-servers.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Editing a Group Name",permalink:"/docs/groups/edit-group-name"},next:{title:"Servers",permalink:"/docs/category/servers"}},c={},p=[{value:"Import locally hosted server",id:"import-locally-hosted-server",level:2}],l={toc:p},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"managing-servers"},"Managing Servers"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("p",null,"Cwtch groups are hosted by untrusted servers. If you want to see the servers you know about, their status, and the groups hosted on them:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On your contacts pane"),(0,o.kt)("li",{parentName:"ol"},"Got to the manage servers icon")),(0,o.kt)("h2",{id:"import-locally-hosted-server"},"Import locally hosted server"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"To import a locally hosted server click on select local server"),(0,o.kt)("li",{parentName:"ol"},"Select the server you want")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Manage.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/67152af3.b56258c2.js b/build-staging/assets/js/67152af3.b56258c2.js new file mode 100644 index 00000000..f86f7c18 --- /dev/null +++ b/build-staging/assets/js/67152af3.b56258c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2322],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),l=u(r),m=o,g=l["".concat(s,".").concat(m)]||l[m]||d[m]||a;return r?n.createElement(g,i(i({ref:t},c),{},{components:r})):n.createElement(g,i({ref:t},c))}));function g(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:o,i[1]=p;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:7},i="Editing a Group Name",p={unversionedId:"groups/edit-group-name",id:"groups/edit-group-name",title:"Editing a Group Name",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/edit-group-name.md",sourceDirName:"groups",slug:"/groups/edit-group-name",permalink:"/docs/groups/edit-group-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/edit-group-name.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"How to Leave a Group",permalink:"/docs/groups/leave-group"},next:{title:"Managing Servers",permalink:"/docs/groups/manage-known-servers"}},s={},u=[],c={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"editing-a-group-name"},"Editing a Group Name"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("p",null,"Group names are private to you, it will not be shared, it is your local name for the group."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On the chat pane go to settings"),(0,o.kt)("li",{parentName:"ol"},"Change the name of the group"),(0,o.kt)("li",{parentName:"ol"},"Press the save button"),(0,o.kt)("li",{parentName:"ol"},"Now your group has a new name")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/group_edit.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6875c492.3614e398.js b/build-staging/assets/js/6875c492.3614e398.js new file mode 100644 index 00000000..ed16af9e --- /dev/null +++ b/build-staging/assets/js/6875c492.3614e398.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8610],{9703:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(5999),r=a(2244);function s(e){const{metadata:t}=e,{previousPage:a,nextPage:s}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,l.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(r.Z,{permalink:a,title:n.createElement(l.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),s&&n.createElement(r.Z,{permalink:s,title:n.createElement(l.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(9460),r=a(1286);function s(e){let{items:t,component:a=r.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(l.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}},1714:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var n=a(7294),l=a(6010),r=a(5999),s=a(8824),o=a(1944),i=a(5281),g=a(9960),c=a(9058),m=a(9703),u=a(197),p=a(9985);function d(e){const t=function(){const{selectMessage:e}=(0,s.c)();return t=>e(t,(0,r.I)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,r.I)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function h(e){let{tag:t}=e;const a=d(t);return n.createElement(n.Fragment,null,n.createElement(o.d,{title:a}),n.createElement(u.Z,{tag:"blog_tags_posts"}))}function b(e){let{tag:t,items:a,sidebar:l,listMetadata:s}=e;const o=d(t);return n.createElement(c.Z,{sidebar:l},n.createElement("header",{className:"margin-bottom--xl"},n.createElement("h1",null,o),n.createElement(g.Z,{href:t.allTagsPath},n.createElement(r.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page"},"View All Tags"))),n.createElement(p.Z,{items:a}),n.createElement(m.Z,{metadata:s}))}function E(e){return n.createElement(o.FG,{className:(0,l.Z)(i.k.wrapper.blogPages,i.k.page.blogTagPostListPage)},n.createElement(h,e),n.createElement(b,e))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/693f9c9e.b37a5356.js b/build-staging/assets/js/693f9c9e.b37a5356.js new file mode 100644 index 00000000..3ff64076 --- /dev/null +++ b/build-staging/assets/js/693f9c9e.b37a5356.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6927],{7822:e=>{e.exports=JSON.parse('{"title":"Servers","slug":"/category/servers","permalink":"/docs/category/servers","navigation":{"previous":{"title":"Managing Servers","permalink":"/docs/groups/manage-known-servers"},"next":{"title":"Servers Introduction","permalink":"/docs/servers/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/697a71fd.731c5d0b.js b/build-staging/assets/js/697a71fd.731c5d0b.js new file mode 100644 index 00000000..eeb52699 --- /dev/null +++ b/build-staging/assets/js/697a71fd.731c5d0b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[712],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>d});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=n.createContext({}),l=function(e){var r=n.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},s=function(e){var r=l(e.components);return n.createElement(p.Provider,{value:r},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),f=l(t),m=o,d=f["".concat(p,".").concat(m)]||f[m]||u[m]||i;return t?n.createElement(d,a(a({ref:r},s),{},{components:t})):n.createElement(d,a({ref:r},s))}));function d(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=m;var c={};for(var p in r)hasOwnProperty.call(r,p)&&(c[p]=r[p]);c.originalType=e,c[f]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:4},a="Changing Your Profile Image",c={unversionedId:"profiles/change-profile-image",id:"profiles/change-profile-image",title:"Changing Your Profile Image",description:"This feature requires Experiments Enabled and",source:"@site/docs/profiles/change-profile-image.md",sourceDirName:"profiles",slug:"/profiles/change-profile-image",permalink:"/docs/profiles/change-profile-image",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-profile-image.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Changing Your Password",permalink:"/docs/profiles/change-password"},next:{title:"Unlocking Encrypted Profiles",permalink:"/docs/profiles/unlock-profile"}},p={},l=[],s={toc:l},f="wrapper";function u(e){let{components:r,...t}=e;return(0,o.kt)(f,(0,n.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"changing-your-profile-image"},"Changing Your Profile Image"),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nboth the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"File Sharing")," and ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," enabled.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Press the pencil next to the profile you want to edit"),(0,o.kt)("li",{parentName:"ol"},"Press on the pink pencil over your profile photo"),(0,o.kt)("li",{parentName:"ol"},"Select an image from your device"),(0,o.kt)("li",{parentName:"ol"},"Scroll down and click on save profile")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6a78f460.b63275b7.js b/build-staging/assets/js/6a78f460.b63275b7.js new file mode 100644 index 00000000..6759962e --- /dev/null +++ b/build-staging/assets/js/6a78f460.b63275b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[439],{3905:(t,e,a)=>{a.d(e,{Zo:()=>c,kt:()=>d});var i=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function o(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=i.createContext({}),p=function(t){var e=i.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},c=function(t){var e=p(t.components);return i.createElement(s.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},h=i.forwardRef((function(t,e){var a=t.components,r=t.mdxType,n=t.originalType,s=t.parentName,c=l(t,["components","mdxType","originalType","parentName"]),u=p(a),h=r,d=u["".concat(s,".").concat(h)]||u[h]||f[h]||n;return a?i.createElement(d,o(o({ref:e},c),{},{components:a})):i.createElement(d,o({ref:e},c))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var n=a.length,o=new Array(n);o[0]=h;var l={};for(var s in e)hasOwnProperty.call(e,s)&&(l[s]=e[s]);l.originalType=t,l[u]="string"==typeof t?t:r,o[1]=l;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>o,default:()=>f,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var i=a(7462),r=(a(7294),a(3905));const n={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"April 6, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/blog/cwtch-stable-roadmap-update"}},s={authorsImageUrls:[void 0]},p=[{value:"Availability Status",id:"availability-status",level:2},{value:"Profile Attributes",id:"profile-attributes",level:2},{value:"Downloading the Nightly",id:"downloading-the-nightly",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},u="wrapper";function f(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,i.Z)({},c,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,r.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,r.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,r.kt)("p",null,"The Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("h2",{id:"availability-status"},"Availability Status"),(0,r.kt)("p",null,'New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".'),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(4940).Z},(0,r.kt)("img",{src:a(1859).Z,width:"442",height:"233"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")),(0,r.kt)("h2",{id:"profile-attributes"},"Profile Attributes"),(0,r.kt)("p",null,"Also new is the ability to augment your profile with a few small pieces of ",(0,r.kt)("strong",{parentName:"p"},"public")," information."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(2243).Z},(0,r.kt)("img",{src:a(3506).Z,width:"730",height:"342"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information")),(0,r.kt)("h2",{id:"downloading-the-nightly"},"Downloading the Nightly"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly builds")," are available from our build server. Download links for ",(0,r.kt)("strong",{parentName:"p"},"2023-04-05-18-28-v1.11.0-7-g0290")," are available below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Windows: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Linux: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Mac: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Android: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"))),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}f.isMDXComponent=!0},2243:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},4940:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3506:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},1859:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6b72ab5e.f554649b.js b/build-staging/assets/js/6b72ab5e.f554649b.js new file mode 100644 index 00000000..6d5ef2e9 --- /dev/null +++ b/build-staging/assets/js/6b72ab5e.f554649b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8017],{2306:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/reproducible-builds","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/6d453d64.4bb55d29.js b/build-staging/assets/js/6d453d64.4bb55d29.js new file mode 100644 index 00000000..e72daeee --- /dev/null +++ b/build-staging/assets/js/6d453d64.4bb55d29.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9287],{794:a=>{a.exports=JSON.parse('{"label":"api","permalink":"/blog/tags/api","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/709d36d8.7ce37739.js b/build-staging/assets/js/709d36d8.7ce37739.js new file mode 100644 index 00000000..6fbefbb7 --- /dev/null +++ b/build-staging/assets/js/709d36d8.7ce37739.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[176],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=o,f=p["".concat(c,".").concat(h)]||p[h]||u[h]||a;return n?r.createElement(f,i(i({ref:t},d),{},{components:n})):r.createElement(f,i({ref:t},d))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={},i="Android Service",s={unversionedId:"components/ui/android",id:"components/ui/android",title:"Android Service",description:"Adapted from Integrating FFI processes with Android services",source:"@site/security/components/ui/android.md",sourceDirName:"components/ui",slug:"/components/ui/android",permalink:"/security/components/ui/android",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cwtch UI",permalink:"/security/category/cwtch-ui"},next:{title:"Image Previews",permalink:"/security/components/ui/image_previews"}},c={},l=[],d={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"android-service"},"Android Service"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/11-android-ffi-service-integration/"},"Adapted from: Discreet Log #11: Integrating FFI processes with Android services")),(0,o.kt)("p",null,"In addition to needing to make plain ol\u2019 method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isn\u2019t really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service."),(0,o.kt)("p",null,"The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, it\u2019s not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service."),(0,o.kt)("p",null,"If you\u2019d like to follow along, our WorkManager specifications are created in the handleCwtch() method of ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt"},"MainActivity.kt"),", and the workers themselves are defined in ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt"},"FlwtchWorker.kt"),"."),(0,o.kt)("p",null,"Our plain ol\u2019 method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback."),(0,o.kt)("p",null,"One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, it\u2019s easy for it to yield and resume as necessary while waiting for events to be generated. Cwtch\u2019s goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately."),(0,o.kt)("p",null,"FlwtchWorker\u2019s eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isn\u2019t running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontend\u2019s Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary."),(0,o.kt)("p",null,"Messages and other permanent state are stored on disk by the service, so the frontend doesn\u2019t need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state."),(0,o.kt)("p",null,"Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isn\u2019t the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'private fun getNativeLibDir(): String {\n val ainfo = this.applicationContext.packageManager.getApplicationInfo(\n "im.cwtch.flwtch", // Must be app name\n PackageManager.GET_SHARED_LIBRARY_FILES)\n return ainfo.nativeLibraryDir\n}\n')),(0,o.kt)("p",null,"\u2026then, whenever the app is launched, we cancel any jobs that aren\u2019t tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/7285d864.e6f36735.js b/build-staging/assets/js/7285d864.e6f36735.js new file mode 100644 index 00000000..aaffc4be --- /dev/null +++ b/build-staging/assets/js/7285d864.e6f36735.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3965],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>m});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function c(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var l=r.createContext({}),p=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):c(c({},e),t)),n},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},d="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},f=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,o=t.originalType,l=t.parentName,s=i(t,["components","mdxType","originalType","parentName"]),d=p(n),f=a,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||o;return n?r.createElement(m,c(c({ref:e},s),{},{components:n})):r.createElement(m,c({ref:e},s))}));function m(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var o=n.length,c=new Array(o);c[0]=f;var i={};for(var l in e)hasOwnProperty.call(e,l)&&(i[l]=e[l]);i.originalType=t,i[d]="string"==typeof t?t:a,c[1]=i;for(var p=2;p{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1.5},c="Starting a New Conversation",i={unversionedId:"chat/add-contact",id:"chat/add-contact",title:"Starting a New Conversation",description:"1. Select a Profile",source:"@site/docs/chat/add-contact.md",sourceDirName:"chat",slug:"/chat/add-contact",permalink:"/docs/chat/add-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/add-contact.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"An Introduction to Cwtch P2P Chat",permalink:"/docs/chat/introduction"},next:{title:"Accepting/Denying New Conversations",permalink:"/docs/chat/accept-deny-new-conversation"}},l={},p=[],s={toc:p},d="wrapper";function u(t){let{components:e,...n}=t;return(0,a.kt)(d,(0,r.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"starting-a-new-conversation"},"Starting a New Conversation"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Select a Profile"),(0,a.kt)("li",{parentName:"ol"},"Click on the Add button"),(0,a.kt)("li",{parentName:"ol"},"Chose 'Add Contact'"),(0,a.kt)("li",{parentName:"ol"},"Paste a Cwtch Address"),(0,a.kt)("li",{parentName:"ol"},"The contact will be added to your contacts list")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/76493ef6.26af640a.js b/build-staging/assets/js/76493ef6.26af640a.js new file mode 100644 index 00000000..6be1e647 --- /dev/null +++ b/build-staging/assets/js/76493ef6.26af640a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6033],{4438:s=>{s.exports=JSON.parse('{"title":"Platforms","slug":"/category/platforms","permalink":"/docs/category/platforms","navigation":{"previous":{"title":"Stickers","permalink":"/docs/contribute/stickers"},"next":{"title":"Running Cwtch on Tails","permalink":"/docs/platforms/tails"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/7650afbf.8584622c.js b/build-staging/assets/js/7650afbf.8584622c.js new file mode 100644 index 00000000..71793efc --- /dev/null +++ b/build-staging/assets/js/7650afbf.8584622c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1586],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),d=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=d(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),l=d(r),u=a,f=l["".concat(c,".").concat(u)]||l[u]||h[u]||o;return r?n.createElement(f,s(s({ref:t},p),{},{components:r})):n.createElement(f,s({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=u;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[l]="string"==typeof e?e:a,s[1]=i;for(var d=2;d{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:3},s="Sharing Cwtch Addresses",i={unversionedId:"chat/share-address-with-friends",id:"chat/share-address-with-friends",title:"Sharing Cwtch Addresses",description:"There are many ways to share a Cwtch address.",source:"@site/docs/chat/share-address-with-friends.md",sourceDirName:"chat",slug:"/chat/share-address-with-friends",permalink:"/docs/chat/share-address-with-friends",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-address-with-friends.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Accepting/Denying New Conversations",permalink:"/docs/chat/accept-deny-new-conversation"},next:{title:"Saving Conversation History",permalink:"/docs/chat/save-conversation-history"}},c={},d=[{value:"Sharing Your Cwtch Address",id:"sharing-your-cwtch-address",level:2}],p={toc:d},l="wrapper";function h(e){let{components:t,...r}=e;return(0,a.kt)(l,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"sharing-cwtch-addresses"},"Sharing Cwtch Addresses"),(0,a.kt)("p",null,"There are many ways to share a Cwtch address."),(0,a.kt)("h2",{id:"sharing-your-cwtch-address"},"Sharing Your Cwtch Address"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Go to your profile"),(0,a.kt)("li",{parentName:"ol"},"Click the copy address icon")),(0,a.kt)("p",null,"You can now share this address. People with this address will be able to add you as a Cwtch contact."),(0,a.kt)("p",null,"For information on blocking connections from people you don't know please see ",(0,a.kt)("a",{parentName:"p",href:"/docs/settings/behaviour/block-unknown-connections"},"Settings: Block Unknown Connections")," "),(0,a.kt)("h1",{id:"sharing-a-friends-cwtch-address"},"Sharing A Friends Cwtch Address"),(0,a.kt)("p",null,"Inside of Cwtch there is another mechanism for exchanging Cwtch addresses."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/76913e45.209f5656.js b/build-staging/assets/js/76913e45.209f5656.js new file mode 100644 index 00000000..45f415bf --- /dev/null +++ b/build-staging/assets/js/76913e45.209f5656.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9072],{6271:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/repliqate","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/7daa3c80.f196e6d6.js b/build-staging/assets/js/7daa3c80.f196e6d6.js new file mode 100644 index 00000000..2b5e2735 --- /dev/null +++ b/build-staging/assets/js/7daa3c80.f196e6d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1970],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},v=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),d=p(t),v=o,m=d["".concat(c,".").concat(v)]||d[v]||u[v]||i;return t?n.createElement(m,s(s({ref:r},l),{},{components:t})):n.createElement(m,s({ref:r},l))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=v;var a={};for(var c in r)hasOwnProperty.call(r,c)&&(a[c]=r[c]);a.originalType=e,a[d]="string"==typeof e?e:o,s[1]=a;for(var p=2;p{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:3},s="How to edit a server",a={unversionedId:"servers/edit-server",id:"servers/edit-server",title:"How to edit a server",description:"This feature requires Experiments Enabled and",source:"@site/docs/servers/edit-server.md",sourceDirName:"servers",slug:"/servers/edit-server",permalink:"/docs/servers/edit-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/edit-server.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"How to create a server",permalink:"/docs/servers/create-server"},next:{title:"How to delete server",permalink:"/docs/servers/delete-server"}},c={},p=[],l={toc:p},d="wrapper";function u(e){let{components:r,...t}=e;return(0,o.kt)(d,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-to-edit-a-server"},"How to edit a server"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," turned on.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to the server icon"),(0,o.kt)("li",{parentName:"ol"},"Select the server you want to edit"),(0,o.kt)("li",{parentName:"ol"},"Press the pencil icon"),(0,o.kt)("li",{parentName:"ol"},"Change the description/ or enable or disable the server"),(0,o.kt)("li",{parentName:"ol"},"Click on save server")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/server_edit.mp4"}))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/7df3f7bb.1bb99fc4.js b/build-staging/assets/js/7df3f7bb.1bb99fc4.js new file mode 100644 index 00000000..5505c717 --- /dev/null +++ b/build-staging/assets/js/7df3f7bb.1bb99fc4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5586],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=c(r),d=o,m=p["".concat(l,".").concat(d)]||p[d]||h[d]||i;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Developing Cwtch",a={unversionedId:"contribute/developing",id:"contribute/developing",title:"Developing Cwtch",description:"This section documents some ways to get started with Cwtch Development.",source:"@site/docs/contribute/developing.md",sourceDirName:"contribute",slug:"/contribute/developing",permalink:"/docs/contribute/developing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/developing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Contribute",permalink:"/docs/category/contribute"},next:{title:"Testing Cwtch",permalink:"/docs/contribute/testing"}},l={},c=[{value:"Cwtch Issues Tracking Process",id:"cwtch-issues-tracking-process",level:2},{value:"Cwtch Pull-Request Process",id:"cwtch-pull-request-process",level:2},{value:"Build Bot",id:"build-bot",level:3},{value:"Useful Resources",id:"useful-resources",level:2}],u={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"developing-cwtch"},"Developing Cwtch"),(0,o.kt)("p",null,"This section documents some ways to get started with Cwtch Development."),(0,o.kt)("h2",{id:"cwtch-issues-tracking-process"},"Cwtch Issues Tracking Process"),(0,o.kt)("p",null,"All Cwtch issues are tracked from the ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"cwtch-ui git repository"),", even if the bug/feature originates in an upstream library. This allows us to keep everything in one place."),(0,o.kt)("p",null,"Issues are generally divided into 4 distinct categories:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Unprocessed")," - These are new issues that have not been discussed by the Cwtch team."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=195&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Scheduled"))," - These issues have been planned for an upcoming release. They are usually tagged with the release they are expected to be fixed in e.g. ",(0,o.kt)("inlineCode",{parentName:"li"},"cwtch-1.11"),". A core Cwtch team member is likely working on the issue, or is expecting to work on the issue in the coming weeks."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=153&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Desired"))," - These are issues that we would like to fix but for some reason we are unable to schedule. This might be because the feature is large and requires a lot of effort, or because there is some blocker (e.g. a missing feature in Flutter or some other library) that prevents work on the feature. "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=136&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Help Wanted"))," - These are generally small issues that we would like to fix but that have been designated low priority. These are ideal first issues for volunteers. ")),(0,o.kt)("p",null,'If you would like to work on an open bug/feature, please comment on the issue and a member of the Cwtch team will follow up with advice on where to go from there. This helps us keep track of who is working on what problems, and reduces the amount of duplicate work. We aim to answer most queries within 24 hours, feel free to "bump" an issue if it takes longer than that.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)")),(0,o.kt)("h2",{id:"cwtch-pull-request-process"},"Cwtch Pull-Request Process"),(0,o.kt)("p",null,"All pull-requests must be reviewed and approved by a core Cwtch team member prior to merging. Sarah reviews all new and active pull requests multiple times a week. "),(0,o.kt)("h3",{id:"build-bot"},"Build Bot"),(0,o.kt)("p",null,"All Cwtch projects are set up with automated builds and testing. Every pull request is expected to be able to pass through these pipelines prior to being merged. If buildbot reports a failure then Sarah will work with you to determine the issue, and any necessary fixes."),(0,o.kt)("p",null,"Buildbot can fail for reasons beyond your control e.g. many of our integration tests rely setting up Tor connections, these can be brittle on occasion and result in timeouts and failures. Always confirm the root cause of a test failure before deciding what to do next."),(0,o.kt)("h2",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/components/ecosystem-overview"},"Cwtch Ecosystem Overview")," - a summary of active Cwtch repositories from the Cwtch Secure Development Handbook."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"Contributing Documentation")," - advice on contributing Cwtch documentation."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/testing"},"Contributing Testing")," - advice on contributing by testing Cwtch."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/translate"},"Contributing Translations")," - advice on contributing translations to Cwtch.")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"All contributions are ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/7dfbf03e.f0688a66.js b/build-staging/assets/js/7dfbf03e.f0688a66.js new file mode 100644 index 00000000..ca38aa0a --- /dev/null +++ b/build-staging/assets/js/7dfbf03e.f0688a66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1234],{6784:e=>{e.exports=JSON.parse('{"title":"Building a Cwtch App","slug":"/category/building-a-cwtch-app","permalink":"/developing/category/building-a-cwtch-app","navigation":{"previous":{"title":"Release and Packaging Process","permalink":"/developing/release"},"next":{"title":"Getting Started","permalink":"/developing/building-a-cwtch-app/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/814f3328.7742819b.js b/build-staging/assets/js/814f3328.7742819b.js new file mode 100644 index 00000000..85f56a81 --- /dev/null +++ b/build-staging/assets/js/814f3328.7742819b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2535],{5641:t=>{t.exports=JSON.parse('{"title":"Recent Logs","items":[{"title":"Cwtch Stable Roadmap Update","permalink":"/blog/cwtch-stable-roadmap-update-june"},{"title":"Cwtch Beta 1.12","permalink":"/blog/cwtch-nightly-1-12"},{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/blog/cwtch-nightly-v.11-74"},{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/blog/cwtch-developer-documentation"},{"title":"Availability Status and Profile Attributes","permalink":"/blog/availability-status-profile-attributes"},{"title":"Cwtch Stable Roadmap Update","permalink":"/blog/cwtch-stable-roadmap-update"},{"title":"Cwtch Beta 1.11","permalink":"/blog/cwtch-nightly-1-11"},{"title":"Updates to Cwtch Documentation","permalink":"/blog/cwtch-documentation"},{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/blog/autobindings-ii"},{"title":"Autogenerating Cwtch Bindings","permalink":"/blog/autobindings"},{"title":"Notes on Cwtch UI Testing (II)","permalink":"/blog/cwtch-testing-ii"},{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/blog/cwtch-android-reproducibility"},{"title":"Notes on Cwtch UI Testing","permalink":"/blog/cwtch-testing-i"},{"title":"Cwtch UI Platform Support","permalink":"/blog/cwtch-platform-support"},{"title":"Making Cwtch Bindings Reproducible","permalink":"/blog/cwtch-bindings-reproducible"},{"title":"Cwtch Stable API Design","permalink":"/blog/cwtch-stable-api-design"},{"title":"Path to Cwtch Stable","permalink":"/blog/path-to-cwtch-stable"}]}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/824a28c6.3dec41f3.js b/build-staging/assets/js/824a28c6.3dec41f3.js new file mode 100644 index 00000000..dd10a869 --- /dev/null +++ b/build-staging/assets/js/824a28c6.3dec41f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5905],{3905:(t,e,i)=>{i.d(e,{Zo:()=>s,kt:()=>b});var r=i(7294);function n(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function o(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,r)}return i}function a(t){for(var e=1;e=0||(n[i]=t[i]);return n}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,i)&&(n[i]=t[i])}return n}var l=r.createContext({}),p=function(t){var e=r.useContext(l),i=e;return t&&(i="function"==typeof t?t(e):a(a({},e),t)),i},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},h="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var i=t.components,n=t.mdxType,o=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),h=p(i),d=n,b=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return i?r.createElement(b,a(a({ref:e},s),{},{components:i})):r.createElement(b,a({ref:e},s))}));function b(t,e){var i=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var o=i.length,a=new Array(o);a[0]=d;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[h]="string"==typeof t?t:n,a[1]=c;for(var p=2;p{i.r(e),i.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=i(7462),n=(i(7294),i(3905));const o={sidebar_position:1},a="Getting Started",c={unversionedId:"building-a-cwtch-app/intro",id:"building-a-cwtch-app/intro",title:"Getting Started",description:"Choosing A Cwtch Library",source:"@site/developing/building-a-cwtch-app/intro.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/intro",permalink:"/developing/building-a-cwtch-app/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Building a Cwtch App",permalink:"/developing/category/building-a-cwtch-app"},next:{title:"Core Concepts",permalink:"/developing/building-a-cwtch-app/core-concepts"}},l={},p=[{value:"Choosing A Cwtch Library",id:"choosing-a-cwtch-library",level:2},{value:"Cwtch Go Lib",id:"cwtch-go-lib",level:3},{value:"CwtchBot",id:"cwtchbot",level:3},{value:"Autobindings (C-bindings)",id:"autobindings-c-bindings",level:3},{value:"libCwtch-rs (Rust)",id:"libcwtch-rs-rust",level:3}],s={toc:p},h="wrapper";function u(t){let{components:e,...i}=t;return(0,n.kt)(h,(0,r.Z)({},s,i,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"getting-started"},"Getting Started"),(0,n.kt)("h2",{id:"choosing-a-cwtch-library"},"Choosing A Cwtch Library"),(0,n.kt)("h3",{id:"cwtch-go-lib"},"Cwtch Go Lib"),(0,n.kt)("p",null,"The official Cwtch library is written in Go and can be found at ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"https://git.openprivacy.ca/cwtch.im/cwtch"),". This library allows access to all Cwtch functionality."),(0,n.kt)("h3",{id:"cwtchbot"},"CwtchBot"),(0,n.kt)("p",null,"We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot#using-cwtchbot-go"},"building an echobot tutorial"),"."),(0,n.kt)("h3",{id:"autobindings-c-bindings"},"Autobindings (C-bindings)"),(0,n.kt)("p",null,"The ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"official c-bindings for Cwtch")," are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI."),(0,n.kt)("h3",{id:"libcwtch-rs-rust"},"libCwtch-rs (Rust)"),(0,n.kt)("p",null,"An experimental rust-fied version of Cwtch Autobindings is available in ",(0,n.kt)("a",{parentName:"p",href:"https://crates.io/crates/libcwtch"},"libCwtch-rs"),". While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/83d480e9.493a1628.js b/build-staging/assets/js/83d480e9.493a1628.js new file mode 100644 index 00000000..80649548 --- /dev/null +++ b/build-staging/assets/js/83d480e9.493a1628.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[205],{3672:e=>{e.exports=JSON.parse('{"label":"release","permalink":"/blog/tags/release","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/840bb092.485f8fcf.js b/build-staging/assets/js/840bb092.485f8fcf.js new file mode 100644 index 00000000..9f260a60 --- /dev/null +++ b/build-staging/assets/js/840bb092.485f8fcf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8351],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>d});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),p=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},s=function(e){var r=p(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,d=u["".concat(l,".").concat(m)]||u[m]||f[m]||a;return t?n.createElement(d,i(i({ref:r},s),{},{components:t})):n.createElement(d,i({ref:r},s))}));function d(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var c={};for(var l in r)hasOwnProperty.call(r,l)&&(c[l]=r[l]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var p=2;p{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:2},i="Changing Your Display Name",c={unversionedId:"profiles/change-name",id:"profiles/change-name",title:"Changing Your Display Name",description:"1. On the Manage Profiles view, Press the pencil next to the profile you want to edit",source:"@site/docs/profiles/change-name.md",sourceDirName:"profiles",slug:"/profiles/change-name",permalink:"/docs/profiles/change-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-name.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Creating a New Profile",permalink:"/docs/profiles/create-a-profile"},next:{title:"Changing Your Password",permalink:"/docs/profiles/change-password"}},l={},p=[],s={toc:p},u="wrapper";function f(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"changing-your-display-name"},"Changing Your Display Name"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On the Manage Profiles view, Press the pencil next to the profile you want to edit"),(0,o.kt)("li",{parentName:"ol"},"Change your name"),(0,o.kt)("li",{parentName:"ol"},"Click save profile")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/89c52e74.28f84d12.js b/build-staging/assets/js/89c52e74.28f84d12.js new file mode 100644 index 00000000..8a86e08b --- /dev/null +++ b/build-staging/assets/js/89c52e74.28f84d12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8655],{3905:(t,e,a)=>{a.d(e,{Zo:()=>p,kt:()=>d});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function i(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function s(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var l=n.createContext({}),c=function(t){var e=n.useContext(l),a=e;return t&&(a="function"==typeof t?t(e):s(s({},e),t)),a},p=function(t){var e=c(t.components);return n.createElement(l.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},b=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,i=t.originalType,l=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),u=c(a),b=r,d=u["".concat(l,".").concat(b)]||u[b]||f[b]||i;return a?n.createElement(d,s(s({ref:e},p),{},{components:a})):n.createElement(d,s({ref:e},p))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var i=a.length,s=new Array(i);s[0]=b;var o={};for(var l in e)hasOwnProperty.call(e,l)&&(o[l]=e[l]);o.originalType=t,o[u]="string"==typeof t?t:r,s[1]=o;for(var c=2;c{a.r(e),a.d(e,{assets:()=>l,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const i={sidebar_position:14},s="Setting Availability Status",o={unversionedId:"profiles/availability-status",id:"profiles/availability-status",title:"Setting Availability Status",description:"New in Cwtch 1.12",source:"@site/docs/profiles/availability-status.md",sourceDirName:"profiles",slug:"/profiles/availability-status",permalink:"/docs/profiles/availability-status",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/availability-status.md",tags:[],version:"current",sidebarPosition:14,frontMatter:{sidebar_position:14},sidebar:"tutorialSidebar",previous:{title:"Importing a Profile",permalink:"/docs/profiles/importing-a-profile"},next:{title:"Setting Profile Attributes",permalink:"/docs/profiles/profile-info"}},l={},c=[],p={toc:c},u="wrapper";function f(t){let{components:e,...i}=t;return(0,r.kt)(u,(0,n.Z)({},p,i,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"setting-availability-status"},"Setting Availability Status"),(0,r.kt)("admonition",{title:"New Feature",type:"warning"},(0,r.kt)("p",{parentName:"admonition"},"New in ",(0,r.kt)("a",{parentName:"p",href:"/blog/cwtch-nightly-1-12"},"Cwtch 1.12")),(0,r.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,r.kt)("p",null,"On the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/category/conversations"},"conversations pane")," click the Status icon next to your profile picture."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(1476).Z},(0,r.kt)("img",{src:a(3163).Z,width:"444",height:"252"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"A drop-down menu will appear with various options e.g. Available, Away, and Busy"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(8791).Z},(0,r.kt)("img",{src:a(3891).Z,width:"443",height:"242"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"When you select Away or Busy as a status the border of your profile picture will change to reflect the status"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(4940).Z},(0,r.kt)("img",{src:a(1859).Z,width:"442",height:"233"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Contacts will see this change reflected in their conversations pane. "),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(8868).Z},(0,r.kt)("img",{src:a(6792).Z,width:"443",height:"223"}))),(0,r.kt)("figcaption",null)))}f.isMDXComponent=!0},8868:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},4940:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},8791:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},1476:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"},6792:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},1859:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3891:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},3163:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/89f86a37.e6d969cf.js b/build-staging/assets/js/89f86a37.e6d969cf.js new file mode 100644 index 00000000..034d057b --- /dev/null +++ b/build-staging/assets/js/89f86a37.e6d969cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9759],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>g});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function c(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),s=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),h=s(a),u=n,g=h["".concat(l,".").concat(u)]||h[u]||m[u]||o;return a?r.createElement(g,c(c({ref:t},p),{},{components:a})):r.createElement(g,c({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,c=new Array(o);c[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[h]="string"==typeof e?e:n,c[1]=i;for(var s=2;s{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},c=void 0,i={permalink:"/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"March 29, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"release",permalink:"/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/blog/cwtch-documentation"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function m(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})))}m.isMDXComponent=!0},6094:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/8eb4e46b.31c74b65.js b/build-staging/assets/js/8eb4e46b.31c74b65.js new file mode 100644 index 00000000..9032d10b --- /dev/null +++ b/build-staging/assets/js/8eb4e46b.31c74b65.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1],{2638:e=>{e.exports=JSON.parse('{"permalink":"/blog/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/blog","blogDescription":"The latest updated on Cwtch development.","blogTitle":"Development Log"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/8ec965fd.ad8c53ac.js b/build-staging/assets/js/8ec965fd.ad8c53ac.js new file mode 100644 index 00000000..aee5dec7 --- /dev/null +++ b/build-staging/assets/js/8ec965fd.ad8c53ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6471],{3905:(e,t,o)=>{o.d(t,{Zo:()=>p,kt:()=>h});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function i(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var c=n.createContext({}),l=function(e){var t=n.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(o),f=r,h=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return o?n.createElement(h,i(i({ref:t},p),{},{components:o})):n.createElement(h,i({ref:t},p))}));function h(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=o.length,i=new Array(a);i[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var l=2;l{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=o(7462),r=(o(7294),o(3905));const a={sidebar_position:5},i="Tor",s={unversionedId:"tor",id:"tor",title:"Tor",description:'Cwtch uses Tor to provide routing and connections. Using Tor hidden services to host profiles and on the fly generated "ephemeral" connections when making a connection provides strong anonymity guarantees to users of Cwtch.',source:"@site/docs/tor.md",sourceDirName:".",slug:"/tor",permalink:"/docs/tor",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/tor.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"QR Codes",permalink:"/docs/settings/experiments/qrcodes"},next:{title:"Contribute",permalink:"/docs/category/contribute"}},c={},l=[{value:"Tor Pane",id:"tor-pane",level:2},{value:"Reset Tor",id:"reset-tor",level:3},{value:"Cache Tor Consensus",id:"cache-tor-consensus",level:3},{value:"Advanced Tor Configuration",id:"advanced-tor-configuration",level:3}],p={toc:l},u="wrapper";function d(e){let{components:t,...a}=e;return(0,r.kt)(u,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"tor"},"Tor"),(0,r.kt)("p",null,"Cwtch uses ",(0,r.kt)("a",{parentName:"p",href:"https://www.torproject.org/"},"Tor"),' to provide routing and connections. Using Tor hidden services to host profiles and on the fly generated "ephemeral" connections when making a connection provides strong anonymity guarantees to users of Cwtch.'),(0,r.kt)("h2",{id:"tor-pane"},"Tor Pane"),(0,r.kt)("p",null,"Since we are adding an additional networking layer to Cwtch, we provide a pane to view Tor network status and make changes. To access it"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"From the profile list pane, click the Tor icon ",(0,r.kt)("img",{alt:"tor icon",src:o(4525).Z,width:"32",height:"32"})),(0,r.kt)("li",{parentName:"ol"},"View the tor network status")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"Tor Status: Online\nTor Version: 0.4.6.9\n")),(0,r.kt)("h3",{id:"reset-tor"},"Reset Tor"),(0,r.kt)("p",null,"The Tor network itself can occasionally have stale connections that aren't detected immediatly by it or Cwtch (we're always trying to improve this). Sometimes a user may find contacts or groups appearing offline they feel should be online. If you'd like to restart all the networking connections in Cwtch, we provide a mechanism to reboot tor from within the app. The ",(0,r.kt)("strong",{parentName:"p"},"reset")," button will reboot Tor from within the Cwtch app."),(0,r.kt)("h3",{id:"cache-tor-consensus"},"Cache Tor Consensus"),(0,r.kt)("p",null,"By default we start a fresh Tor process every time the app boots, and it requires downloading some Tor network state before it can start. This process is not instant. If you want to speed up Cwtch booting, you can enable Caching Tor Conensus to speed up future boots. If you run into a boot problem where the data is stale or corrupted and Cwtch is reporting it cannot boot Tor, disable this feature and ",(0,r.kt)("strong",{parentName:"p"},"reset")," tor again, and it should work."),(0,r.kt)("h3",{id:"advanced-tor-configuration"},"Advanced Tor Configuration"),(0,r.kt)("p",null,"We also offer the option to provide advance Tor configuration option in this section by allowing you to"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Specify a custom SOCKS port to connect to an existing Tor over"),(0,r.kt)("li",{parentName:"ul"},"Specify a custom Control port to connect to an existing Tor over"),(0,r.kt)("li",{parentName:"ul"},"and specify further options by entering custom ",(0,r.kt)("inlineCode",{parentName:"li"},"torrc")," options")))}d.isMDXComponent=!0},4525:(e,t,o)=>{o.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAATrwAAE68BY+aOwwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMUSURBVFiFvZZPiNVVFMc/Z546zkwzOikaxlSSFRklQVBQCEWmmRK1CYIWLabIReC6TdCiVtamlaUlQbhrkfTPiMxF0KoyhtISyjBpgkZszJnGT4vfefXT3u817zfvzYHHvffc8873+zv33HsO9EDUsfna9vUAfBcwlPMrFoWAukQN9WXgNNBQ9wPX/99/l3SDAHArsAMYBG4HXge2R8SXXfJfLeom9Xn1jHpY/UPd3HPgEoED6kn1N3VGfWAxwZeqU/4rzywaeBLYXALfV8dHrSRUHwRWAnek6gfg2Tq+6l7DCWAjcBz4DtgbEedq+qon6ls53p1HUCvzF/IQrcixcdm69wTU9aXlZI671UYr+66KujMfnKvUAXVY/SmP4aB6Za+AV6hvqq8l6Op8B1aqT5au46S6S41ugm9Uj6hbSroNOV6bhehzL5V3uxINdYv6abnGq2vV0Zzfk9Vwm/+Vr9SRhYDfpH7W/JL80lXq8lw3Mg+25t5UCxLvLITAh+rVOe9TB0t7oV6nrlMfyXw42oKA5aO7XCqvoboV+CIifs6EWhoR0yWTbRTNxwhwGHgIOFbhbnfHBICdQDN8/RFxIYkNqePAidQNAOeAMeD3Cl/3qcOdEtgETKj/2KjXAE8BByLieKq/pmi9+oDzFb76qWjP2hFoANNAIyL+zGN4HHilFI1RigjMAWeBdk3o2lbKduX4PEXJnQZmgXuBgxFhgq8GbgHOpJ854IY2/iZbKdtF4FvgLuBi3uWxiDhZ2n8UOAKsAn6haEarCtIscKJTAoeA8YiYocj0IXWotP9jRmMQWAasS7tW8lFETHVK4H3gRos6PwN8DzwGoC6jyHwSdD3wK3Bzha89VSCVBCJiDngaeBsYBk4BO9SRjMpoicAwRTIOtHD1RkR83DGBJHEUeA54jyLMe4E9FnV/TdMM2A7c2cLFofyIaox2m01R7wdeBT4AvgFuoziSCeAJ4GGKXGjKX8CLwAsRMTsfjPmQWK6Oq59k0bmgzuXPHI+pL3lpx9RWajUNaj9F1jfr/VngdJ3O+G/ZO0GaKrbieAAAAABJRU5ErkJggg=="}}]); \ No newline at end of file diff --git a/build-staging/assets/js/8fe7a387.3b916c07.js b/build-staging/assets/js/8fe7a387.3b916c07.js new file mode 100644 index 00000000..4cf88fef --- /dev/null +++ b/build-staging/assets/js/8fe7a387.3b916c07.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5233],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=i.createContext({}),s=function(e){var t=i.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=s(e.components);return i.createElement(p.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(n),h=a,g=d["".concat(p,".").concat(h)]||d[h]||m[h]||r;return n?i.createElement(g,o(o({ref:t},c),{},{components:n})):i.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=h;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[d]="string"==typeof e?e:a,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const r={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"March 3, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"autobindings",permalink:"/blog/tags/autobindings"},{label:"libcwtch",permalink:"/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/blog/autobindings"}},p={authorsImageUrls:[void 0]},s=[{value:"The Structure of an Application Experiment",id:"the-structure-of-an-application-experiment",level:2},{value:"New Required Management APIs",id:"new-required-management-apis",level:3},{value:"Adding Support for Application Experiments in the Spec File",id:"adding-support-for-application-experiments-in-the-spec-file",level:3},{value:"Generation-Time Inclusion",id:"generation-time-inclusion",level:3},{value:"Cwtch UI Integration",id:"cwtch-ui-integration",level:3},{value:"Nightlies & Next Steps",id:"nightlies--next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:s},d="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,i.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"the-structure-of-an-application-experiment"},"The Structure of an Application Experiment"),(0,a.kt)("p",null,"An application-level experiment consists of:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"A set of top-level APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DeleteServer")," - these are the APIs that we want to expose to calling applications."),(0,a.kt)("li",{parentName:"ol"},"An encapsulating structure for the set of APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ServersFunctionality")," - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity."),(0,a.kt)("li",{parentName:"ol"},"A global variable that exists at the top level of libCwtch, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"var serverExperiment *servers.ServersFunctionality servers")," - our single pointer to the underlying functionality."),(0,a.kt)("li",{parentName:"ol"},"A set of management-related APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"Init"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"UpdateSettings"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"OnACNEvent")," - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers)."),(0,a.kt)("li",{parentName:"ol"},"Management code within ",(0,a.kt)("inlineCode",{parentName:"li"},"_startCwtch")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"_reconnectCwtch")," that calls the management APIs on the global variable.")),(0,a.kt)("p",null,"From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on ",(0,a.kt)("inlineCode",{parentName:"p"},"application")," or a specific ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"."),(0,a.kt)("p",null,"Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template."),(0,a.kt)("h3",{id:"new-required-management-apis"},"New Required Management APIs"),(0,a.kt)("p",null,"To achieve this weaving, we now require application-level experiments to implement an ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandlerInterface")," interface and expose itself via an\ninitialize constructor ",(0,a.kt)("inlineCode",{parentName:"p"},"Init(acn, appDir) -> EventHandlerInterface"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"Enable(app, acn)"),"."),(0,a.kt)("p",null,"For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface."),(0,a.kt)("p",null,"We can then generate, and optionally include blocks of code like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," = .Init(&globalACN, appDir)\n eventHandler.AddModule()\n .Enable(application, &globalACN)\n")),(0,a.kt)("p",null,"and place them at specific points in the code. ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandler")," has also been extended to maintain a collection of ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," so that it can\npass on interesting events."),(0,a.kt)("h3",{id:"adding-support-for-application-experiments-in-the-spec-file"},"Adding Support for Application Experiments in the Spec File"),(0,a.kt)("p",null,"We have introduced a new ",(0,a.kt)("inlineCode",{parentName:"p"},"!")," operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option ",(0,a.kt)("inlineCode",{parentName:"p"},"exp")," which will call the function on the configured experiment, and ",(0,a.kt)("inlineCode",{parentName:"p"},"global")," to allow the setting up\nof a global functionality within the library."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},' # Server Hosting Experiment\n !serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"\n !serverExperiment global serverExperiment *servers.ServersFunctionality servers\n !serverExperiment exp CreateServer application password string:description bool:autostart\n !serverExperiment exp SetServerAttribute application string:handle string:key string:val\n !serverExperiment exp LoadServers application acn password\n !serverExperiment exp LaunchServers application acn\n !serverExperiment exp LaunchServer application string:handle\n !serverExperiment exp StopServer application string:handle\n !serverExperiment exp StopServers application\n !serverExperiment exp DestroyServers\n !serverExperiment exp DeleteServer application string:handle password\n')),(0,a.kt)("h3",{id:"generation-time-inclusion"},"Generation-Time Inclusion"),(0,a.kt)("p",null," Without any arguments provided ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," will not generate code for any experiments."),(0,a.kt)("p",null," In order to determine what experimental code to generate, ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," now interprets arguments as enabled compile time experiments, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings serverExperiment")," will turn on\ngeneration of server hosting code, per the spec file above."),(0,a.kt)("h3",{id:"cwtch-ui-integration"},"Cwtch UI Integration"),(0,a.kt)("p",null,"The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"c_LoadServers")," - if it doesn't then the UI is safe to assume the\nfeature is not available."),(0,a.kt)("figure",null,(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7365).Z,width:"1290",height:"754"})),(0,a.kt)("figcaption",null,"A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.")),(0,a.kt)("h2",{id:"nightlies--next-steps"},"Nightlies & Next Steps"),(0,a.kt)("p",null,"We are now publishing ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/"},"nightlies")," of autobinding derived libCwtch-go, along with ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2"},"Repliqate scripts")," for reproducibility."),(0,a.kt)("p",null,"With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11."),(0,a.kt)("p",null,"However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),".")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}m.isMDXComponent=!0},7365:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png"},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/917e8196.077d63dd.js b/build-staging/assets/js/917e8196.077d63dd.js new file mode 100644 index 00000000..208a7896 --- /dev/null +++ b/build-staging/assets/js/917e8196.077d63dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5497],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),l=p(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[l]="string"==typeof e?e:o,s[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:9},s="QR Codes",a={unversionedId:"settings/experiments/qrcodes",id:"settings/experiments/qrcodes",title:"QR Codes",description:"This documentation page is a stub. You can help",source:"@site/docs/settings/experiments/qrcodes.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/qrcodes",permalink:"/docs/settings/experiments/qrcodes",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/qrcodes.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{sidebar_position:9},sidebar:"tutorialSidebar",previous:{title:"Message Formatting",permalink:"/docs/settings/experiments/message-formatting"},next:{title:"Tor",permalink:"/docs/tor"}},c={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"qr-codes"},"QR Codes"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/935f2afb.cdf3516a.js b/build-staging/assets/js/935f2afb.cdf3516a.js new file mode 100644 index 00000000..31674822 --- /dev/null +++ b/build-staging/assets/js/935f2afb.cdf3516a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"What is Cwtch?","href":"/docs/intro","docId":"intro"},{"type":"category","label":"Getting started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Supported Platforms","href":"/docs/getting-started/supported_platforms","docId":"getting-started/supported_platforms"}],"href":"/docs/category/getting-started"},{"type":"category","label":"Profiles","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"An Introduction to Cwtch Profiles","href":"/docs/profiles/introduction","docId":"profiles/introduction"},{"type":"link","label":"Creating a New Profile","href":"/docs/profiles/create-a-profile","docId":"profiles/create-a-profile"},{"type":"link","label":"Changing Your Display Name","href":"/docs/profiles/change-name","docId":"profiles/change-name"},{"type":"link","label":"Changing Your Password","href":"/docs/profiles/change-password","docId":"profiles/change-password"},{"type":"link","label":"Changing Your Profile Image","href":"/docs/profiles/change-profile-image","docId":"profiles/change-profile-image"},{"type":"link","label":"Unlocking Encrypted Profiles","href":"/docs/profiles/unlock-profile","docId":"profiles/unlock-profile"},{"type":"link","label":"Deleting a Profile","href":"/docs/profiles/delete-profile","docId":"profiles/delete-profile"},{"type":"link","label":"Backup or Exporting a Profile","href":"/docs/profiles/exporting-profile","docId":"profiles/exporting-profile"},{"type":"link","label":"Importing a Profile","href":"/docs/profiles/importing-a-profile","docId":"profiles/importing-a-profile"},{"type":"link","label":"Setting Availability Status","href":"/docs/profiles/availability-status","docId":"profiles/availability-status"},{"type":"link","label":"Setting Profile Attributes","href":"/docs/profiles/profile-info","docId":"profiles/profile-info"}],"href":"/docs/category/profiles"},{"type":"category","label":"Conversations","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"An Introduction to Cwtch P2P Chat","href":"/docs/chat/introduction","docId":"chat/introduction"},{"type":"link","label":"Starting a New Conversation","href":"/docs/chat/add-contact","docId":"chat/add-contact"},{"type":"link","label":"Accepting/Denying New Conversations","href":"/docs/chat/accept-deny-new-conversation","docId":"chat/accept-deny-new-conversation"},{"type":"link","label":"Sharing Cwtch Addresses","href":"/docs/chat/share-address-with-friends","docId":"chat/share-address-with-friends"},{"type":"link","label":"Saving Conversation History","href":"/docs/chat/save-conversation-history","docId":"chat/save-conversation-history"},{"type":"link","label":"Message Formatting","href":"/docs/chat/message-formatting","docId":"chat/message-formatting"},{"type":"link","label":"Accessing Conversation Settings","href":"/docs/chat/conversation-settings","docId":"chat/conversation-settings"},{"type":"link","label":"Replying to a Message","href":"/docs/chat/reply-to-message","docId":"chat/reply-to-message"},{"type":"link","label":"Sharing a File","href":"/docs/chat/share-file","docId":"chat/share-file"},{"type":"link","label":"Blocking a Contact","href":"/docs/chat/block-contact","docId":"chat/block-contact"},{"type":"link","label":"Unblocking a Contact","href":"/docs/chat/unblock-contact","docId":"chat/unblock-contact"},{"type":"link","label":"Removing a Conversation","href":"/docs/chat/delete-contact","docId":"chat/delete-contact"}],"href":"/docs/category/conversations"},{"type":"category","label":"Groups","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"An Introduction to Cwtch Groups","href":"/docs/groups/introduction","docId":"groups/introduction"},{"type":"link","label":"Creating a New Group","href":"/docs/groups/create-group","docId":"groups/create-group"},{"type":"link","label":"Sending Invites to a Group","href":"/docs/groups/send-invite","docId":"groups/send-invite"},{"type":"link","label":"Accepting a Group Invite","href":"/docs/groups/accept-group-invite","docId":"groups/accept-group-invite"},{"type":"link","label":"How to Leave a Group","href":"/docs/groups/leave-group","docId":"groups/leave-group"},{"type":"link","label":"Editing a Group Name","href":"/docs/groups/edit-group-name","docId":"groups/edit-group-name"},{"type":"link","label":"Managing Servers","href":"/docs/groups/manage-known-servers","docId":"groups/manage-known-servers"}],"href":"/docs/category/groups"},{"type":"category","label":"Servers","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Servers Introduction","href":"/docs/servers/introduction","docId":"servers/introduction"},{"type":"link","label":"How to create a server","href":"/docs/servers/create-server","docId":"servers/create-server"},{"type":"link","label":"How to edit a server","href":"/docs/servers/edit-server","docId":"servers/edit-server"},{"type":"link","label":"How to delete server","href":"/docs/servers/delete-server","docId":"servers/delete-server"},{"type":"link","label":"How to share your Server Key Bundle","href":"/docs/servers/share-key","docId":"servers/share-key"},{"type":"link","label":"How to Unlock a server","href":"/docs/servers/unlock-server","docId":"servers/unlock-server"}],"href":"/docs/category/servers"},{"type":"category","label":"Settings","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"An Introduction to Cwtch App Settings","href":"/docs/settings/introduction","docId":"settings/introduction"},{"type":"category","label":"Appearance","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Change Language","href":"/docs/settings/appearance/change-language","docId":"settings/appearance/change-language"},{"type":"link","label":"Light/Dark and themes Breakdown","href":"/docs/settings/appearance/light-dark-mode","docId":"settings/appearance/light-dark-mode"},{"type":"link","label":"UI columns","href":"/docs/settings/appearance/ui-columns","docId":"settings/appearance/ui-columns"},{"type":"link","label":"Streamer/Presentation Mode","href":"/docs/settings/appearance/streamer-mode","docId":"settings/appearance/streamer-mode"}],"href":"/docs/category/appearance"},{"type":"category","label":"Behaviour","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Block Unknown Connections","href":"/docs/settings/behaviour/block-unknown-connections","docId":"settings/behaviour/block-unknown-connections"},{"type":"link","label":"Notification policy","href":"/docs/settings/behaviour/notification-policy","docId":"settings/behaviour/notification-policy"},{"type":"link","label":"Notification Content","href":"/docs/settings/behaviour/notification-content","docId":"settings/behaviour/notification-content"}],"href":"/docs/category/behaviour"},{"type":"category","label":"Experiments","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Groups Experiment","href":"/docs/settings/experiments/group-experiment","docId":"settings/experiments/group-experiment"},{"type":"link","label":"Server Hosting","href":"/docs/settings/experiments/server-hosting","docId":"settings/experiments/server-hosting"},{"type":"link","label":"File Sharing","href":"/docs/settings/experiments/file-sharing","docId":"settings/experiments/file-sharing"},{"type":"link","label":"Image Previews and Profile Pictures","href":"/docs/settings/experiments/image-previews-and-profile-pictures","docId":"settings/experiments/image-previews-and-profile-pictures"},{"type":"link","label":"Clickable Links Experiment","href":"/docs/settings/experiments/clickable-links","docId":"settings/experiments/clickable-links"},{"type":"link","label":"Message Formatting","href":"/docs/settings/experiments/message-formatting","docId":"settings/experiments/message-formatting"},{"type":"link","label":"QR Codes","href":"/docs/settings/experiments/qrcodes","docId":"settings/experiments/qrcodes"}],"href":"/docs/category/experiments"}],"href":"/docs/category/settings"},{"type":"link","label":"Tor","href":"/docs/tor","docId":"tor"},{"type":"category","label":"Contribute","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Developing Cwtch","href":"/docs/contribute/developing","docId":"contribute/developing"},{"type":"link","label":"Testing Cwtch","href":"/docs/contribute/testing","docId":"contribute/testing"},{"type":"link","label":"Translating Cwtch","href":"/docs/contribute/translate","docId":"contribute/translate"},{"type":"link","label":"Documentation Style Guide","href":"/docs/contribute/documentation","docId":"contribute/documentation"},{"type":"link","label":"Stickers","href":"/docs/contribute/stickers","docId":"contribute/stickers"}],"href":"/docs/category/contribute"},{"type":"category","label":"Platforms","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Running Cwtch on Tails","href":"/docs/platforms/tails","docId":"platforms/tails"}],"href":"/docs/category/platforms"}]},"docs":{"chat/accept-deny-new-conversation":{"id":"chat/accept-deny-new-conversation","title":"Accepting/Denying New Conversations","description":"1. Go to your profile","sidebar":"tutorialSidebar"},"chat/add-contact":{"id":"chat/add-contact","title":"Starting a New Conversation","description":"1. Select a Profile","sidebar":"tutorialSidebar"},"chat/block-contact":{"id":"chat/block-contact","title":"Blocking a Contact","description":"1. On a conversation window","sidebar":"tutorialSidebar"},"chat/conversation-settings":{"id":"chat/conversation-settings","title":"Accessing Conversation Settings","description":"In a conversation window, click on the Settings icon in the top bar.","sidebar":"tutorialSidebar"},"chat/delete-contact":{"id":"chat/delete-contact","title":"Removing a Conversation","description":"This feature will result in irreversible deletion. This cannot be undone.","sidebar":"tutorialSidebar"},"chat/introduction":{"id":"chat/introduction","title":"An Introduction to Cwtch P2P Chat","description":"Cwtch uses Tor v3 Onion Services to establish anonymous, peer-to-peer connections between Profiles.","sidebar":"tutorialSidebar"},"chat/message-formatting":{"id":"chat/message-formatting","title":"Message Formatting","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"chat/reply-to-message":{"id":"chat/reply-to-message","title":"Replying to a Message","description":"1. Select a message you want to reply to","sidebar":"tutorialSidebar"},"chat/save-conversation-history":{"id":"chat/save-conversation-history","title":"Saving Conversation History","description":"By default, for privacy, Cwtch does not preserve conversation history between sessions.","sidebar":"tutorialSidebar"},"chat/share-address-with-friends":{"id":"chat/share-address-with-friends","title":"Sharing Cwtch Addresses","description":"There are many ways to share a Cwtch address.","sidebar":"tutorialSidebar"},"chat/share-file":{"id":"chat/share-file","title":"Sharing a File","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"chat/unblock-contact":{"id":"chat/unblock-contact","title":"Unblocking a Contact","description":"1. Select the contact in your Conversation list. Blocked contacts are moved to the bottom of the list.","sidebar":"tutorialSidebar"},"contribute/developing":{"id":"contribute/developing","title":"Developing Cwtch","description":"This section documents some ways to get started with Cwtch Development.","sidebar":"tutorialSidebar"},"contribute/documentation":{"id":"contribute/documentation","title":"Documentation Style Guide","description":"This section documents the expected structure and quality of Cwtch documentation.","sidebar":"tutorialSidebar"},"contribute/stickers":{"id":"contribute/stickers","title":"Stickers","description":"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email erinn@openprivacy.ca with details and an address for us to mail stickers to.","sidebar":"tutorialSidebar"},"contribute/testing":{"id":"contribute/testing","title":"Testing Cwtch","description":"This section documents some ways to get started with Cwtch Testing.","sidebar":"tutorialSidebar"},"contribute/translate":{"id":"contribute/translate","title":"Translating Cwtch","description":"If you would like to contribute translations to Cwtch the application or this handbook here is how","sidebar":"tutorialSidebar"},"getting-started/supported_platforms":{"id":"getting-started/supported_platforms","title":"Supported Platforms","description":"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).","sidebar":"tutorialSidebar"},"groups/accept-group-invite":{"id":"groups/accept-group-invite","title":"Accepting a Group Invite","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"groups/create-group":{"id":"groups/create-group","title":"Creating a New Group","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"groups/edit-group-name":{"id":"groups/edit-group-name","title":"Editing a Group Name","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"groups/introduction":{"id":"groups/introduction","title":"An Introduction to Cwtch Groups","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"groups/leave-group":{"id":"groups/leave-group","title":"How to Leave a Group","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"groups/manage-known-servers":{"id":"groups/manage-known-servers","title":"Managing Servers","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"groups/send-invite":{"id":"groups/send-invite","title":"Sending Invites to a Group","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"What is Cwtch?","description":"Cwtch (/k\u028at\u0283/ - a Welsh word roughly translating to \u201ca hug that creates a safe place\u201d) is a decentralized, privacy-preserving, metadata resistant messaging app.","sidebar":"tutorialSidebar"},"platforms/tails":{"id":"platforms/tails","title":"Running Cwtch on Tails","description":"New in Cwtch 1.12","sidebar":"tutorialSidebar"},"profiles/availability-status":{"id":"profiles/availability-status","title":"Setting Availability Status","description":"New in Cwtch 1.12","sidebar":"tutorialSidebar"},"profiles/change-name":{"id":"profiles/change-name","title":"Changing Your Display Name","description":"1. On the Manage Profiles view, Press the pencil next to the profile you want to edit","sidebar":"tutorialSidebar"},"profiles/change-password":{"id":"profiles/change-password","title":"Changing Your Password","description":"1. Press the pencil next to the profile you want to edit","sidebar":"tutorialSidebar"},"profiles/change-profile-image":{"id":"profiles/change-profile-image","title":"Changing Your Profile Image","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"profiles/create-a-profile":{"id":"profiles/create-a-profile","title":"Creating a New Profile","description":"1. Press the + action button in the right bottom corner and select \\"New Profile\\"","sidebar":"tutorialSidebar"},"profiles/delete-profile":{"id":"profiles/delete-profile","title":"Deleting a Profile","description":"This feature will result in irreversible deletion of key material. This cannot be undone.","sidebar":"tutorialSidebar"},"profiles/exporting-profile":{"id":"profiles/exporting-profile","title":"Backup or Exporting a Profile","description":"On the Profile Management Screen:","sidebar":"tutorialSidebar"},"profiles/importing-a-profile":{"id":"profiles/importing-a-profile","title":"Importing a Profile","description":"1. Press the + action button in the right bottom corner and select \\"Import Profile\\"","sidebar":"tutorialSidebar"},"profiles/introduction":{"id":"profiles/introduction","title":"An Introduction to Cwtch Profiles","description":"With Cwtch you can create one of more Profiles. Each profile generates a random ed25519 key pair compatible with","sidebar":"tutorialSidebar"},"profiles/profile-info":{"id":"profiles/profile-info","title":"Setting Profile Attributes","description":"New in Cwtch 1.12","sidebar":"tutorialSidebar"},"profiles/unlock-profile":{"id":"profiles/unlock-profile","title":"Unlocking Encrypted Profiles","description":"When you restart Cwtch, if you used a password to protect your profile, it will not be loaded by default, and you will need to unlock it.","sidebar":"tutorialSidebar"},"servers/create-server":{"id":"servers/create-server","title":"How to create a server","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"servers/delete-server":{"id":"servers/delete-server","title":"How to delete server","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"servers/edit-server":{"id":"servers/edit-server","title":"How to edit a server","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"servers/introduction":{"id":"servers/introduction","title":"Servers Introduction","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"servers/share-key":{"id":"servers/share-key","title":"How to share your Server Key Bundle","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"servers/unlock-server":{"id":"servers/unlock-server","title":"How to Unlock a server","description":"This feature requires Experiments Enabled and","sidebar":"tutorialSidebar"},"settings/appearance/change-language":{"id":"settings/appearance/change-language","title":"Change Language","description":"Thanks to the help of volunteers, the Cwtch app has been translated to many languages.","sidebar":"tutorialSidebar"},"settings/appearance/light-dark-mode":{"id":"settings/appearance/light-dark-mode","title":"Light/Dark and themes Breakdown","description":"1. Press the setting icon","sidebar":"tutorialSidebar"},"settings/appearance/streamer-mode":{"id":"settings/appearance/streamer-mode","title":"Streamer/Presentation Mode","description":"Streamer/Presentation mode makes the app more visually private. In this mode, Cwtch will not display","sidebar":"tutorialSidebar"},"settings/appearance/ui-columns":{"id":"settings/appearance/ui-columns","title":"UI columns","description":"1. Press the settings icon","sidebar":"tutorialSidebar"},"settings/behaviour/block-unknown-connections":{"id":"settings/behaviour/block-unknown-connections","title":"Block Unknown Connections","description":"By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. You can change this behaviour through the Block Unknown Connections","sidebar":"tutorialSidebar"},"settings/behaviour/notification-content":{"id":"settings/behaviour/notification-content","title":"Notification Content","description":"1. Go to settings","sidebar":"tutorialSidebar"},"settings/behaviour/notification-policy":{"id":"settings/behaviour/notification-policy","title":"Notification policy","description":"1. Go to settings","sidebar":"tutorialSidebar"},"settings/experiments/clickable-links":{"id":"settings/experiments/clickable-links","title":"Clickable Links Experiment","description":"This feature, if enabled, presents a deanonymization risk.","sidebar":"tutorialSidebar"},"settings/experiments/file-sharing":{"id":"settings/experiments/file-sharing","title":"File Sharing","description":"These setting enables Cwtch filesharing functionality. This reveals the \\"Share File\\" option in the conversation pane, and allows you to download files from conversations.","sidebar":"tutorialSidebar"},"settings/experiments/group-experiment":{"id":"settings/experiments/group-experiment","title":"Groups Experiment","description":"Enables Cwtch to connect to untrusted servers and use them to host private, asynchronous, groups.","sidebar":"tutorialSidebar"},"settings/experiments/image-previews-and-profile-pictures":{"id":"settings/experiments/image-previews-and-profile-pictures","title":"Image Previews and Profile Pictures","description":"This experiment requires the File Sharing experiment enabled.","sidebar":"tutorialSidebar"},"settings/experiments/message-formatting":{"id":"settings/experiments/message-formatting","title":"Message Formatting","description":"When enabled, this experiment changes the conversation compose box to add message formatting UX.","sidebar":"tutorialSidebar"},"settings/experiments/qrcodes":{"id":"settings/experiments/qrcodes","title":"QR Codes","description":"This documentation page is a stub. You can help","sidebar":"tutorialSidebar"},"settings/experiments/server-hosting":{"id":"settings/experiments/server-hosting","title":"Server Hosting","description":"Server hosting is currently an experimental feature in Cwtch, it is not enabled by default.","sidebar":"tutorialSidebar"},"settings/introduction":{"id":"settings/introduction","title":"An Introduction to Cwtch App Settings","description":"Appearance","sidebar":"tutorialSidebar"},"tor":{"id":"tor","title":"Tor","description":"Cwtch uses Tor to provide routing and connections. Using Tor hidden services to host profiles and on the fly generated \\"ephemeral\\" connections when making a connection provides strong anonymity guarantees to users of Cwtch.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/947e3a34.7609aa54.js b/build-staging/assets/js/947e3a34.7609aa54.js new file mode 100644 index 00000000..7070146e --- /dev/null +++ b/build-staging/assets/js/947e3a34.7609aa54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7875],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,d=u["".concat(c,".").concat(m)]||u[m]||h[m]||i;return n?r.createElement(d,a(a({ref:t},l),{},{components:n})):r.createElement(d,a({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},a="Connectivity",s={unversionedId:"components/connectivity/intro",id:"components/connectivity/intro",title:"Connectivity",description:"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.",source:"@site/security/components/connectivity/intro.md",sourceDirName:"components/connectivity",slug:"/components/connectivity/intro",permalink:"/security/components/connectivity/intro",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Connectivity & Tor",permalink:"/security/category/connectivity--tor"},next:{title:"Tapir",permalink:"/security/category/tapir"}},c={},p=[{value:"Known Risks",id:"known-risks",level:2},{value:"Private Key Exposure to the Tor Process",id:"private-key-exposure-to-the-tor-process",level:3},{value:"Mitigations",id:"mitigations",level:3},{value:"Tor Process Management",id:"tor-process-management",level:3},{value:"Testing Status",id:"testing-status",level:2}],l={toc:p},u="wrapper";function h(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"connectivity"},"Connectivity"),(0,o.kt)("p",null,"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication."),(0,o.kt)("p",null,"We provide the ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity"),"\npackage for managing the Tor daemon and setting up and tearing down onion\nservices through Tor."),(0,o.kt)("h2",{id:"known-risks"},"Known Risks"),(0,o.kt)("h3",{id:"private-key-exposure-to-the-tor-process"},"Private Key Exposure to the Tor Process"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (Requires Physical Access or Privilege Escalation to\nexploit)"),(0,o.kt)("p",null,"We must pass the private key of any onion service we wish to set up to the\nconnectivity library, through the ",(0,o.kt)("inlineCode",{parentName:"p"},"Listen")," interface (and thus to the Tor\nprocess). This is one of the most critical areas that is outside of our\ncontrol. Any binding to a rouge tor process or binary will result in\ncompromise of the Onion private key."),(0,o.kt)("h3",{id:"mitigations"},"Mitigations"),(0,o.kt)("p",null,"Connectivity attempt to bind to the system-provided Tor process as the default,\n",(0,o.kt)("em",{parentName:"p"},"only")," when it has been provided with an authentication token."),(0,o.kt)("p",null,"Otherwise connectivity always attempts to deploy its own Tor process\nusing a known\ngood binary packaged with the system (outside of the scope of the connectivity\npackage)"),(0,o.kt)("p",null,"In the long term we hope an integrated library will become available and allow\ndirect management through an in-process interface to prevent the private key\nfrom leaving the process boundary (or other alternative paths that allow us\nto maintain full control over the private key in-memory.)"),(0,o.kt)("h3",{id:"tor-process-management"},"Tor Process Management"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (Requires Physical Access or Privilege\nEscalation to exploit)"),(0,o.kt)("p",null,"Many issues can arise from the management of a separate process, including the\nneed to restart, exit and otherwise ensure appropriate management."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity/src/branch/master/acn.go"},"ACN"),"\ninterface provides ",(0,o.kt)("inlineCode",{parentName:"p"},"Restart"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Close")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetBootstrapStatus")," interfaces to\nallow applications to manage the underlying Tor process. In addition the ",(0,o.kt)("inlineCode",{parentName:"p"},"SetStatusCallback"),"\nmethod can be used to allow an application to be notified when the status of\nthe Tor process changes."),(0,o.kt)("p",null,"However, if sufficiently-privileged users wish they can interfere with this\nmechanism, and as such the Tor process is a more brittle component\ninteraction than others."),(0,o.kt)("h2",{id:"testing-status"},"Testing Status"),(0,o.kt)("p",null,"Current connectivity has limited unit testing capabilities and none of these\nare run during pull requests or merges. There is no integration testing."),(0,o.kt)("p",null,"It is worth noting that connectivity is used by both Tapir and Cwtch in their\nintegration tests (and so despite the lack of package level testing, it is\nexposed to system-wide test conditions)"))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/975564ee.8216ecd4.js b/build-staging/assets/js/975564ee.8216ecd4.js new file mode 100644 index 00000000..930f9ca2 --- /dev/null +++ b/build-staging/assets/js/975564ee.8216ecd4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8389],{3905:(t,e,n)=>{n.d(e,{Zo:()=>u,kt:()=>f});var r=n(7294);function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function i(t){for(var e=1;e=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}var s=r.createContext({}),p=function(t){var e=r.useContext(s),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},u=function(t){var e=p(t.components);return r.createElement(s.Provider,{value:e},t.children)},l="mdxType",h={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var n=t.components,o=t.mdxType,a=t.originalType,s=t.parentName,u=c(t,["components","mdxType","originalType","parentName"]),l=p(n),d=o,f=l["".concat(s,".").concat(d)]||l[d]||h[d]||a;return n?r.createElement(f,i(i({ref:e},u),{},{components:n})):r.createElement(f,i({ref:e},u))}));function f(t,e){var n=arguments,o=e&&e.mdxType;if("string"==typeof t||o){var a=n.length,i=new Array(a);i[0]=d;var c={};for(var s in e)hasOwnProperty.call(e,s)&&(c[s]=e[s]);c.originalType=t,c[l]="string"==typeof t?t:o,i[1]=c;for(var p=2;p{n.r(e),n.d(e,{assets:()=>s,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:1},i="An Introduction to Cwtch P2P Chat",c={unversionedId:"chat/introduction",id:"chat/introduction",title:"An Introduction to Cwtch P2P Chat",description:"Cwtch uses Tor v3 Onion Services to establish anonymous, peer-to-peer connections between Profiles.",source:"@site/docs/chat/introduction.md",sourceDirName:"chat",slug:"/chat/introduction",permalink:"/docs/chat/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Conversations",permalink:"/docs/category/conversations"},next:{title:"Starting a New Conversation",permalink:"/docs/chat/add-contact"}},s={},p=[{value:"How P2P Chat Works Under the Hood",id:"how-p2p-chat-works-under-the-hood",level:2}],u={toc:p},l="wrapper";function h(t){let{components:e,...n}=t;return(0,o.kt)(l,(0,r.Z)({},u,n,{components:e,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"an-introduction-to-cwtch-p2p-chat"},"An Introduction to Cwtch P2P Chat"),(0,o.kt)("p",null,"Cwtch uses Tor v3 Onion Services to establish anonymous, peer-to-peer connections between Profiles."),(0,o.kt)("h2",{id:"how-p2p-chat-works-under-the-hood"},"How P2P Chat Works Under the Hood"),(0,o.kt)("p",null,"In order to chat with your friends in a peer-to-peer conversation both must be online."),(0,o.kt)("p",null,"After a successful connection both parties engage in an ",(0,o.kt)("strong",{parentName:"p"},"authentication protocol")," which:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Asserts that each party has access to the private key associated with their public identity."),(0,o.kt)("li",{parentName:"ul"},"Generates an ephemeral session key used to encrypt all further communication during the session.")),(0,o.kt)("p",null,"This exchange (documented in further detail in ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/authentication_protocol.html"},"authentication protocol"),") is ",(0,o.kt)("em",{parentName:"p"},"offline deniable"),"\ni.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the\nfact - it is impossible to definitely prove that the exchange happened at all."),(0,o.kt)("p",null,"Once the authentication process is successful then both you and your friend can communicate away assured that no one else\ncan learn anything about the contents or the metadata of your conversation."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9785.e0c467d7.js b/build-staging/assets/js/9785.e0c467d7.js new file mode 100644 index 00000000..b1c5c624 --- /dev/null +++ b/build-staging/assets/js/9785.e0c467d7.js @@ -0,0 +1 @@ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9785],{3905:(e,t,n)=>{"use strict";n.d(t,{Zo:()=>u,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),s=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return o.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=s(n),p=a,f=m["".concat(i,".").concat(p)]||m[p]||d[p]||r;return n?o.createElement(f,c(c({ref:t},u),{},{components:n})):o.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,c=new Array(r);c[0]=p;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[m]="string"==typeof e?e:a,c[1]=l;for(var s=2;s{"use strict";n.d(t,{Z:()=>u});var o=n(7294),a=n(5999),r=n(5281),c=n(7462),l=n(6010);const i={iconEdit:"iconEdit_Z9Sw"};function s(e){let{className:t,...n}=e;return o.createElement("svg",(0,c.Z)({fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,l.Z)(i.iconEdit,t),"aria-hidden":"true"},n),o.createElement("g",null,o.createElement("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})))}function u(e){let{editUrl:t}=e;return o.createElement("a",{href:t,target:"_blank",rel:"noreferrer noopener",className:r.k.common.editThisPage},o.createElement(s,null),o.createElement(a.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page"},"Edit this page"))}},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var o=n(7462),a=n(7294),r=n(6010),c=n(5999),l=n(6668),i=n(9960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function u(e){let{as:t,id:n,...u}=e;const{navbar:{hideOnScroll:m}}=(0,l.L)();if("h1"===t||!n)return a.createElement(t,(0,o.Z)({},u,{id:void 0}));const d=(0,c.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return a.createElement(t,(0,o.Z)({},u,{className:(0,r.Z)("anchor",m?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n}),u.children,a.createElement(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d},"\u200b"))}},1506:(e,t,n)=>{"use strict";n.d(t,{Z:()=>he});var o=n(7294),a=n(3905),r=n(7462),c=n(5742);var l=n(2389),i=n(6010),s=n(2949),u=n(6668);function m(){const{prism:e}=(0,u.L)(),{colorMode:t}=(0,s.I)(),n=e.theme,o=e.darkTheme||n;return"dark"===t?o:n}var d=n(5281),p=n(7594),f=n.n(p);const g=/title=(?["'])(?.*?)\1/,h=/\{(?<range>[\d,-]+)\}/,y={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function b(e,t){const n=e.map((e=>{const{start:n,end:o}=y[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${o})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:o,magicComments:a,metastring:r}=t;if(r&&h.test(r)){const e=r.match(h).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${r}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,o=f()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(o),code:n}}if(void 0===o)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);default:return b(Object.keys(y),t)}}(o,a),l=n.split("\n"),i=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),s=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let p=0;p<l.length;){const e=l[p].match(c);if(!e){p+=1;continue}const t=e.slice(1).find((e=>void 0!==e));s[t]?i[s[t]].range+=`${p},`:u[t]?i[u[t]].start=p:m[t]&&(i[m[t]].range+=`${i[m[t]].start}-${p-1},`),l.splice(p,1)}n=l.join("\n");const d={};return Object.entries(i).forEach((e=>{let[t,{range:n}]=e;f()(n).forEach((e=>{d[e]??=[],d[e].push(t)}))})),{lineClassNames:d,code:n}}const E={codeBlockContainer:"codeBlockContainer_Ckt0"};function k(e){let{as:t,...n}=e;const a=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[o,a]=e;const r=t[o];r&&"string"==typeof a&&(n[r]=a)})),n}(m());return o.createElement(t,(0,r.Z)({},n,{style:a,className:(0,i.Z)(n.className,E.codeBlockContainer,d.k.common.codeBlock)}))}const N={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function C(e){let{children:t,className:n}=e;return o.createElement(k,{as:"pre",tabIndex:0,className:(0,i.Z)(N.codeBlockStandalone,"thin-scrollbar",n)},o.createElement("code",{className:N.codeBlockLines},t))}var w=n(902);const B={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Z(e,t){const[n,a]=(0,o.useState)(),r=(0,o.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,o.useEffect)((()=>{r()}),[r]),function(e,t,n){void 0===n&&(n=B);const a=(0,w.zX)(t),r=(0,w.Ql)(n);(0,o.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,r),()=>t.disconnect()}),[e,a,r])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),r())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}const T={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]};var L={Prism:n(7410).Z,theme:T};function j(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _(){return _=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},_.apply(this,arguments)}var x=/\r\n|\r|\n/,O=function(e){0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},S=function(e,t){var n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)};function P(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&-1===t.indexOf(o)&&(n[o]=e[o]);return n}var z=function(e){function t(){for(var t=this,n=[],o=arguments.length;o--;)n[o]=arguments[o];e.apply(this,n),j(this,"getThemeDict",(function(e){if(void 0!==t.themeDict&&e.theme===t.prevTheme&&e.language===t.prevLanguage)return t.themeDict;t.prevTheme=e.theme,t.prevLanguage=e.language;var n=e.theme?function(e,t){var n=e.plain,o=Object.create(null),a=e.styles.reduce((function(e,n){var o=n.languages,a=n.style;return o&&!o.includes(t)||n.types.forEach((function(t){var n=_({},e[t],a);e[t]=n})),e}),o);return a.root=n,a.plain=_({},n,{backgroundColor:null}),a}(e.theme,e.language):void 0;return t.themeDict=n})),j(this,"getLineProps",(function(e){var n=e.key,o=e.className,a=e.style,r=_({},P(e,["key","className","style","line"]),{className:"token-line",style:void 0,key:void 0}),c=t.getThemeDict(t.props);return void 0!==c&&(r.style=c.plain),void 0!==a&&(r.style=void 0!==r.style?_({},r.style,a):a),void 0!==n&&(r.key=n),o&&(r.className+=" "+o),r})),j(this,"getStyleForToken",(function(e){var n=e.types,o=e.empty,a=n.length,r=t.getThemeDict(t.props);if(void 0!==r){if(1===a&&"plain"===n[0])return o?{display:"inline-block"}:void 0;if(1===a&&!o)return r[n[0]];var c=o?{display:"inline-block"}:{},l=n.map((function(e){return r[e]}));return Object.assign.apply(Object,[c].concat(l))}})),j(this,"getTokenProps",(function(e){var n=e.key,o=e.className,a=e.style,r=e.token,c=_({},P(e,["key","className","style","token"]),{className:"token "+r.types.join(" "),children:r.content,style:t.getStyleForToken(r),key:void 0});return void 0!==a&&(c.style=void 0!==c.style?_({},c.style,a):a),void 0!==n&&(c.key=n),o&&(c.className+=" "+o),c})),j(this,"tokenize",(function(e,t,n,o){var a={code:t,grammar:n,language:o,tokens:[]};e.hooks.run("before-tokenize",a);var r=a.tokens=e.tokenize(a.code,a.grammar,a.language);return e.hooks.run("after-tokenize",a),r}))}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.render=function(){var e=this.props,t=e.Prism,n=e.language,o=e.code,a=e.children,r=this.getThemeDict(this.props),c=t.languages[n];return a({tokens:function(e){for(var t=[[]],n=[e],o=[0],a=[e.length],r=0,c=0,l=[],i=[l];c>-1;){for(;(r=o[c]++)<a[c];){var s=void 0,u=t[c],m=n[c][r];if("string"==typeof m?(u=c>0?u:["plain"],s=m):(u=S(u,m.type),m.alias&&(u=S(u,m.alias)),s=m.content),"string"==typeof s){var d=s.split(x),p=d.length;l.push({types:u,content:d[0]});for(var f=1;f<p;f++)O(l),i.push(l=[]),l.push({types:u,content:d[f]})}else c++,t.push(u),n.push(s),o.push(0),a.push(s.length)}c--,t.pop(),n.pop(),o.pop(),a.pop()}return O(l),i}(void 0!==c?this.tokenize(t,o,c,n):[o]),className:"prism-code language-"+n,style:void 0!==r?r.root:{},getLineProps:this.getLineProps,getTokenProps:this.getTokenProps})},t}(o.Component);const A=z,I={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function W(e){let{line:t,classNames:n,showLineNumbers:a,getLineProps:c,getTokenProps:l}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const s=c({line:t,className:(0,i.Z)(n,a&&I.codeLine)}),u=t.map(((e,t)=>o.createElement("span",(0,r.Z)({key:t},l({token:e,key:t})))));return o.createElement("span",s,a?o.createElement(o.Fragment,null,o.createElement("span",{className:I.codeLineNumber}),o.createElement("span",{className:I.codeLineContent},u)):u,o.createElement("br",null))}var M=n(5999);function H(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"}))}function D(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))}const V={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function R(e){let{code:t,className:n}=e;const[a,r]=(0,o.useState)(!1),c=(0,o.useRef)(void 0),l=(0,o.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const o=document.createElement("textarea"),a=document.activeElement;o.value=e,o.setAttribute("readonly",""),o.style.contain="strict",o.style.position="absolute",o.style.left="-9999px",o.style.fontSize="12pt";const r=document.getSelection(),c=r.rangeCount>0&&r.getRangeAt(0);n.append(o),o.select(),o.selectionStart=0,o.selectionEnd=e.length;let l=!1;try{l=document.execCommand("copy")}catch{}o.remove(),c&&(r.removeAllRanges(),r.addRange(c)),a&&a.focus()}(t),r(!0),c.current=window.setTimeout((()=>{r(!1)}),1e3)}),[t]);return(0,o.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),o.createElement("button",{type:"button","aria-label":a?(0,M.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,M.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,M.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.Z)("clean-btn",n,V.copyButton,a&&V.copyButtonCopied),onClick:l},o.createElement("span",{className:V.copyButtonIcons,"aria-hidden":"true"},o.createElement(H,{className:V.copyButtonIcon}),o.createElement(D,{className:V.copyButtonSuccessIcon})))}function $(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"}))}const F={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function q(e){let{className:t,onClick:n,isEnabled:a}=e;const r=(0,M.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return o.createElement("button",{type:"button",onClick:n,className:(0,i.Z)("clean-btn",t,a&&F.wordWrapButtonEnabled),"aria-label":r,title:r},o.createElement($,{className:F.wordWrapButtonIcon,"aria-hidden":"true"}))}function G(e){let{children:t,className:n="",metastring:a,title:c,showLineNumbers:l,language:s}=e;const{prism:{defaultLanguage:d,magicComments:p}}=(0,u.L)(),f=s??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??d,h=m(),y=function(){const[e,t]=(0,o.useState)(!1),[n,a]=(0,o.useState)(!1),r=(0,o.useRef)(null),c=(0,o.useCallback)((()=>{const n=r.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[r,e]),l=(0,o.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=r.current,n=e>t||r.current.querySelector("code").hasAttribute("style");a(n)}),[r]);return Z(r,l),(0,o.useEffect)((()=>{l()}),[e,l]),(0,o.useEffect)((()=>(window.addEventListener("resize",l,{passive:!0}),()=>{window.removeEventListener("resize",l)})),[l]),{codeBlockRef:r,isEnabled:e,isCodeScrollable:n,toggle:c}}(),b=function(e){return e?.match(g)?.groups.title??""}(a)||c,{lineClassNames:E,code:C}=v(t,{metastring:a,language:f,magicComments:p}),w=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return o.createElement(k,{as:"div",className:(0,i.Z)(n,f&&!n.includes(`language-${f}`)&&`language-${f}`)},b&&o.createElement("div",{className:N.codeBlockTitle},b),o.createElement("div",{className:N.codeBlockContent},o.createElement(A,(0,r.Z)({},L,{theme:h,code:C,language:f??"text"}),(e=>{let{className:t,tokens:n,getLineProps:a,getTokenProps:r}=e;return o.createElement("pre",{tabIndex:0,ref:y.codeBlockRef,className:(0,i.Z)(t,N.codeBlock,"thin-scrollbar")},o.createElement("code",{className:(0,i.Z)(N.codeBlockLines,w&&N.codeBlockLinesWithNumbering)},n.map(((e,t)=>o.createElement(W,{key:t,line:e,getLineProps:a,getTokenProps:r,classNames:E[t],showLineNumbers:w})))))})),o.createElement("div",{className:N.buttonGroup},(y.isEnabled||y.isCodeScrollable)&&o.createElement(q,{className:N.codeButton,onClick:()=>y.toggle(),isEnabled:y.isEnabled}),o.createElement(R,{className:N.codeButton,code:C}))))}function U(e){let{children:t,...n}=e;const a=(0,l.Z)(),c=function(e){return o.Children.toArray(e).some((e=>(0,o.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof c?G:C;return o.createElement(i,(0,r.Z)({key:String(a)},n),c)}var Q=n(9960);var X=n(6043);const Y={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function J(e){return!!e&&("SUMMARY"===e.tagName||J(e.parentElement))}function K(e,t){return!!e&&(e===t||K(e.parentElement,t))}function ee(e){let{summary:t,children:n,...a}=e;const c=(0,l.Z)(),s=(0,o.useRef)(null),{collapsed:u,setCollapsed:m}=(0,X.u)({initialState:!a.open}),[d,p]=(0,o.useState)(a.open),f=o.isValidElement(t)?t:o.createElement("summary",null,t??"Details");return o.createElement("details",(0,r.Z)({},a,{ref:s,open:d,"data-collapsed":u,className:(0,i.Z)(Y.details,c&&Y.isBrowser,a.className),onMouseDown:e=>{J(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;J(t)&&K(t,s.current)&&(e.preventDefault(),u?(m(!1),p(!0)):m(!0))}}),f,o.createElement(X.z,{lazy:!1,collapsed:u,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{m(e),p(!e)}},o.createElement("div",{className:Y.collapsibleContent},n)))}const te={details:"details_b_Ee"},ne="alert alert--info";function oe(e){let{...t}=e;return o.createElement(ee,(0,r.Z)({},t,{className:(0,i.Z)(ne,te.details,t.className)}))}var ae=n(2503);function re(e){return o.createElement(ae.Z,e)}const ce={containsTaskList:"containsTaskList_mC6p"};const le={img:"img_ev3q"};const ie="admonition_LlT9",se="admonitionHeading_tbUL",ue="admonitionIcon_kALy",me="admonitionContent_S0QG";const de={note:{infimaClassName:"secondary",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:o.createElement(M.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:o.createElement(M.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 16 16"},o.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:o.createElement(M.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},pe={secondary:"note",important:"info",success:"tip",warning:"danger"};function fe(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=o.Children.toArray(e),n=t.find((e=>o.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n,rest:a}}(e.children);return{...e,title:e.title??t,children:n}}const ge={head:function(e){const t=o.Children.map(e.children,(e=>o.isValidElement(e)?function(e){if(e.props?.mdxType&&e.props.originalType){const{mdxType:t,originalType:n,...a}=e.props;return o.createElement(e.props.originalType,a)}return e}(e):e));return o.createElement(c.Z,e,t)},code:function(e){const t=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return o.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")||(0,o.isValidElement)(e)&&t.includes(e.props?.mdxType)))?o.createElement("code",e):o.createElement(U,e)},a:function(e){return o.createElement(Q.Z,e)},pre:function(e){return o.createElement(U,(0,o.isValidElement)(e.children)&&"code"===e.children.props?.originalType?e.children.props:{...e})},details:function(e){const t=o.Children.toArray(e.children),n=t.find((e=>o.isValidElement(e)&&"summary"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return o.createElement(oe,(0,r.Z)({},e,{summary:n}),a)},ul:function(e){return o.createElement("ul",(0,r.Z)({},e,{className:(t=e.className,(0,i.Z)(t,t?.includes("contains-task-list")&&ce.containsTaskList))}));var t},img:function(e){return o.createElement("img",(0,r.Z)({loading:"lazy"},e,{className:(t=e.className,(0,i.Z)(t,le.img))}));var t},h1:e=>o.createElement(re,(0,r.Z)({as:"h1"},e)),h2:e=>o.createElement(re,(0,r.Z)({as:"h2"},e)),h3:e=>o.createElement(re,(0,r.Z)({as:"h3"},e)),h4:e=>o.createElement(re,(0,r.Z)({as:"h4"},e)),h5:e=>o.createElement(re,(0,r.Z)({as:"h5"},e)),h6:e=>o.createElement(re,(0,r.Z)({as:"h6"},e)),admonition:function(e){const{children:t,type:n,title:a,icon:r}=fe(e),c=function(e){const t=pe[e]??e,n=de[t];return n||(console.warn(`No admonition config found for admonition type "${t}". Using Info as fallback.`),de.info)}(n),l=a??c.label,{iconComponent:s}=c,u=r??o.createElement(s,null);return o.createElement("div",{className:(0,i.Z)(d.k.common.admonition,d.k.common.admonitionType(e.type),"alert",`alert--${c.infimaClassName}`,ie)},o.createElement("div",{className:se},o.createElement("span",{className:ue},u),l),o.createElement("div",{className:me},t))},mermaid:n(1875).Z};function he(e){let{children:t}=e;return o.createElement(a.Zo,{components:ge},t)}},2244:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var o=n(7294),a=n(6010),r=n(9960);function c(e){const{permalink:t,title:n,subLabel:c,isNext:l}=e;return o.createElement(r.Z,{className:(0,a.Z)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},c&&o.createElement("div",{className:"pagination-nav__sublabel"},c),o.createElement("div",{className:"pagination-nav__label"},n))}},3008:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var o=n(7294),a=n(6010),r=n(9960);const c={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function l(e){let{permalink:t,label:n,count:l}=e;return o.createElement(r.Z,{href:t,className:(0,a.Z)(c.tag,l?c.tagWithCount:c.tagRegular)},n,l&&o.createElement("span",null,l))}},1526:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var o=n(7294),a=n(6010),r=n(5999),c=n(3008);const l={tags:"tags_jXut",tag:"tag_QGVx"};function i(e){let{tags:t}=e;return o.createElement(o.Fragment,null,o.createElement("b",null,o.createElement(r.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list"},"Tags:")),o.createElement("ul",{className:(0,a.Z)(l.tags,"padding--none","margin-left--sm")},t.map((e=>{let{label:t,permalink:n}=e;return o.createElement("li",{key:n,className:l.tag},o.createElement(c.Z,{label:t,permalink:n}))}))))}},7594:(e,t)=>{function n(e){let t,n=[];for(let o of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(o))n.push(parseInt(o,10));else if(t=o.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,o,a,r]=t;if(o&&r){o=parseInt(o),r=parseInt(r);const e=o<r?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(r+=e);for(let t=o;t!==r;t+=e)n.push(t)}}return n}t.default=n,e.exports=n}}]); \ No newline at end of file diff --git a/build-staging/assets/js/97a045eb.5c55b238.js b/build-staging/assets/js/97a045eb.5c55b238.js new file mode 100644 index 00000000..135b5e9b --- /dev/null +++ b/build-staging/assets/js/97a045eb.5c55b238.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3838],{4869:a=>{a.exports=JSON.parse('{"label":"nightly","permalink":"/blog/tags/nightly","allTagsPath":"/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/986bf1b5.1e9911cc.js b/build-staging/assets/js/986bf1b5.1e9911cc.js new file mode 100644 index 00000000..408076cb --- /dev/null +++ b/build-staging/assets/js/986bf1b5.1e9911cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3625],{8327:e=>{e.exports=JSON.parse('{"title":"Profiles","slug":"/category/profiles","permalink":"/docs/category/profiles","navigation":{"previous":{"title":"Supported Platforms","permalink":"/docs/getting-started/supported_platforms"},"next":{"title":"An Introduction to Cwtch Profiles","permalink":"/docs/profiles/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/98da7451.9df2feb9.js b/build-staging/assets/js/98da7451.9df2feb9.js new file mode 100644 index 00000000..5637cb9a --- /dev/null +++ b/build-staging/assets/js/98da7451.9df2feb9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8141],{8777:e=>{e.exports=JSON.parse('{"title":"Settings","slug":"/category/settings","permalink":"/docs/category/settings","navigation":{"previous":{"title":"How to Unlock a server","permalink":"/docs/servers/unlock-server"},"next":{"title":"An Introduction to Cwtch App Settings","permalink":"/docs/settings/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/992a3bb7.e91a6bcf.js b/build-staging/assets/js/992a3bb7.e91a6bcf.js new file mode 100644 index 00000000..d0aa1b78 --- /dev/null +++ b/build-staging/assets/js/992a3bb7.e91a6bcf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1415],{8229:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9b12a270.bb5deec9.js b/build-staging/assets/js/9b12a270.bb5deec9.js new file mode 100644 index 00000000..b782fde3 --- /dev/null +++ b/build-staging/assets/js/9b12a270.bb5deec9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9249],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>g});var r=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function o(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?a(Object(i),!0).forEach((function(t){n(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):a(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function c(e,t){if(null==e)return{};var i,r,n=function(e,t){if(null==e)return{};var i,r,n={},a=Object.keys(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var s=r.createContext({}),l=function(e){var t=r.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},d=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,a=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),p=l(i),h=n,g=p["".concat(s,".").concat(h)]||p[h]||u[h]||a;return i?r.createElement(g,o(o({ref:t},d),{},{components:i})):r.createElement(g,o({ref:t},d))}));function g(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=i.length,o=new Array(a);o[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:n,o[1]=c;for(var l=2;l<a;l++)o[l]=i[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,i)}h.displayName="MDXCreateElement"},9816:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=i(7462),n=(i(7294),i(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"February 10, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"repliqate",permalink:"/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/blog/cwtch-testing-i"}},s={authorsImageUrls:[void 0]},l=[{value:"Changes Necessary for Reproducible Android Bindings",id:"changes-necessary-for-reproducible-android-bindings",level:2},{value:"Repliqate Scripts",id:"repliqate-scripts",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:l},p="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,r.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(4756).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"changes-necessary-for-reproducible-android-bindings"},"Changes Necessary for Reproducible Android Bindings"),(0,n.kt)("p",null,"After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Insufficient path stripping introduced by Android NDK tools")," - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/android/ndk/wiki/Changelog-r22"},"changed the binutils and default linker")," to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our ",(0,n.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-platform-support"},"long term support plan"),", we will be moving towards adopting the latest NDK in the future."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Paths in DWARF entries")," - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.")),(0,n.kt)("figure",null,(0,n.kt)("p",null,(0,n.kt)("a",{target:"_blank",href:i(4560).Z},(0,n.kt)("img",{src:i(9842).Z,width:"1863",height:"428"}))),(0,n.kt)("figcaption",null,"Vimdiff comparing the decoded (",(0,n.kt)("code",null,"readelf --debug-dump=line"),") DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Go Compiler Acquisition")," - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there ",(0,n.kt)("em",{parentName:"li"},"was")," a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.")),(0,n.kt)("h2",{id:"repliqate-scripts"},"Repliqate Scripts"),(0,n.kt)("p",null,"With those issues now fixed, Cwtch Android bindings are ",(0,n.kt)("strong",{parentName:"p"},"officially reproducible!")," The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script"},"cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script")," in the ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/"},"Cwtch Repliqate scripts repository"),"."),(0,n.kt)("p",null,"This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4560:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},9842:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},4756:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"},4515:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9bb37799.506f4b14.js b/build-staging/assets/js/9bb37799.506f4b14.js new file mode 100644 index 00000000..b42e3d83 --- /dev/null +++ b/build-staging/assets/js/9bb37799.506f4b14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9767],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),h=p(r),m=o,d=h["".concat(c,".").concat(m)]||h[m]||u[m]||a;return r?n.createElement(d,i(i({ref:t},l),{},{components:r})):n.createElement(d,i({ref:t},l))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[h]="string"==typeof e?e:o,i[1]=s;for(var p=2;p<a;p++)i[p]=r[p];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},2957:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Cwtch Technical Basics",s={unversionedId:"components/intro",id:"components/intro",title:"Cwtch Technical Basics",description:"This page presents a brief technical overview of the Cwtch protocol.",source:"@site/security/components/intro.md",sourceDirName:"components",slug:"/components/intro",permalink:"/security/components/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Cwtch Components",permalink:"/security/category/cwtch-components"},next:{title:"Component Ecosystem Overview",permalink:"/security/components/ecosystem-overview"}},c={},p=[{value:"A Cwtch Profile",id:"a-cwtch-profile",level:2},{value:"2-party conversions: Peer to Peer",id:"2-party-conversions-peer-to-peer",level:2},{value:"Multi-party conversations: Groups and Peer to Server Communication",id:"multi-party-conversations-groups-and-peer-to-server-communication",level:2},{value:"Servers are Peers",id:"servers-are-peers",level:3}],l={toc:p},h="wrapper";function u(e){let{components:t,...a}=e;return(0,o.kt)(h,(0,n.Z)({},l,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cwtch-technical-basics"},"Cwtch Technical Basics"),(0,o.kt)("p",null,"This page presents a brief technical overview of the Cwtch protocol."),(0,o.kt)("h2",{id:"a-cwtch-profile"},"A Cwtch Profile"),(0,o.kt)("p",null,"Users can create one of more Cwtch Profiles. Each profile generates a random ed25519 keypair compatible with\nTor."),(0,o.kt)("p",null,"In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys +\nassociated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages)."),(0,o.kt)("h2",{id:"2-party-conversions-peer-to-peer"},"2-party conversions: Peer to Peer"),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(7868).Z,width:"960",height:"540"})),(0,o.kt)("p",null,'For 2 parties to engage in a peer-to-peer conversation both must be online, but only one needs to be reachable via\ntheir onion service. For the sake of clarity we often label one party the "inbound peer" (the one who hosts the onion service) and the other party the\n"outbound peer" (the one that connects to the onion service).'),(0,o.kt)("p",null,"After connection both parties engage in an authentication protocol which:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Asserts that each party has access to the private key associated with their public identity."),(0,o.kt)("li",{parentName:"ul"},"Generates an ephemeral session key used to encrypt all further communication during the session.")),(0,o.kt)("p",null,"This exchange (documented in further detail in ",(0,o.kt)("a",{parentName:"p",href:"/security/components/tapir/authentication_protocol"},"authentication protocol"),") is ",(0,o.kt)("em",{parentName:"p"},"offline deniable"),"\ni.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the\nfact - it is impossible to definitely prove that the exchange happened at all."),(0,o.kt)("p",null,"After, the authentication protocol the two parties may exchange messages with each other freely."),(0,o.kt)("h2",{id:"multi-party-conversations-groups-and-peer-to-server-communication"},"Multi-party conversations: Groups and Peer to Server Communication"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Note: Metadata Resistant Group Communication is still an active research area and what is documented here\nwill likely change in the future.")),(0,o.kt)("p",null,"When a person wants to start a group conversation they first randomly generate a secret ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),". All group communication will be encrypted using this key."),(0,o.kt)("p",null,"Along with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),", the group creator also decides on a ",(0,o.kt)("strong",{parentName:"p"},"Cwtch Server")," to use as the host of the group.\nFor more information on how Servers authenticate themselves see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/cwtch/key_bundles"},"key bundles"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Identifier")," is generated using the group key and the group server and these three elements are packaged up\ninto an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections)."),(0,o.kt)("p",null,"To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts\ntheir message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and generates a cryptographic signature over the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Id"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Server"),"\nand the decrypted message (see: ",(0,o.kt)("a",{parentName:"p",href:"/security/components/cwtch/message_formats"},"wire formats")," for more information)."),(0,o.kt)("p",null,"To receive message from the group, a profile connected to the server hosting the group and downloads ",(0,o.kt)("em",{parentName:"p"},"all")," messages (since\ntheir previous connection). Profiles then attempt to decrypt each message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and if successful attempt\nto verify the signature (see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/cwtch/server"},"Cwtch Servers")," ",(0,o.kt)("a",{parentName:"p",href:"/security/components/cwtch/groups"},"Cwtch Groups")," for an overview of attacks and mitigations)."),(0,o.kt)("h3",{id:"servers-are-peers"},"Servers are Peers"),(0,o.kt)("p",null,"In many respects communication with a server is identical to communication with a regular Cwtch peer,\nall the same steps above are taken however the server always acts as the inbound peer, and the outbound\npeer always uses newly generated ",(0,o.kt)("strong",{parentName:"p"},"ephemeral keypair"),' as their "longterm identity".'),(0,o.kt)("p",null,"As such peer-server conversations only differ in the ",(0,o.kt)("em",{parentName:"p"},"kinds")," of messages that are sent between the two parties,\nwith the server relaying all messages that it receives and also allowing any client to query for older messages."))}u.isMDXComponent=!0},7868:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9c021584.82717406.js b/build-staging/assets/js/9c021584.82717406.js new file mode 100644 index 00000000..bce64bd0 --- /dev/null +++ b/build-staging/assets/js/9c021584.82717406.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7438],{8055:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/release","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9d21518d.b4fade03.js b/build-staging/assets/js/9d21518d.b4fade03.js new file mode 100644 index 00000000..9720f26f --- /dev/null +++ b/build-staging/assets/js/9d21518d.b4fade03.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3628],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(r),d=i,f=u["".concat(p,".").concat(d)]||u[d]||m[d]||a;return r?n.createElement(f,o(o({ref:t},l),{},{components:r})):n.createElement(f,o({ref:t},l))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:i,o[1]=s;for(var c=2;c<a;c++)o[c]=r[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},1335:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const a={sidebar_position:4},o="Image Previews and Profile Pictures",s={unversionedId:"settings/experiments/image-previews-and-profile-pictures",id:"settings/experiments/image-previews-and-profile-pictures",title:"Image Previews and Profile Pictures",description:"This experiment requires the File Sharing experiment enabled.",source:"@site/docs/settings/experiments/image-previews-and-profile-pictures.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/image-previews-and-profile-pictures",permalink:"/docs/settings/experiments/image-previews-and-profile-pictures",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/image-previews-and-profile-pictures.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"File Sharing",permalink:"/docs/settings/experiments/file-sharing"},next:{title:"Clickable Links Experiment",permalink:"/docs/settings/experiments/clickable-links"}},p={},c=[],l={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"image-previews-and-profile-pictures"},"Image Previews and Profile Pictures"),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"This experiment requires the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"File Sharing")," experiment enabled.")),(0,i.kt)("p",null,"When enabled, Cwtch will download image files automatically, display image previews in the conversation window, and enable the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profile Pictures")," feature;"),(0,i.kt)("p",null,"On Desktop, enabling this experiment will allow access to an additional setting ",(0,i.kt)("inlineCode",{parentName:"p"},'"'),"Download Folder` which can be changed to tell Cwtch where to (automatically) download pictures."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9dd8190d.f34b30a9.js b/build-staging/assets/js/9dd8190d.f34b30a9.js new file mode 100644 index 00000000..bab6532d --- /dev/null +++ b/build-staging/assets/js/9dd8190d.f34b30a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2688],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),s=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(n),g=a,m=h["".concat(c,".").concat(g)]||h[g]||d[g]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=g;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var s=2;s<o;s++)r[s]=n[s];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}g.displayName="MDXCreateElement"},7561:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const o={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"February 24, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"autobindings",permalink:"/blog/tags/autobindings"},{label:"libcwtch",permalink:"/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/blog/cwtch-testing-ii"}},c={authorsImageUrls:[void 0]},s=[{value:"A Brief History of Cwtch Bindings",id:"a-brief-history-of-cwtch-bindings",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:s},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,a.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,a.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"a-brief-history-of-cwtch-bindings"},"A Brief History of Cwtch Bindings"),(0,a.kt)("p",null,"Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/therecipe/qt"},"therecipe/qt"),". However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework."),(0,a.kt)("p",null,"As part of early prototyping efforts for Flutter we built out a first version of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libCwtch-go"),", and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings."),(0,a.kt)("p",null,"This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape"},"experimental features")," - handle settings, ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings"},"duplication of logic between Cwtch and libCwtch-go"),", and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go"},"special behaviour in libCwtch-go that better belongs in the core Cwtch library"),"."),(0,a.kt)("p",null,"As part of a broader effort to ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"refine the Cwtch API in preparation for Cwtch Stable")," we have taken the opportunity to fix many of these problems."),(0,a.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,a.kt)("p",null,"The current ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockContact")," API implementation is:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"//export c_BlockContact\nfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\n BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\n}\n\nfunc BlockContact(profileOnion string, conversationID int) {\n profile := application.GetPeer(profileOnion)\n if profile != nil {\n profile.BlockConversation(conversationID)\n }\n}\n")),(0,a.kt)("p",null,"All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively."),(0,a.kt)("p",null,"In the new ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings")," we reduce these multiple lines to ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19"},"a single one"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"profile BlockConversation conversation\n")),(0,a.kt)("p",null,"Defining a ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"-level function, called ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockConversation")," which takes in a single parameter of type ",(0,a.kt)("inlineCode",{parentName:"p"},"conversation"),"."),(0,a.kt)("p",null,"Using a similar boilerplate-reduction for the reset of ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," yields ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format"},"5-basic function prototypes"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateProfile")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"BlockConversation")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"GetMessage")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"DownloadFile")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareFile"))),(0,a.kt)("p",null,"Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec"},"described in fewer than 50 lines, including comments"),". Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.)."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments"))," (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on ",(0,a.kt)("inlineCode",{parentName:"li"},"cwtch-server"),"). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart-side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch API"),": This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the ",(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"Cwtch Stable API redesign"),". In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9e2a7473.1020ed04.js b/build-staging/assets/js/9e2a7473.1020ed04.js new file mode 100644 index 00000000..e4934a20 --- /dev/null +++ b/build-staging/assets/js/9e2a7473.1020ed04.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1258],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),c=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return i.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),u=a,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var c=2;c<o;c++)r[c]=n[c];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},8725:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var i=n(7462),a=(n(7294),n(3905));const o={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"January 13, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"},{label:"api",permalink:"/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/blog/path-to-cwtch-stable"}},s={authorsImageUrls:[void 0]},c=[{value:"Clarifying Terminology",id:"clarifying-terminology",level:3},{value:"Tenets of the Cwtch API Design",id:"tenets-of-the-cwtch-api-design",level:3},{value:"The Cwtch Experiment Landscape",id:"the-cwtch-experiment-landscape",level:3},{value:"The Problem with Experiments",id:"the-problem-with-experiments",level:3},{value:"Restricting Powerful Cwtch APIs",id:"restricting-powerful-cwtch-apis",level:3},{value:"Pre-Registered Hooks",id:"pre-registered-hooks",level:4},{value:"<code>ProtocolEngine</code> Subsystems",id:"protocolengine-subsystems",level:4},{value:"Impact on Enabling (Powerful) New Functionality",id:"impact-on-enabling-powerful-new-functionality",level:4},{value:"Application Experiments",id:"application-experiments",level:2},{value:"Bindings",id:"bindings",level:2},{value:"Timelines and Next Actions",id:"timelines-and-next-actions",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2},{value:"Appendix A: Special Behaviour Defined by libcwtch-go",id:"appendix-a-special-behaviour-defined-by-libcwtch-go",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,a.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,a.kt)("p",null,"As we move out of Beta and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,a.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(4867).Z,width:"1005",height:"481"})),(0,a.kt)("h3",{id:"clarifying-terminology"},"Clarifying Terminology"),(0,a.kt)("p",null,"Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch")," refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtchlib")," refers to the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"reference implementation of the Cwtch Protocol")," / Application framework, currently written in Go."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Bindings")," refers to C/Java/Kotlin/Rust bindings (primarily ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libcwtch-go"),") that act as an interface between Cwtchlib and downstream applications."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.")),(0,a.kt)("h3",{id:"tenets-of-the-cwtch-api-design"},"Tenets of the Cwtch API Design"),(0,a.kt)("p",null,"Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Robustness")," - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Completeness")," - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Security")," \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.")),(0,a.kt)("h3",{id:"the-cwtch-experiment-landscape"},"The Cwtch Experiment Landscape"),(0,a.kt)("p",null,"A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Groups")," \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Hybrid Groups")," - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Server Hosting")," \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Message Formatting")," \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search / Microblogging")," \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status / Profile Metadata")," \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.")),(0,a.kt)("h3",{id:"the-problem-with-experiments"},"The Problem with Experiments"),(0,a.kt)("p",null,"We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"SendMessages")," interface that only allows callers to send messages."),(0,a.kt)("p",null,"We have also worked to package experimental functionality into so-called ",(0,a.kt)("strong",{parentName:"p"},"Gated Functionalities")," that are only available if a given experiment is turned on."),(0,a.kt)("p",null,"Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"SendMessages")," \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing)."),(0,a.kt)("li",{parentName:"ul"},"The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality."),(0,a.kt)("li",{parentName:"ul"},"This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.")),(0,a.kt)("h3",{id:"restricting-powerful-cwtch-apis"},"Restricting Powerful Cwtch APIs"),(0,a.kt)("p",null,"To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through ",(0,a.kt)("inlineCode",{parentName:"li"},"Application")," and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile."),(0,a.kt)("li",{parentName:"ul"},"Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a ",(0,a.kt)("inlineCode",{parentName:"li"},"RestrictedCwtchConversationInterface")," which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact."),(0,a.kt)("li",{parentName:"ul"},"Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," to control which experiments get access to which events at a given time.")),(0,a.kt)("h4",{id:"pre-registered-hooks"},"Pre-Registered Hooks"),(0,a.kt)("p",null,"In order to implement certain functionality actions need to take place in-between events handled by ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),". As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group)."),(0,a.kt)("p",null,"This is currently only possible with invasive changes to the ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort."),(0,a.kt)("p",null,"We are introducing a new set of Cwtch APIs designed for this purpose:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnNewPeerMessage")," - hooked prior to inserting the message into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnPeerMessageConfirmed")," \u2013 hooked after a peer message has been inserted into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEncryptedGroupMessage")," \u2013 hooked after receiving an encrypted message from a group server."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnGroupMessageReceived")," \u2013 hooked after a successful decryption of a group message, but before inserting it into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactRequestValue")," \u2013 hooked on request of a scoped (the permission level of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"public")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation")," level attributes), zoned ( relating to a specific feature e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"filesharing")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"chat"),"), and keyed (the name of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"name")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest"),") value from a contact."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactReceiveValue")," \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.")),(0,a.kt)("p",null,"Including the following APIs for managing hooked functionality:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the extension is interested processing."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," - returns a set of experiments that the extension is interested in being notified about"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," - to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (assuming all experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," is active)")),(0,a.kt)("h4",{id:"protocolengine-subsystems"},(0,a.kt)("inlineCode",{parentName:"h4"},"ProtocolEngine")," Subsystems"),(0,a.kt)("p",null,"As mentioned in our experiment summary, some functionality needs to be implemented directly in the ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),". The ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus)."),(0,a.kt)("p",null,"Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),"."),(0,a.kt)("p",null,"At the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," ecosystem. "),(0,a.kt)("p",null,"We are formalizing this subsystem into an interface, similar to the hooked functionality in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the subsystem needs to consume to operate."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," \u2013 to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (when all the experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," are active)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterContexts")," - returns the set of contexts that the subsystem implements e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"im.cwtch.filesharing"))),(0,a.kt)("p",null,"This also requires a formalization of two ",(0,a.kt)("em",{parentName:"p"},"engine specific")," events (for use on the event bus):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SendCwtchMessage")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage")," that is used internally in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," for messages between subsystems."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchMessageReceived")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.")),(0,a.kt)("p",null,"And the introduction of three ",(0,a.kt)("strong",{parentName:"p"},"additional")," ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEnine")," specific events:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StartEngineSubsystem")," \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StopEngineSubsystem")," \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SubsystemStatus")," \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging")),(0,a.kt)("p",null,"This will allow us to move the following functionality, currently part of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," itself, into generic subsystems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Attribute Lookup Handling")," - this functionality is currently part of the overloaded ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function, filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter of the ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage"),". As such it can be entirely delegated to a subsystem. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Chunk Request Handling")," \u2013 this is also part of handlePeerMessage, also filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage"),")"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Start File Share/Stop File Share")," \u2013 this is currently part of the ",(0,a.kt)("inlineCode",{parentName:"li"},"handleEvent")," behaviour of ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," and can be moved into an ",(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," handler of the file sharing subsystem (where such events are already processed).")),(0,a.kt)("p",null,"The introduction of pre-registered hooks in combination with the formalizations of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," subsystems will allow the follow functionality, currently implemented in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," or libcwtch-go to be moved to standalone packages:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Filesharing also depends on the file sharing subsystem to be enabled in a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),". This subsystem is responsible for processing chunk requests."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Legacy Groups")," \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status/Profile Metadata")," \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.")),(0,a.kt)("h4",{id:"impact-on-enabling-powerful-new-functionality"},"Impact on Enabling (Powerful) New Functionality"),(0,a.kt)("p",null,"None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search")," \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Non Chat Conversation Contexts")," - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.")),(0,a.kt)("h2",{id:"application-experiments"},"Application Experiments"),(0,a.kt)("p",null,"One kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers."),(0,a.kt)("p",null,"This kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library."),(0,a.kt)("p",null,"This functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface."),(0,a.kt)("h2",{id:"bindings"},"Bindings"),(0,a.kt)("p",null,"The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications."),(0,a.kt)("p",null,"We can split the bindings into four core areas:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Management")," - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Experiments")," - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Core Profile Management")," - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Experimental Profile Features")," \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.")),(0,a.kt)("p",null,"The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings."),(0,a.kt)("p",null,"In an ideal future, all of these bindings could be ",(0,a.kt)("strong",{parentName:"p"},"generated automatically")," from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)"),(0,a.kt)("p",null,"We can define three types of C/Java/Kotlin interface function templates:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileMethodName(profilehandle String, args...)")," \u2013 which directly resolves the Cwtch Profile and calls the function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileExperimentalMethodName(profilehandle String, args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ApplicationExperimentalMethodName(args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.")),(0,a.kt)("p",null,"All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ",(0,a.kt)("inlineCode",{parentName:"p"},"ProfileInterface")," for the first, exported methods of the various ",(0,a.kt)("inlineCode",{parentName:"p"},"Functionalities")," for the second, and ",(0,a.kt)("inlineCode",{parentName:"p"},"ApplicationExperiment")," definitions for the third."),(0,a.kt)("h2",{id:"timelines-and-next-actions"},"Timelines and Next Actions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Freeze any changes to the bindings interface")," - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib."),(0,a.kt)("li",{parentName:"ul"},"As part of Cwtch 1.11 and 1.12 Release Cycles",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Implement the ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," Subsystem Design as outlined above."),(0,a.kt)("li",{parentName:"ul"},"Implement the Hooks API."),(0,a.kt)("li",{parentName:"ul"},"Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting)."),(0,a.kt)("li",{parentName:"ul"},"Move event handling from the bindings into Application."),(0,a.kt)("li",{parentName:"ul"},"Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions."))),(0,a.kt)("li",{parentName:"ul"},"Once Automated UI Tests have been integrated into the Cwtch UI Repository:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings ",(0,a.kt)("strong",{parentName:"li"},"and")," a dart calling convention library from cwtchlib and any configured application experiments libraries"),(0,a.kt)("li",{parentName:"ul"},"Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process)."),(0,a.kt)("li",{parentName:"ul"},"At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.")))),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})),(0,a.kt)("h2",{id:"appendix-a-special-behaviour-defined-by-libcwtch-go"},"Appendix A: Special Behaviour Defined by libcwtch-go"),(0,a.kt)("p",null,"The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application Settings",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Including Enabling / Disabling Experiment"))),(0,a.kt)("li",{parentName:"ul"},"ACN Process Management - starting/stopping/restarting/configuring Tor."),(0,a.kt)("li",{parentName:"ul"},"Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)"),(0,a.kt)("li",{parentName:"ul"},"Logging Levels - configuring appropriate logging levels (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"INFO")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"DEBUG"),")"),(0,a.kt)("li",{parentName:"ul"},"Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled."),(0,a.kt)("li",{parentName:"ul"},"UI Contact Structures - aggregating contact information for the main Cwtch UI."),(0,a.kt)("li",{parentName:"ul"},"Group Experiment Functionality",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Experiment Gating"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfoList"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfo"),(0,a.kt)("li",{parentName:"ul"},"UI Server Struct Definition"))),(0,a.kt)("li",{parentName:"ul"},"Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients."),(0,a.kt)("li",{parentName:"ul"},'"Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".'),(0,a.kt)("li",{parentName:"ul"},"Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled)."),(0,a.kt)("li",{parentName:"ul"},"Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Profile Engine Activation - starting/stopping a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," when requested by the UI, or in response to changes in ACN state."),(0,a.kt)("li",{parentName:"ul"},"UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event."),(0,a.kt)("li",{parentName:"ul"},"File sharing restarts "),(0,a.kt)("li",{parentName:"ul"},"UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting ",(0,a.kt)("inlineCode",{parentName:"li"},"handle")," to a ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation id"),"). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself."),(0,a.kt)("li",{parentName:"ul"},"Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)")))}d.isMDXComponent=!0},4867:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9e4087bc.582408aa.js b/build-staging/assets/js/9e4087bc.582408aa.js new file mode 100644 index 00000000..6b05be93 --- /dev/null +++ b/build-staging/assets/js/9e4087bc.582408aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3608],{3169:(e,t,a)=>{a.r(t),a.d(t,{default:()=>o});var r=a(7294),l=a(9960),n=a(5999),c=a(1944),m=a(7961);function s(e){let{year:t,posts:a}=e;return r.createElement(r.Fragment,null,r.createElement("h3",null,t),r.createElement("ul",null,a.map((e=>r.createElement("li",{key:e.metadata.date},r.createElement(l.Z,{to:e.metadata.permalink},e.metadata.formattedDate," - ",e.metadata.title))))))}function i(e){let{years:t}=e;return r.createElement("section",{className:"margin-vert--lg"},r.createElement("div",{className:"container"},r.createElement("div",{className:"row"},t.map(((e,t)=>r.createElement("div",{key:t,className:"col col--4 margin-vert--lg"},r.createElement(s,e)))))))}function o(e){let{archive:t}=e;const a=(0,n.I)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),l=(0,n.I)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),s=function(e){const t=e.reduceRight(((e,t)=>{const a=t.metadata.date.split("-")[0],r=e.get(a)??[];return e.set(a,[t,...r])}),new Map);return Array.from(t,(e=>{let[t,a]=e;return{year:t,posts:a}}))}(t.blogPosts);return r.createElement(r.Fragment,null,r.createElement(c.d,{title:a,description:l}),r.createElement(m.Z,null,r.createElement("header",{className:"hero hero--primary"},r.createElement("div",{className:"container"},r.createElement("h1",{className:"hero__title"},a),r.createElement("p",{className:"hero__subtitle"},l))),r.createElement("main",null,s.length>0&&r.createElement(i,{years:s}))))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/9f1c7621.9c0d80ed.js b/build-staging/assets/js/9f1c7621.9c0d80ed.js new file mode 100644 index 00000000..9241aced --- /dev/null +++ b/build-staging/assets/js/9f1c7621.9c0d80ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1312],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>g});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function s(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=l(a),h=r,g=u["".concat(p,".").concat(h)]||u[h]||d[h]||i;return a?n.createElement(g,o(o({ref:t},c),{},{components:a})):n.createElement(g,o({ref:t},c))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:r,o[1]=s;for(var l=2;l<i;l++)o[l]=a[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},4387:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"February 17, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"support",permalink:"/blog/tags/support"},{label:"testing",permalink:"/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/blog/cwtch-android-reproducibility"}},p={authorsImageUrls:[void 0]},l=[{value:"Constraining Cwtch UI Fields",id:"constraining-cwtch-ui-fields",level:2},{value:"More Automated UI Tests",id:"more-automated-ui-tests",level:2},{value:"New Release of Cwtchbot",id:"new-release-of-cwtchbot",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:l},u="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(u,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,r.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6097).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraining-cwtch-ui-fields"},"Constraining Cwtch UI Fields"),(0,r.kt)("p",null,"Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3785).Z},(0,r.kt)("img",{src:a(6561).Z,width:"410",height:"90"}))),(0,r.kt)("figcaption",null,"Screenshot demonstrating how certain strings would violate the bounds of their containers.")),(0,r.kt)("p",null,"These cases were fixed by parenting impacted elements in a ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"clip: hardEdge")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"decoration:BoxDecoration()")," (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration)."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3551).Z},(0,r.kt)("img",{src:a(9812).Z,width:"427",height:"76"}))),(0,r.kt)("figcaption",null,"Now these clipped strings are tightly constrained to their container bounds.")),(0,r.kt)("p",null,"These fixes are available in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"latest Cwtch Nightly"),", and will be officially released in Cwtch 1.11."),(0,r.kt)("h2",{id:"more-automated-ui-tests"},"More Automated UI Tests"),(0,r.kt)("p",null,"We have added two new sets of automated UI tests to our pipeline:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"02: Global Settings")," - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628"},"PR: 628"),")"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"04: Profile Management")," - these tests check that creating, unlocking, and deleting a profile work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632"},"PR: 632"),")")),(0,r.kt)("h2",{id:"new-release-of-cwtchbot"},"New Release of Cwtchbot"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"Cwtchbot")," has been updated to use the latest Cwtch 0.18.10 API."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3551:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png"},3785:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},6097:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"},9812:(e,t,a)=>{a.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAasAAABMCAIAAABcRQ+0AAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO2deUBU57n/n3Nm34cBZhiYYVhkXwURxAV0kLggauK1McSkadIm2i1tr/mV5N70Nm1q9zXVtvc2aWLV2zSrsTFBiGiMYECibAIjwjBsMwPD7Ps55/4xhhIYYVhC7C/vR/+YOed93+/zDMzDe97lebHnD+4FBAKB+PxR06nFP2sbEAgE4jMDRUAEAvH5BUVABALx+QVFQAQC8fkFRUAEAvH5hf7pNS2JUUkUKpEsRhApE4RL2QIhmy+iMRgAQPh8brvFbbPaxg02o96iHzINak1D2k/PGAQCgZjJEkdABostT8mUrUiTxidLE5Jvq8pk8iWRfElkhCpx8qLhZo+hr0d/4/pId7vP415awxAIBGImSxYBxXJFbHaBMitPGn8r8Fmt1qampra2tp6eHq1Wq9frLRaL2+0GADabLRKJoqKiYmNjk5OTc3JyioqKpAnJ0oTkTHWFoa9H19Yy0NpkHhlcKvMQCARiJksQASUxqvj84ri8ImFkFADodLrTp0/X1tZevnz5dlXcbjeO426X++rVq3Q6vXRtiQQTSIQSM9glsvCY+GRpfHLSmtL+lsa+K5fQ0zECgfiUWFQEZPH4SWs2Jq0pFUcpAKCuru748eM1NTVzVuRxeU8+/sSHHzW9eea0ShH75aqHaGZK3zfYbun56R9+UVS8pqqqSq1WZ9+1KzZnlaahXtNwzuOwL8ZUBAKBmMnCI6AiIzd5bZkqpwAA6urqjhw5Mkunbyo4hlduqViZkD1hmWCz2dvLt0VwJGatEaPhToeDpKiampqamprCwsKDBw+q1eqC3fdLE1J6Pqgd7Li6YGsRCARiJguKgBiWXro1vXSrIEKq0+kOHz586tSp0Guz2exdm7a7BqxZaZkRYeEbVq91jdpJH0HDMLvdQVJkoNjly5cvX75cWVlZXV2tyimQxKg668901p8BilqIzQgEAjGDea8H5AhEBburCvc8KIiQnjx5ctOmTfMKfwCQkZrO93AoP8VhsMPDw8P4Iq/NAwCAgZ/wU58McKdOndq0adPJkycFEdLCPQ8W7K7iCETztRmBQCCCMr8IKIiQ5e/cl6neAQDV1dWHDh1yuVzzlcxITfdYXEABHaOnJaXQKBrpJwAAo+Eur5skyGnlXS7XoUOHqqurASBTvSN/5z5BhGy+oggEAjGTeURAQYRs5bY9SWs2Wq3WqqqqY8eOLUySz+H53X4KKBrQlDEK0k9SBAUANB5DNzro8/uC1jp27FhVVZXVak1as3Hltj0oCCIQiMUTagTkCEQ5W3YnFm4wGAz79u07f/78wjUxAIoCCiiSxHEa6SOAojAa7mX4R8f0JDm9DzjJ+fPn9+3bZzAYEgs35GzZjR6HEQjEIgktAmJY5uYdgd7fQw89dO3atcVIerwenEEHDEggHQ4H4fYDAI1B09uMo0b97HWvXbv20EMPBXqCmZt3AIYtxhIEAvE5J6S54PTSrYGxvwMHDiwy/AFAt6Zne5Ka9GMYEzebLaSfBAAan3GpsdFiscxZ/dq1awcOHDh+/HimeodjwtR57u1F2rMMVBx6Vhgpsxr1vU3vX69/Z9rdtJIteTv2ep1OfW9Xa80bQXfCzN5CgHt//CegqHFdf9f7Nbq2KzMLhCK0/oGvxmbnO80Tuo6W5tePf7ZCc3q9bEKheB2KEOJOA5szS74iI7do78OCCGl1dfWCx/5uiWFYrCK2vFR9f8W9gGMjFsMrb7zy8Ob9jhGrV0z+6MVftF/vCLGp/fv3Hz582DZmaHz5z2idIAKBWAA1nVrazoKMWUqwePyV2/dKE5JPnjz585//fDFiXA73sS9++dDXvpOfk8fksegsukDAz8/Jo9yE3+Vr13efOV/j9XlDbK21tVUul+cXFtGZ7OGuViLkistP6vry9Q9+NXX9ZtuY3jamX1v1aNHehzQN50i/P1Bgyzf+M0NdIU/O6P+okS0Q3f2fvxRFxejaW0JvAQDWVj2at+PepMKSnkvvAcC2b39/RVHpjcb6qZbMKcQWiHY88aPU9Zs5QvGopjNx9YZtj3/PaTFNDA0sv1AoXi+b0JxehyKEuNPoNVrmGAdMWrNRlVOg0+mefvrpxSiJheIfP/3DL+z+NwGfz2AwAhdpOI3D4fAVIjyKdfGjBvs89709/fTTOp1OlVOQtGbjYmz7tJEmJBn7NKTfF5dXlLxWHZ9frO/t9rn/uYqIIwrrvlgrT84AgI0PP85gc9rOnppXCwAgUcR1XXhXEBmlylldtPehyPik/pbGaZbMKaTIyPV53KbB/pj03AhVYl7FXrvJ2Pvh+5+JUCheL5vQnF6HIoS4A5mtDyiJUeVVfoHNF1ZXV3d0hPp8OhOhQPCT7z27MnsljUabeRej4Xaf4/W33xwzjc+rWb/fbzQat2/fzguTGHq7Xba5xxA/E5xWszIzT5aYQni9SWtKR7ra6v/866kFuCJx2oa7KJJMXb+ZFxZ++dUXRzWd82oBACiCSN1QzhWJBREyRUZux3v/aH33jWll5hQyDWplK9Jis1f5ve7U9eUep+3Ci8+5P/nBLptQKF4vm9CcXocihLjT6DVaZpsJic8vFkcp6urq5rvrYyocNuc/vl2dlZ6F47f6myRFulwuDpszeSVCEpGfk9d9Q0PNc8fbqVOn7rnnHrVaHZ9ffMemkDH2aVg8vtflwOn05jdPzBxod1ktDA7H63Qa+28EHc6fswUA0DTW5++6z+d2eV3O+ud/E3Sofk6hj6FwnKZpPBd0OH/ZhELxetmEQvF6TiHEHchtn4LFckVcXhEAHDlyZOGt43jllor83Lypvb9uTc+2vZVdvT2TV+h0+oqEFRw2ZwESAfPi8orEcsWC7fy0Of2zp0488cjpnz0V9NsVt7KQ8PkmhgcuvPicY2L8337w3NqqR6cWYAtEbL6AJIjRno7r9e8krl5f9fPnpz37p67fTBEESRKaS+/p2q4U7/vy3mePMD75kYYiJEtMIXw+XduV5tePL1goLFrp93r9Xs+FF58zjwxu+9b3t3/nmWle8yURhM9nG9M3v36cwebMNCZ1/WaeWOL3edvPnrpe/86nJxTKx1u878sUSXoc9rNHDuvarixMCHEHctsIGJtdIIyMqqurmyXjC5POwD4Gx3E6bXqPUiQUbd5YxuVwp14Ml0iy0jP5XN4nmmIwJ7uE8+Ly5ct1dXXCyKjY7IIFVA+Rgrv3P/T7v2WoKyavMBYUr4Miliu73j8rW5EKABsf+RaLyw8Mt0+SuGotRZLGPk10WrZQKs/dtsdlNWsazk0tI0/NGh/s97ndsTmr4vOLE1atHdfenDaYtWxCssRUTcM5niQicfWG/J37IhOSZs7Xz2nMsgmF4vWSCCHuQIKPAzJY7LwdX+CFhf/whz/s7e0NWpNBZ5Tnlo5M6EVcEZvBihSFKyNi9GbjZAEMw1TK2B2bttK8OI1Fn9z7wePytm3eKhJ+YkfHlWstzVev+HzBt8TNjtPp3LlzJ53J7L/SQBL+uSvcntIvfXPjI9/O2lzZc+k9v9czeT0mLUeakDx0vdXY1wMA6+5/rOSL3+AIRIMdHy1GLoAwUhafX4wBJKxaFxYde+XNkwPXmqYWMI8OylMyZStSCa83ZZ0aKOrCS793mk1Ty5B+nzw5U6JQEV5v0pqN47q+s0cOf1ZCTDZXtbKIKxKzuLz4vCLNpXPNb56YrzHLJhSK10sihLjTuO04oDwlUxqfrNPpZkl3KuYKB8dHwngiuUTOoNH8pL9d2zW1AIvB5DO5tkELU4AzeEygKDqbEbQpDIMNGzb0Dw+8U/Ouw+GYrxs1NTU6nU4ZnyxPyRxobZ5v9alExie57TY2X5Cprmh+47ZDOSRBkISfJInFaE0yMayLW1nkdTmshuELL/5u5mCWz+1y26wUSQJAf0vjh6++NLORgdbm7PJdHocdp9Gv/uPvHcEWii+bUGvNG2mlW1wWMwDUP/+boD+UOY1ZNqFQvF4SIcQdSPAV0QV3789UVxw9evTZZ5+9XU0eiwsAHp/HTxLKiJgwnqhD1018HBQwwBh0RkJs3H8eeiohLp4iKYqiaIxgc8EYxuaxxZFhhjHj95/5QcPlhgmLeZbdwUF56qmnDhw40F53uum1ha/ZTly9YcMDBzvqz6SsVZtHBt/66ZOTtwIfyIevHeuoO73g9hEIxCJRZuZt+OLXZxuDoqih69fOHvlxKK3VdGqD9wEDpx3V1tbOUtnhcU6+HhofzkvLHTbrxyy3VrRQQPkJvzRalpieyKaxvG5vIAXWNDAMY3JYwnARRsNFAtG3HvtGcV5h7du1A/pBrUHnI0J9KK6trT1w4MDkIU0LI2FVsd/n7ag9LUtMDYtW8sThDvP8FujMl9xtexJXr+cIRDQG0+tyWEaHm988YbjZPbXM+ge+Kk/OYPH4GIZ7nHb9jesfnPjT1OGwcGV8we77xXIFi8snCL/bbu1rvnTl1MlPuFawLqtsBy8snMHh+t1uh3m84723pw11LZvQkni9bEKheL0kQoiQwDAAwD5+MZP5ricJMg4oiVHlV95rtVqffPLJoHVmguO0L6mrGrubHe5/PsNSQK1cuXLLXVuEYSIGk4HTaDgGGAYYjuM4TqPRmGwmT8QXSIR0Bt3v8o1r9DQ6TRUbmx6elB2TzsDpPcO9IfozNDT0yCOPSKKiB641LXhhYOGeBy36kY73TovlClliKgA1dL01cGvaOGDB3fvv+tpTPo878BYAMtUV6x84uGrXfbnb7klZV8bkcAML01YUlZR88RsFu+/P2bI7Pr/YY7OaR4cCVdbc+0iWugIADH09Y9peoEAan6TMzu9rvjT5xdj+nWeUWfkeh83Q220eHWSyufLkDHlyxuQQO1sg2vat/5JEx1oNI/ob151mE18SochYyRNLJldsrCgqWVv1KJsvHBu4abzZ7XW5JApVbHaBc2LcNNi/zEJL4vWyCYXi9ZIIIULEahhpq3kTp9GiVqTNvGsbN5x44uGbTRdDbC34OKBEoQKApqYgg7gsBksiCJuwmT0+T2D+N1oSpTMOifnCmNgYu3v6EN7Q0LDX66WJaBwBl83jUCRJEiQFt4IajU7HaTiGgc/pHWrp9xE+tpRPo9NkGTHimHAhV9A9fKNjoGuGFcFpampSq9UShWphCwOzNley+cLui7UA0HWhJnXd5qik9BDr5lfuy9y8w2oY7WtpoDOYQqnc7/MCQOLq9cX3PmI3jd24fJ7OZCszVxbf92XT8IDVMMIWiBJWrXXZrbVHfzKmvTXXtPqeBzI2bc/fdd+Fv/wOAFLXl0fGJ49pe6c+j299/HuyFWmp68u73q8BgMJ7HuCKwjQN5y7+9Q+BAoII2dZvPh2XV/Tha8cC38CMTdsxDG98+fmAdwAQl1e04YGvpW/cqmmsX06hpfJ62YTm9HqphBCfFUEWoIhkMQDQ1tY28xaHxU5XJCdGqVYmZCXI4nLjMyMEEsDgi/seEIaLD3zpK4poBYP+z+kOl8tFkiSGAYYBTsNoDBqDzWCwmEw2k8li0ug4hgHhJQxdI5aRCZxFx2k4ANA5DF6UICJOujo9Hws5/1XA4IDxC0CZme9zuwJ7qqyGEYthWCxXhJKHlcHmJK/dZNWPvP6Db188drT++d+c+vF322reBIBMdYXP7Xr7V//V8L9/fv+l3ze/cYLJ5WdtrgQAZcZKJoc72N4y+bUBgA9ffclls4hl0YG30oRkDMMCTU1y9cyrGIZFxq0IvBVFKTwO2+T3EwBsY3pdewuTw1Nm5Qeu8CWRpsH+yWABAP0tjeO6m3xJ5DILLZXXyyY0p9dLJYT4rAjSBxREygCgp6dn5i2/3+/xe8dtE06PM4wvlvDF73c2UhRVuqGUB9zKrRXFq4v6tP3Xe7qGRoa5XO72u7byeXygAg/uH0NRgGEURQWiG+EjTH1jOJvOELAAA6CAAgrDMGG85AsP3vth/9WOrpA25AUMDhg/X9gCkUQZ57Ka8ypuzQt5XU4ag5leuuXyKy/OXjc+bw2bL+xrvjTzllAqNw32T/6Wu2wWn9spCJcCgFAmBwCLYaTi0LNh0cqJYd3pnz0FAB67jcUTBMpzhGLC7/N53Hu+/1u2QKRru3L+hd+OdLf7vR6OKCxQhsXjue223G170jaUA4Zfrz9z9cyrZv0QAITJFQDAYHOYbI7TMlH6pW8qMlZ6nPb3Xzoyqul0mici45PZApHbZlk2oSXxetmEQvF6qYQQnxXBImC4FAC02iDPkk6P63J3M0GSJEV6/F6nx+32eQCg+4OOtqFOVXLCuqLiNQVFq1bmE34Cx3Emk2nXW3wmN1fCp7PogGE4HSP9BE6n+VxeigS73uq2OAmfz2vxskRsBp/lGLYKYkV0DhOn417Ce+PmjRA9CRgcMH6+ZJXtYLDYjMio9I3bpl6XrZj7QTgsWgkATsvEtOsRqkQ6kyVNSCl77IlP3MAwAHDbbQAQrojjhYU3vf7Xor1fUmbl69qukIQfp99aK+5zu2g0etKaUpfNou/tVmTkBq6TBEGj3/rB+b1eJoerzMofaG2WKOMVGSuvnnnV7/EAAJ3JCjRC+H1MLk8cldz0+l/zKvYmrFo7qukkCD+GYRyhyG2zLJvQkni9bEKheL1UQojPiiA/ALZACAB6fZB0zSRFTp5k5PF5x3zjgf5aJFPyRu1p77u+438/cf/eqvVFxXweHwAoijJeH3UZ7BiG0ZgMDAcmj9XVc1Mg5HExJpvJYgvZOIcuTpVatSazZgwoABwEKnFAok/b75myLHl2AgYHjJ8v8pQsr9Nx/NCXpl7c+eRPxfIYoVRuNYzMUtfrcgIAVyyZdn1M20v4fKbB/tM//4+ZtfqvNKzadR9bIHKYxgr3fJGiSJOuf1qZiRGdKne13+flCETSuCTbuGFmOw6TUZSafbPp4orCDWyBaKgzSKpEp2VCECEd6W4vuHs/g8WeOVO0bEJL5fWyCc3p9VIJIeYF9zZ9ZwZr3ju1gowDsvkiAAglXfOtOQ0KXqg9YXFYXW7XTW3fj3/9k8f+/evvvFfjcDr8Th9OYkABRsO9To/b4jIOjz3/xitHThzXG8YooMLSZMKEMDqXIUqMYIdxSYIEDAscnAQAVrstdE8CBgeMnxfhyvgwuWL84znESYx9GhqdkV66dfJK0H17+t5ukiTkKZkzb9lNxrCY2Ljcwpm3HOZxt80qiJB2f1BHkcSYtnfmypvBjo+Aonji8KHOa4Bhw11BRmYt+mEMx0mSsBpHSZK4ESwdk2NinCsM63r/rNflcNss7bVvfVZCS+X1sgnN6fVSCSHmhSzYRDAAsHn83G175tXU9D4gTqPTGAwAcLvdITZBAXW+44NbrynK4/X29vX+8Oc/kkvlD27fv/WebQwZVxAlcgxZTd16sZC3d/s2h8eTvjadJ+VRtFtjhDQmLSwtksLBqbfpm3V2iZchYB9/ZfrGo1kIGExjBN92MgtpJXfhdPrMP++axvqk4o2BbZ7OiXEAiM1eRZLktEXRw12toz2d0alZO5/82WhPO+H3SxRxoz0drTVvtNedLtr70NqqR2NzCiz6YUGETCSTf3DiT4HdAm67VSxXFN/7iMdpb3rtrzMNM/ZpfB63LDElOiVzTNt76eR/zywzMawDgPTSrXQmS9NQH3QdgNNswnB888HvYhje/MbxmWvQlk1oqbxeNqFQvF4SIUQoMNicFYUlyWs3CSOjgpfAsKzNlbyw8N4P35+WJ+12hDQMwWFycuIzbE6bZqTPR/hSFUl8FtdgHR8cGyYpksNkS0URTo9LzBPRcPz6oIaiKD9BOK3e02fqm5s6FdFycYSYw2fTSVwVpizasprDZc/sT2E4Pu60vnOxXszl/e3yyw/ed39Pb6iDgItBlpjqdTqmZdYEAGOfxmbUi2UxYTGxHefejssriohNFETIej6om1by3d/9cOPD35IlpaWW3EX6/U6zaQQoAOj5oI7weTPLdigz8+JXFRNer21MLwiXBiKg3+vBcZrZMNT48vPTVs9OQvi8DJZwqKvt3P/8MmgBx8Q4AGAYfv38u40vPx+0jM/jDshdPfPq7Q7BWDahJfF62YRC8XpJhBChkLW5MmfL3bOXoTNZycWb5CmZrzz99VDaDLIrbv+vjtGZzKSkpMnT0MU8UWZs2pBpWMAR8FhcwEDAEdwc7ZOHRdndjhiJvN84MDox6vX5IoXhvXotANBp9F2F29anrdNZjG2abrvDwefxKRqFAQYYJhYLv/zYfTw+FwAIggAA0u23DZgtw+Y/nXpFbx4fsfV7KIdrPivmORyORqPxe73HvrU/9FoIBOJfhbwdX5gzAgawjRtCiYDBd8W57Ra+JFIkEgUiIIZhXr+3TdvpI/wDxiEcwwUcPo7jE3az1jBIARUbqRi3ToxZJwDA6rqV6V4eJtuQXRwtkSpk0tWJaeMWy5jFzIrkuq1unoRPY9Id3RNevsND+j648pFSFBkjiqAIkoHT0lSJ4zZzOEfWPxHqWugAIpEoYPy8aiEQiH8VWt76W/f7n9iqm1VemVayxT5ufPuX35t6nQg5R1SwCGiz8iWRMplsdHQUACiKcnpcALe6YwQQJvvE5GsAqPnoPZf3E4OGDBojOy5j3GSz273x0dFMBjM6WhYVGY4z6DQ5nUbHSYIk/CRh99Hp2Nq0bMLlB5ICDAOKSlclfNjV6ifYAlaY2T0WohsAIJPJAsaHXgWBQPxrMW2iKZDRhwJqwVv4g0xuBmbrVSpViE1MC38AECkKX5dW1Nnfe+1Gl8ftZQvY/AgBjUGnCNI1YbcbrWaD2WQw2SfsLpPDPeH0ON2EnwCKAoBwkYjL5mCASbhSHJtHztSAwWipAQKBCJ0gfUCbUQ8AyckLzLPCpDPyE3NVUkUYX+Lxer0+H0mRkSlyl9XlmXAAgM/vr7/aPDRmyEtOV0RIO7W941bL6tRMeXgEBsCg0fKS0t776DILuAJmmMUTamgPGBwwHoFAIEIhSAS06IcAICsra2EthvHFG7PWEQTJpNFrWxspitrF2eSt66Azb2kNj49d6rhKUuSIySgLCx80jpIUhWP49qJ1NBwHgBRF3IXWK36CCOfJbN4JkgopV2DA4IDxCAQCEQpBHjNNg1oAKChYyLEbTDojPzHHanfXtlwes5jj5THFWbksFhMoivARgQXUfoKgKBIA3F6PVj9MfJwMdTIPlkQoDBMIAYCOM1m0UBd5BwwOGI9AIBChEKQPaBrSGm72SBOSCwsLZzkmKSh8Dn9LXpnT5fMTpIjPj4uSs8VceYbSMmSyjVoCiQ9iIiJlkshR0z9PFOGzuamxcXTarXBMw/GcxKTrgx02j8VLhLQrrrCwUCgUGm72LCw1VlhMbP6Oe6NTs9rOnvroH39XZuZllu0Qy5VMLtfv8Yxpe8//5XfTzn5Vf+XfY3P++UfCbbOc/O5XAq+T1mzMVFfwwsJxOt1pNl098+qNxvMLsAqBQHzaBF8RbejrkSYkl5WVzSsCMmj0NamrpKIIUkDFRESyGEwMA9JHep0eu9E2uYmOxWRWFpe+dal+dGIMAPgcblleUVxU9NSmkhQqi3fM6XUGFZpJWVlZwOzQrZ1kw4Nfi81e5bSYJrPO0ugMj8P+0emX7SZDTHpuYsG6dVWP1v7hp1Nr0RgM05D2zR89Ma211PWbC+7eP9LT0XHubZ/LGZORa9EPL8AqBAIxJzevXFJkrNS2LvxEquARUH/jeqa6oqKiYpZzQmZCAVgdtjZtpzIiRsgVBOKJz+UdadNRJPVxEcAAosMj9paWX77ebjCbSnNXRYdHMj+ZJCNcIE6OTrjW3xFijuiKioqA2aFbO5VrZ15rqz11/y/+Enjbf/Vy/9VboX+w46owMmpm4gOcziD9QdYcJa8tM/Zpao/+JPC2r6VhYSYhEIg5MfZpXv3+44tpIXgEHOluN/T1KOOTy8vLZzkubhoE4W/sbr7a185hsiWCsCR5YnJMYmykIlIczqQxPg6CAAA4hkkEorK8Qh/h57BYOIYBAIWBw+WwOGy6saE+vVZvNoYY/srLy5VKpaGvZ6S7PURTp3Lhxedud0uZla/MzItQrei+eBYAssp35my5+/r5d668eZLGYBDBzvYMi1E2nPyfBZiBQCCWn+AR0Odx69papPHJVVVVoUdACsBH+H0uu81lN1rHe0f661rP8zi8Xz7zU5lCSbgJiqT8Lp/f7QMKAmlTMQxoLDqdy8RomMVp++mvnuu5qfETfh/h94e8qruqqgoAdG0tge2iS8WO/3c4IjYBAAx9PYHTEd02q8syEVh0TaMzwpTKB393gvD5bGOGjvdO32g8H5dXhGM4i8vf8/3fckUSn8fV13yp8e8vLKFVCARiCbltZoSB1qakNaVqtXoB8yEAQFGUj/D5CJ/L6/6wtVkVr2JzuXArA/Qni2K3/nXoum8O9Vud88iIBQCFhYVqtdpqHB1YxFhAUN76SbVYrojNXpW6bnPpw4+/8vTXNQ3nJk8j66w/4/d6xgf6lJl5aSV3Fezer7/RxQ+LIClyxZrSnkvv6dpbssoqU9ZvHtf1BQ6vQCAQdxq33XRhHhnsb2kEgIMHDy5GgKKoV956zWKzAhbo9GEY/sn/GAYYuNyut945bbaY59t+wLz+lsZP44Bq88hg67tvNL3+V0G4NGnNxqm3bjSe729ptI3pO+vPfHDiT2wePz5/jcUwguO0znNvt777xsTQwIUXn3NaTEFTByIQiDuB2bad9V25ZB4dVKvVlZWVi9EY0Y++9Ldj7ts/olIUdeHSxQ8+vDTfg9IrKyvVarV5dLDvSpBjOpYKt8MGFOW/vf2E30cB+D0eXdsVn9sVeHaexB9ymmsEArHMzJYf0DSk1TTUF+y+v7q6+uzZs5PJshbA66dPpSSmbFGX0+l0AKCA8nq9LCYLACiKuq7peuHEi/p/rJQAAAUuSURBVDa7fV5tcjic6upqANA01C9sGeDtWLWrSqJQjXS3m0cG5ckZyqx8m8nY19Kwoqgku3xn14WznfVn1I8eMvZrDDd7xFExaSVbnBZT4FF3uKstPr/YaZkYut6aun4zi8tH08EIxB3LHBlSNQ3npAkpqpyCZ5555tChQwuW8RP+Xx79DZvNKllbwqDTKZKaMJujpDKSJG/09f741z/r1807hD3zzDNKpVJ7rWlybG6pcFnNbH529l276SwW4fWaRwavnnkFALjCMF5YBFcs4YnDmRxupnoHo4Lj93gs+uHmN08EMhW/99+/KHvsibSSLdnluxzm8Y9Ov7ywGWoEArEMBMmQOg1FRm7R3ocFEdLq6upjx44tRozNYn3z0a/v3r7T7/d39lzPTMvQDmiffPZ7fdq++Ta1f//+w4cP28YMjS//ebAjyKk9CAQCMTs1ndq5008NdlztrD8DAIcPHy4pKVmMntvj+c0fnyMIgiRJ49iY2+0+8vwfFxD+SkpKDh8+DACd9WdQ+EMgEAsmpAR8nfVn2uveAoCjR4/m5OQsRk8oEOI47vF6hoYHcRxfEZ843xZycnKOHj0KAO11bwVCMwKBQCyM0FKQUlT72bc0DeeEQuELL7ywmCC4tnANAHR0dXZpuul0elFBIYfNDr16Tk7OCy+8IBQKNQ3n2s++BaFtGkEgEIighJqE2WWzXHvn9d7LF6RS6cmTJxfwOMxiMpUxyrsrdlEUdfrdt691tE2YzcoY5arcfB6XF/Qo3mmUlJScPHlSKpX2Xr5w7Z3XZ56TjUAgEPOCtrMgI8SiXqfDNDTAYLOjV6Tec889RqOxtbU1lIpMJrNo1epd23fuu/sLSYkrRg36o3/5o8vtjlOq0pJS8nJWxilVIqHYOG6c5XC4/fv3HzlyhMViaRrOXT3zmm0M5YJGIBCLotdomUcEBACv02Hs0wAG0oSUsrIyuVx+8eJFf7AUKVNhs9n377kvXhXvdruaWq688L8v9Wn7SZLs6ulyezwMOiNcIomSRfUP9OuNQU754HA4hw8ffvzxxwGgve6ta2+/uuBTURAIBGKSXqNl7tUwQcCw9NKt6aVbBRFSnU53+PDhU6emHzc+FTqdLuQLGEym3+93u1wOl/PjZjAGg8HjcJlMJklRNpvV7Zm+faKysrK6ulqpVNrGDJ31Zzrrz6CxPwQCsSTUdGoXFAEBAECRkZu8tkyVUwAAdXV1R44cWUAChVkoLCw8ePCgWq0GAO21pp4PatHCFwQCsYQsKgICAIvHT1qzMWlNqThKAQB1dXXHjx8PPZvW7SgvL6+qqgrEPvPooKahXtNwzuOY3545BAKBmJ3FRsAAkhhVfH5xXF6RMDIKAHQ63enTp2tra+fbJSwsLCwrK6uoqFAqlQBgNY72tzT2Xbm0tHt+EQgEIsDSRMAAYrkiNrtAmZUnjb910LDVam1qampra+vp6dFqtXq93mKxuN1uAGCz2SKRSCaTqVSq5OTkrKysgoICoVAYqGjo69G1tQy0Nn0aCa8QCAQiwFJGwAAMFluekilbkSaNT5YmzO/MdcPNHkNfj/7G9ZHu9qXN9oxAIBAzqenUzpEbZr74PO6B1uZATnlJjEqiUIlkMYJImSBcyhYI2XwRjcEAAMLnc9stbpvVNm6wGfUW/ZBpUIuedhEIxDKzxBFwKqahIEENp9EBgAz5DBAEAoH49PgUI2BQUOxDIBB3DqHuC0YgEIj//0AREIFAfH5BERCBQHx+QREQgUB8fvk/oU/HigH/qfEAAAAASUVORK5CYII="},6561:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a02b4022.90907439.js b/build-staging/assets/js/a02b4022.90907439.js new file mode 100644 index 00000000..24ed2b43 --- /dev/null +++ b/build-staging/assets/js/a02b4022.90907439.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3492],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(a),u=r,d=m["".concat(s,".").concat(u)]||m[u]||h[u]||i;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:r,o[1]=l;for(var p=2;p<i;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},4889:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"June 16, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"release",permalink:"/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/blog/cwtch-nightly-v.11-74"}},s={authorsImageUrls:[void 0]},p=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},m="wrapper";function h(e){let{components:t,...i}=e;return(0,r.kt)(m,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(159).Z,width:"1004",height:"480"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(8173).Z},(0,r.kt)("img",{src:a(5726).Z,width:"1388",height:"828"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.12")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Profile Attributes")," - profiles can now be augmented with ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"additional public information")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Availability Status")," - you can now notify contacts that you ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/availability-status"},"are ",(0,r.kt)("strong",{parentName:"a"},"away")," or ",(0,r.kt)("strong",{parentName:"a"},"busy"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Five New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Japanese"),", ",(0,r.kt)("strong",{parentName:"li"},"Korean"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili")," and ",(0,r.kt)("strong",{parentName:"li"},"Swedish")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Support for Tails")," - adds an ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/platforms/tails"},"OnionGrater")," configuration and a new ",(0,r.kt)("inlineCode",{parentName:"li"},"CWTCH_TAILS")," environment variable that enables special Tor behaviour."))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Based on Flutter 3.10"),(0,r.kt)("li",{parentName:"ul"},"Inter is now the main UI font"),(0,r.kt)("li",{parentName:"ul"},"New Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"New Network Management code to better manage Tor on unstable networks"),(0,r.kt)("li",{parentName:"ul"},"File Sharing Experiment Fixes",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Fix performance issues for file bubble"),(0,r.kt)("li",{parentName:"ul"},"Allow restarting of file shares that have timed out"),(0,r.kt)("li",{parentName:"ul"},"Fix NPE in FileBubble caused by deleting the underlying file"),(0,r.kt)("li",{parentName:"ul"},"Move from RetVal to UpdateConversationAttributes to minimze UI thread issues"))),(0,r.kt)("li",{parentName:"ul"},"Updates to Linux install scripts to support more distributions"),(0,r.kt)("li",{parentName:"ul"},"Add a Retry Peer connection to prioritize connection attempts for certain conversations"),(0,r.kt)("li",{parentName:"ul"},"Updates to ",(0,r.kt)("inlineCode",{parentName:"li"},"_FlDartProject")," to allow custom setting of Flutter asset paths"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili"),", ",(0,r.kt)("strong",{parentName:"li"},"Swedish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Japanese")," (29%), ",(0,r.kt)("strong",{parentName:"li"},"Korean")," (23%), ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.12 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"libCwtch-autobindings-2023-06-13-10-50-v0.0.5"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},8173:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},159:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"},5726:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a08943ae.a0db67c9.js b/build-staging/assets/js/a08943ae.a0db67c9.js new file mode 100644 index 00000000..a0a10703 --- /dev/null +++ b/build-staging/assets/js/a08943ae.a0db67c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1800],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},l=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,s=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(n),h=r,d=u["".concat(s,".").concat(h)]||u[h]||g[h]||o;return n?a.createElement(d,c(c({ref:t},l),{},{components:n})):a.createElement(d,c({ref:t},l))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,c=new Array(o);c[0]=h;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[u]="string"==typeof e?e:r,c[1]=i;for(var p=2;p<o;p++)c[p]=n[p];return a.createElement.apply(null,c)}return a.createElement.apply(null,n)}h.displayName="MDXCreateElement"},2661:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>g,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const o={sidebar_position:1},c="Change Language",i={unversionedId:"settings/appearance/change-language",id:"settings/appearance/change-language",title:"Change Language",description:"Thanks to the help of volunteers, the Cwtch app has been translated to many languages.",source:"@site/docs/settings/appearance/change-language.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/change-language",permalink:"/docs/settings/appearance/change-language",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/change-language.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Appearance",permalink:"/docs/category/appearance"},next:{title:"Light/Dark and themes Breakdown",permalink:"/docs/settings/appearance/light-dark-mode"}},s={},p=[],l={toc:p},u="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,a.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"change-language"},"Change Language"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"Thanks to the help of volunteers"),", the Cwtch app has been translated to many languages. "),(0,r.kt)("p",null,"To change the language Cwtch uses:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Open Settings"),(0,r.kt)("li",{parentName:"ol"},'The top setting is "Language", you can use the drop down to select the language that you wish to use.')))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a19b8c23.380ff2ab.js b/build-staging/assets/js/a19b8c23.380ff2ab.js new file mode 100644 index 00000000..ac6e5c9d --- /dev/null +++ b/build-staging/assets/js/a19b8c23.380ff2ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6435],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),l=p(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[l]="string"==typeof e?e:o,s[1]=a;for(var p=2;p<i;p++)s[p]=r[p];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},5487:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Servers Introduction",a={unversionedId:"servers/introduction",id:"servers/introduction",title:"Servers Introduction",description:"This feature requires Experiments Enabled and",source:"@site/docs/servers/introduction.md",sourceDirName:"servers",slug:"/servers/introduction",permalink:"/docs/servers/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Servers",permalink:"/docs/category/servers"},next:{title:"How to create a server",permalink:"/docs/servers/create-server"}},c={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"servers-introduction"},"Servers Introduction"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," turned on.")),(0,o.kt)("p",null,"Cwtch contact to contact chat is fully peer to peer, which means if one peer is offline, you cannot chat, and there is no mechanism for multiple people to chat."),(0,o.kt)("p",null,"To support group chat (and offline delivery) we have created untrusted Cwtch servers which can host messages for a group. The messages are encrypted with the group key, and fetch via ephemeral onions, so the server has no way to know what messages for what groups it might be holding, or who is accessing it."),(0,o.kt)("p",null,"Currently running servers in the Cwtch app is only supported on the Desktop version as mobile devices' internet conection and environment is too unstable and unsuitable to running a server."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a34f2ac7.72611369.js b/build-staging/assets/js/a34f2ac7.72611369.js new file mode 100644 index 00000000..65517c6a --- /dev/null +++ b/build-staging/assets/js/a34f2ac7.72611369.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6291],{1683:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/support","page":1,"postsPerPage":10,"totalPages":1,"totalCount":3,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a430b379.8153e8a0.js b/build-staging/assets/js/a430b379.8153e8a0.js new file mode 100644 index 00000000..0c5fa200 --- /dev/null +++ b/build-staging/assets/js/a430b379.8153e8a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1367],{8595:e=>{e.exports=JSON.parse('{"label":"repliqate","permalink":"/blog/tags/repliqate","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a65a3c47.bfeca907.js b/build-staging/assets/js/a65a3c47.bfeca907.js new file mode 100644 index 00000000..97db4493 --- /dev/null +++ b/build-staging/assets/js/a65a3c47.bfeca907.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7591],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var o=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,o)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,o,n=function(e,t){if(null==e)return{};var a,o,n={},r=Object.keys(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=o.createContext({}),p=function(e){var t=o.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return o.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(a),u=n,m=h["".concat(c,".").concat(u)]||h[u]||d[u]||r;return a?o.createElement(m,i(i({ref:t},s),{},{components:a})):o.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var p=2;p<r;p++)i[p]=a[p];return o.createElement.apply(null,i)}return o.createElement.apply(null,a)}u.displayName="MDXCreateElement"},5432:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=a(7462),n=(a(7294),a(3905));const r={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"April 28, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/blog/availability-status-profile-attributes"}},c={authorsImageUrls:[void 0]},p=[{value:"Cwtch Development Handbook",id:"cwtch-development-handbook",level:2},{value:"Release and Packaging Process",id:"release-and-packaging-process",level:3},{value:"Cwtch Application Development and Cwtchbot v0.1.0!",id:"cwtch-application-development-and-cwtchbot-v010",level:3},{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(h,(0,o.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(3466).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"cwtch-development-handbook"},"Cwtch Development Handbook"),(0,n.kt)("p",null,"We have created a new documentation section, ",(0,n.kt)("a",{parentName:"p",href:"/developing/intro"},"the developers handbook"),". This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients)."),(0,n.kt)("h3",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"The new handbook features a breakdown of ",(0,n.kt)("a",{parentName:"p",href:"/developing/release"},"Cwtch release processes")," - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created."),(0,n.kt)("h3",{id:"cwtch-application-development-and-cwtchbot-v010"},"Cwtch Application Development and Cwtchbot v0.1.0!"),(0,n.kt)("p",null,"For the first time ever we now have ",(0,n.kt)("a",{parentName:"p",href:"/developing/category/building-a-cwtch-app"},"comprehensive documentation on how to build a Cwtch Application"),". This section of the development handbook covers everything from ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"choosing a Cwtch library"),", to ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot"},"building your first application"),"."),(0,n.kt)("p",null,"Together with this new documentation we have also ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"released version 0.1 of the Cwtchbot framework"),", updating calls to use the ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-api-design"},"new Cwtch Stable API"),"."),(0,n.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,n.kt)("p",null,"There is a ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,n.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/"},"2023-04-26-20-57-v1.11.0-33-gb4371"),"."),(0,n.kt)("p",null,"This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"in-development Tails support"),". "),(0,n.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,n.kt)("p",null,"Please see the contribution documentation for advice on ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,n.kt)("p",null,"Subscribe to our ",(0,n.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,n.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,n.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3466:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a6882456.7303ae16.js b/build-staging/assets/js/a6882456.7303ae16.js new file mode 100644 index 00000000..e36056e1 --- /dev/null +++ b/build-staging/assets/js/a6882456.7303ae16.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4415],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>b});var o=n(7294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function c(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}function a(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?c(Object(n),!0).forEach((function(e){r(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function i(t,e){if(null==t)return{};var n,o,r=function(t,e){if(null==t)return{};var n,o,r={},c=Object.keys(t);for(o=0;o<c.length;o++)n=c[o],e.indexOf(n)>=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(t);for(o=0;o<c.length;o++)n=c[o],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var l=o.createContext({}),p=function(t){var e=o.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},s=function(t){var e=p(t.components);return o.createElement(l.Provider,{value:e},t.children)},u="mdxType",m={inlineCode:"code",wrapper:function(t){var e=t.children;return o.createElement(o.Fragment,{},e)}},d=o.forwardRef((function(t,e){var n=t.components,r=t.mdxType,c=t.originalType,l=t.parentName,s=i(t,["components","mdxType","originalType","parentName"]),u=p(n),d=r,b=u["".concat(l,".").concat(d)]||u[d]||m[d]||c;return n?o.createElement(b,a(a({ref:e},s),{},{components:n})):o.createElement(b,a({ref:e},s))}));function b(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var c=n.length,a=new Array(c);a[0]=d;var i={};for(var l in e)hasOwnProperty.call(e,l)&&(i[l]=e[l]);i.originalType=t,i[u]="string"==typeof t?t:r,a[1]=i;for(var p=2;p<c;p++)a[p]=n[p];return o.createElement.apply(null,a)}return o.createElement.apply(null,n)}d.displayName="MDXCreateElement"},5937:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>i,toc:()=>p});var o=n(7462),r=(n(7294),n(3905));const c={sidebar_position:8},a="Unblocking a Contact",i={unversionedId:"chat/unblock-contact",id:"chat/unblock-contact",title:"Unblocking a Contact",description:"1. Select the contact in your Conversation list. Blocked contacts are moved to the bottom of the list.",source:"@site/docs/chat/unblock-contact.md",sourceDirName:"chat",slug:"/chat/unblock-contact",permalink:"/docs/chat/unblock-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/unblock-contact.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"Blocking a Contact",permalink:"/docs/chat/block-contact"},next:{title:"Removing a Conversation",permalink:"/docs/chat/delete-contact"}},l={},p=[],s={toc:p},u="wrapper";function m(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,o.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"unblocking-a-contact"},"Unblocking a Contact"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Select the contact in your Conversation list. Blocked contacts are moved to the bottom of the list."),(0,r.kt)("li",{parentName:"ol"},"Go to Conversation Settings"),(0,r.kt)("li",{parentName:"ol"},"Scroll down to Block Contact"),(0,r.kt)("li",{parentName:"ol"},"Move the switch to Unblock Contact")),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help\nby ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a6aa9e1f.4532b4f8.js b/build-staging/assets/js/a6aa9e1f.4532b4f8.js new file mode 100644 index 00000000..876527bb --- /dev/null +++ b/build-staging/assets/js/a6aa9e1f.4532b4f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3089],{46:(e,t,a)=>{a.r(t),a.d(t,{default:()=>u});var n=a(7294),r=a(6010),l=a(2263),i=a(1944),o=a(5281),s=a(9058),m=a(9703),c=a(197),g=a(9985);function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,l.Z)(),{blogDescription:r,blogTitle:o,permalink:s}=t,m="/"===s?a:o;return n.createElement(n.Fragment,null,n.createElement(i.d,{title:m,description:r}),n.createElement(c.Z,{tag:"blog_posts_list"}))}function d(e){const{metadata:t,items:a,sidebar:r}=e;return n.createElement(s.Z,{sidebar:r},n.createElement(g.Z,{items:a}),n.createElement(m.Z,{metadata:t}))}function u(e){return n.createElement(i.FG,{className:(0,r.Z)(o.k.wrapper.blogPages,o.k.page.blogListPage)},n.createElement(p,e),n.createElement(d,e))}},9703:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(5999),l=a(2244);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,r.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(l.Z,{permalink:a,title:n.createElement(r.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),i&&n.createElement(l.Z,{permalink:i,title:n.createElement(r.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(9460),l=a(1286);function i(e){let{items:t,component:a=l.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(r.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a6fe627e.b2883d9a.js b/build-staging/assets/js/a6fe627e.b2883d9a.js new file mode 100644 index 00000000..66965eda --- /dev/null +++ b/build-staging/assets/js/a6fe627e.b2883d9a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9239],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var a=n.createContext({}),c=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(a.Provider,{value:t},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=c(r),d=o,f=l["".concat(a,".").concat(d)]||l[d]||m[d]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var p={};for(var a in t)hasOwnProperty.call(t,a)&&(p[a]=t[a]);p.originalType=e,p[l]="string"==typeof e?e:o,s[1]=p;for(var c=2;c<i;c++)s[c]=r[c];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},2577:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Groups Experiment",p={unversionedId:"settings/experiments/group-experiment",id:"settings/experiments/group-experiment",title:"Groups Experiment",description:"Enables Cwtch to connect to untrusted servers and use them to host private, asynchronous, groups.",source:"@site/docs/settings/experiments/group-experiment.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/group-experiment",permalink:"/docs/settings/experiments/group-experiment",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/group-experiment.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Experiments",permalink:"/docs/category/experiments"},next:{title:"Server Hosting",permalink:"/docs/settings/experiments/server-hosting"}},a={},c=[{value:"To Turn On",id:"to-turn-on",level:2}],u={toc:c},l="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"groups-experiment"},"Groups Experiment"),(0,o.kt)("p",null,"Enables Cwtch to ",(0,o.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},"connect to untrusted servers")," and use them to ",(0,o.kt)("a",{parentName:"p",href:"/docs/groups/introduction"},"host private, asynchronous, groups"),"."),(0,o.kt)("h2",{id:"to-turn-on"},"To Turn On"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to Settings"),(0,o.kt)("li",{parentName:"ol"},"Enable Experiments"),(0,o.kt)("li",{parentName:"ol"},"Enable the Group experiment")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a7023ddc.b24ccc70.js b/build-staging/assets/js/a7023ddc.b24ccc70.js new file mode 100644 index 00000000..38952ed3 --- /dev/null +++ b/build-staging/assets/js/a7023ddc.b24ccc70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1713],{3457:l=>{l.exports=JSON.parse('[{"label":"cwtch","permalink":"/blog/tags/cwtch","count":17},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable","count":17},{"label":"planning","permalink":"/blog/tags/planning","count":4},{"label":"release","permalink":"/blog/tags/release","count":2},{"label":"developer-documentation","permalink":"/blog/tags/developer-documentation","count":2},{"label":"nightly","permalink":"/blog/tags/nightly","count":1},{"label":"documentation","permalink":"/blog/tags/documentation","count":1},{"label":"security-handbook","permalink":"/blog/tags/security-handbook","count":1},{"label":"bindings","permalink":"/blog/tags/bindings","count":4},{"label":"autobindings","permalink":"/blog/tags/autobindings","count":2},{"label":"libcwtch","permalink":"/blog/tags/libcwtch","count":2},{"label":"support","permalink":"/blog/tags/support","count":3},{"label":"testing","permalink":"/blog/tags/testing","count":2},{"label":"reproducible-builds","permalink":"/blog/tags/reproducible-builds","count":2},{"label":"repliqate","permalink":"/blog/tags/repliqate","count":2},{"label":"api","permalink":"/blog/tags/api","count":1}]')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a79c88c2.e76d7c3e.js b/build-staging/assets/js/a79c88c2.e76d7c3e.js new file mode 100644 index 00000000..4adeed16 --- /dev/null +++ b/build-staging/assets/js/a79c88c2.e76d7c3e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9976],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),u=r,m=h["".concat(c,".").concat(u)]||h[u]||g[u]||i;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,o[1]=l;for(var s=2;s<i;s++)o[s]=a[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},8553:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"January 13, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"},{label:"api",permalink:"/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/blog/path-to-cwtch-stable"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...i}=e;return(0,r.kt)(h,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,r.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,r.kt)("p",null,"As we move out of Beta and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,r.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(4867).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},4867:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a8c7fdc6.649793e5.js b/build-staging/assets/js/a8c7fdc6.649793e5.js new file mode 100644 index 00000000..bfc808d8 --- /dev/null +++ b/build-staging/assets/js/a8c7fdc6.649793e5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1602],{6454:e=>{e.exports=JSON.parse('{"pluginId":"docs-security","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Cwtch Security Handbook","href":"/security/intro","docId":"intro"},{"type":"link","label":"Risk Model","href":"/security/risk","docId":"risk"},{"type":"category","label":"Cwtch Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cwtch Technical Basics","href":"/security/components/intro","docId":"components/intro"},{"type":"link","label":"Component Ecosystem Overview","href":"/security/components/ecosystem-overview","docId":"components/ecosystem-overview"},{"type":"category","label":"Connectivity & Tor","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Connectivity","href":"/security/components/connectivity/intro","docId":"components/connectivity/intro"}],"href":"/security/category/connectivity--tor"},{"type":"category","label":"Tapir","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Packet Format","href":"/security/components/tapir/packet_format","docId":"components/tapir/packet_format"},{"type":"link","label":"Authentication Protocol","href":"/security/components/tapir/authentication_protocol","docId":"components/tapir/authentication_protocol"}],"href":"/security/category/tapir"},{"type":"category","label":"Cwtch","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Message Formats","href":"/security/components/cwtch/message_formats","docId":"components/cwtch/message_formats"},{"type":"link","label":"Key Bundles","href":"/security/components/cwtch/key_bundles","docId":"components/cwtch/key_bundles"},{"type":"link","label":"Groups","href":"/security/components/cwtch/groups","docId":"components/cwtch/groups"},{"type":"link","label":"Cwtch Server","href":"/security/components/cwtch/server","docId":"components/cwtch/server"}],"href":"/security/category/cwtch"},{"type":"category","label":"Cwtch UI","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Android Service","href":"/security/components/ui/android","docId":"components/ui/android"},{"type":"link","label":"Image Previews","href":"/security/components/ui/image_previews","docId":"components/ui/image_previews"},{"type":"link","label":"Input","href":"/security/components/ui/input","docId":"components/ui/input"},{"type":"link","label":"Message Overlays","href":"/security/components/ui/overlays","docId":"components/ui/overlays"}],"href":"/security/category/cwtch-ui"}],"href":"/security/category/cwtch-components"},{"type":"link","label":"Deployment","href":"/security/deployment","docId":"deployment"},{"type":"link","label":"Development","href":"/security/development","docId":"development"},{"type":"link","label":"References","href":"/security/references","docId":"references"}]},"docs":{"components/connectivity/intro":{"id":"components/connectivity/intro","title":"Connectivity","description":"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.","sidebar":"tutorialSidebar"},"components/cwtch/groups":{"id":"components/cwtch/groups","title":"Groups","description":"For the most part the Cwtch risk model for groups is split into two distinct","sidebar":"tutorialSidebar"},"components/cwtch/key_bundles":{"id":"components/cwtch/key_bundles","title":"Key Bundles","description":"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary","sidebar":"tutorialSidebar"},"components/cwtch/message_formats":{"id":"components/cwtch/message_formats","title":"Message Formats","description":"Peer to Peer Messages","sidebar":"tutorialSidebar"},"components/cwtch/server":{"id":"components/cwtch/server","title":"Cwtch Server","description":"The goal of the Cwtch protocol is to enable group communication through","sidebar":"tutorialSidebar"},"components/ecosystem-overview":{"id":"components/ecosystem-overview","title":"Component Ecosystem Overview","description":"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of","sidebar":"tutorialSidebar"},"components/intro":{"id":"components/intro","title":"Cwtch Technical Basics","description":"This page presents a brief technical overview of the Cwtch protocol.","sidebar":"tutorialSidebar"},"components/tapir/authentication_protocol":{"id":"components/tapir/authentication_protocol","title":"Authentication Protocol","description":"Each peer, given an open connection $C$:","sidebar":"tutorialSidebar"},"components/tapir/packet_format":{"id":"components/tapir/packet_format","title":"Packet Format","description":"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message,","sidebar":"tutorialSidebar"},"components/ui/android":{"id":"components/ui/android","title":"Android Service","description":"Adapted from Integrating FFI processes with Android services","sidebar":"tutorialSidebar"},"components/ui/image_previews":{"id":"components/ui/image_previews","title":"Image Previews","description":"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.","sidebar":"tutorialSidebar"},"components/ui/input":{"id":"components/ui/input","title":"Input","description":"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices","sidebar":"tutorialSidebar"},"components/ui/overlays":{"id":"components/ui/overlays","title":"Message Overlays","description":"Adapted from Notes on the Cwtch Chat API","sidebar":"tutorialSidebar"},"deployment":{"id":"deployment","title":"Deployment","description":"Risk: Binaries are replaced on the website with malicious ones","sidebar":"tutorialSidebar"},"development":{"id":"development","title":"Development","description":"The main process to counter malicious actors in development of Cwtch is the","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Cwtch Security Handbook","description":"Welcome to the Cwtch Secure Development Handbook! The purpose of this","sidebar":"tutorialSidebar"},"references":{"id":"references","title":"References","description":"* Atwater, Erinn, and Sarah Jamie Lewis. \\"Token Based Services-Differences from Privacy Pass.\\"","sidebar":"tutorialSidebar"},"risk":{"id":"risk","title":"Risk Model","description":"Communications metadata is known to be exploited by various adversaries to","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a9159543.799d02e8.js b/build-staging/assets/js/a9159543.799d02e8.js new file mode 100644 index 00000000..a1a97156 --- /dev/null +++ b/build-staging/assets/js/a9159543.799d02e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5941],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),u=l(r),f=i,g=u["".concat(p,".").concat(f)]||u[f]||m[f]||o;return r?n.createElement(g,s(s({ref:t},c),{},{components:r})):n.createElement(g,s({ref:t},c))}));function g(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,s=new Array(o);s[0]=f;var a={};for(var p in t)hasOwnProperty.call(t,p)&&(a[p]=t[p]);a.originalType=e,a[u]="string"==typeof e?e:i,s[1]=a;for(var l=2;l<o;l++)s[l]=r[l];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},8986:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:2},s="Server Hosting",a={unversionedId:"settings/experiments/server-hosting",id:"settings/experiments/server-hosting",title:"Server Hosting",description:"Server hosting is currently an experimental feature in Cwtch, it is not enabled by default.",source:"@site/docs/settings/experiments/server-hosting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/server-hosting",permalink:"/docs/settings/experiments/server-hosting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/server-hosting.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Groups Experiment",permalink:"/docs/settings/experiments/group-experiment"},next:{title:"File Sharing",permalink:"/docs/settings/experiments/file-sharing"}},p={},l=[],c={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"server-hosting"},"Server Hosting"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Server hosting is currently an experimental feature in Cwtch, it is not enabled by default.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Go to Settings"),(0,i.kt)("li",{parentName:"ol"},"Enable Experiments"),(0,i.kt)("li",{parentName:"ol"},"Enable the Server Hosting experiment"),(0,i.kt)("li",{parentName:"ol"},"You will probably also want to enable the Group experiment if you want to participate on a group hosted on your server")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/a9d2d00e.8d3943df.js b/build-staging/assets/js/a9d2d00e.8d3943df.js new file mode 100644 index 00000000..6b35b886 --- /dev/null +++ b/build-staging/assets/js/a9d2d00e.8d3943df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6126],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),h=o,d=u["".concat(l,".").concat(h)]||u[h]||m[h]||i;return r?n.createElement(d,a(a({ref:t},p),{},{components:r})):n.createElement(d,a({ref:t},p))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=h;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var c=2;c<i;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}h.displayName="MDXCreateElement"},1528:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:4},a="Groups",s={unversionedId:"components/cwtch/groups",id:"components/cwtch/groups",title:"Groups",description:"For the most part the Cwtch risk model for groups is split into two distinct",source:"@site/security/components/cwtch/groups.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/groups",permalink:"/security/components/cwtch/groups",draft:!1,tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Key Bundles",permalink:"/security/components/cwtch/key_bundles"},next:{title:"Cwtch Server",permalink:"/security/components/cwtch/server"}},l={},c=[{value:"Risk Overview: Key Derivation",id:"risk-overview-key-derivation",level:2},{value:"Risk: Malicious Peer Leaks Group Key and/or Conversation",id:"risk-malicious-peer-leaks-group-key-andor-conversation",level:2},{value:"Risk: Active Attacks by Group Members",id:"risk-active-attacks-by-group-members",level:2},{value:"Mitigations:",id:"mitigations",level:3}],p={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"groups"},"Groups"),(0,o.kt)("p",null,"For the most part the Cwtch risk model for groups is split into two distinct\nprofiles:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Groups made up of mutually trusted participants where peers are assumed\nhonest."),(0,o.kt)("li",{parentName:"ul"},"Groups consisting of strangers where peers are assumed to be potentially\nmalicious.")),(0,o.kt)("p",null,"Most of the mitigations described in this section relate to the latter case, but\nnaturally also impact the former. Even if assumed honest peers later turn\nmalicious there are mechanisms that can detect such malice and prevent it from\nhappening in the future."),(0,o.kt)("h2",{id:"risk-overview-key-derivation"},"Risk Overview: Key Derivation"),(0,o.kt)("p",null,"In the ideal case we would use a protocol like OTR, the limitations preventing\nus from doing so right now are:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Offline messages are not guaranteed to reach all peers, and as such any\nmetadata relating to key material might get lost. We need a key derivation\nprocess which is robust to missing messages or incomplete broadcast.\n")),(0,o.kt)("h2",{id:"risk-malicious-peer-leaks-group-key-andor-conversation"},"Risk: Malicious Peer Leaks Group Key and/or Conversation"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated (but impossible to mitigate fully)")),(0,o.kt)("p",null,"Whether dealing with trusted smaller groups or partially-public larger groups\nthere is ",(0,o.kt)("em",{parentName:"p"},"always")," the possibility that a malicious actor will leak group\nmessages."),(0,o.kt)("p",null,"We plan to make it easy for peers to ",(0,o.kt)("a",{parentName:"p",href:"#fork"},"fork")," groups to mitigate the\nsame key being used to encrypt lots of sensitive information and provide\nsome level of forward secrecy for past group conversations."),(0,o.kt)("h2",{id:"risk-active-attacks-by-group-members"},"Risk: Active Attacks by Group Members"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")),(0,o.kt)("p",null,"Group members, who have access to the key material of the group, can conspire\nwith a server or other group members to break transcript consistency."),(0,o.kt)("p",null,"While we cannot directly prevent censorship given this kind of active\ncollusion, we have a number of mechanisms in place that should reveal the\npresence of censorship to honest members of the group. "),(0,o.kt)("h3",{id:"mitigations"},"Mitigations:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Because each message is signed by the peers public key, it should not be\npossible (within the cryptographic assumptions of the underlying cryptography)\nfor one group member to imitate another."),(0,o.kt)("li",{parentName:"ul"},"Each message contains a unique identifier derived from the contents and the\nprevious message hash - making it impossible for collaborators to include\nmessages from non-colluding members without revealing an implicit message\nchain (which if they were attempting to censor other messages would\nreveal such censorship)\n")),(0,o.kt)("p",null,"Finally: We are actively working on adding non-repudiation to Cwtch servers such\nthat they themselves are restricted in what they can censor efficiently."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ac6c2a1e.de6fd122.js b/build-staging/assets/js/ac6c2a1e.de6fd122.js new file mode 100644 index 00000000..9b5e629d --- /dev/null +++ b/build-staging/assets/js/ac6c2a1e.de6fd122.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8639],{6086:s=>{s.exports=JSON.parse('{"label":"support","permalink":"/blog/tags/support","allTagsPath":"/blog/tags","count":3}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/acb99df2.6a426454.js b/build-staging/assets/js/acb99df2.6a426454.js new file mode 100644 index 00000000..bdc589b4 --- /dev/null +++ b/build-staging/assets/js/acb99df2.6a426454.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[10],{1892:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/cwtch-stable","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/blog/tags/cwtch-stable/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/af23c5f9.7089b1b0.js b/build-staging/assets/js/af23c5f9.7089b1b0.js new file mode 100644 index 00000000..10a5c9d9 --- /dev/null +++ b/build-staging/assets/js/af23c5f9.7089b1b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3218],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){i(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,i=function(e,t){if(null==e)return{};var a,n,i={},r=Object.keys(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),h=p(a),m=i,d=h["".concat(s,".").concat(m)]||h[m]||u[m]||r;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:i,o[1]=l;for(var p=2;p<r;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},4958:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var n=a(7462),i=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"March 31, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/blog/cwtch-nightly-1-11"}},s={authorsImageUrls:[void 0]},p=[{value:"Update on the January Roadmap",id:"update-on-the-january-roadmap",level:2},{value:"A Timeline for Cwtch Stable",id:"a-timeline-for-cwtch-stable",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},h="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(h,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,i.kt)("strong",{parentName:"p"},"Beta")," to ",(0,i.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,i.kt)("p",null,"This post ",(0,i.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,i.kt)("p",null,(0,i.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,i.kt)("h2",{id:"update-on-the-january-roadmap"},"Update on the January Roadmap"),(0,i.kt)("p",null,"Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:"),(0,i.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"finalized a feature set that defines Cwtch Stable")," and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/security/intro"},"Security and Design Documents")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"Infrastructure and ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"Support")," \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"in addition to a new development blog. \u2705"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a ",(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"style guide for documentation"),", and \u2705"),(0,i.kt)("li",{parentName:"ul"},"have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"with at least one screenshot (where applicable). \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published: ",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"Interface Specification Document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Release Process Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-platform-support"},"Support Plan document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Packaging Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a document describing the ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"Reproducible Builds Process")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)")),(0,i.kt)("p",null,"While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings"},"Cwtch Autobindings")," with ",(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings-ii"},"compile-time optional experiments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-nightly-1-11"},"Cwtch 1.11")," - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.")),(0,i.kt)("h2",{id:"a-timeline-for-cwtch-stable"},"A Timeline for Cwtch Stable"),(0,i.kt)("p",null,"Now for the big news, we plan on releasing a candidate Cwtch Stable release during ",(0,i.kt)("strong",{parentName:"p"},"Summer 2023"),". Here is our plan for getting there:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document"),(0,i.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document"),(0,i.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots."))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries"),(0,i.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"An implementation of ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information"),(0,i.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist."),(0,i.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team"),(0,i.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable."),(0,i.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,i.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,i.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,i.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,i.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,i.kt)("h2",{id:"get-involved"},"Get Involved"),(0,i.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,i.kt)("p",null,"We also also updated our guides on ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,i.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,i.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b0404c31.48ec076b.js b/build-staging/assets/js/b0404c31.48ec076b.js new file mode 100644 index 00000000..d03b0dfe --- /dev/null +++ b/build-staging/assets/js/b0404c31.48ec076b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7860],{3905:(e,t,a)=>{a.d(t,{Zo:()=>h,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){o(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,o=function(e,t){if(null==e)return{};var a,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},h=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(a),u=o,m=p["".concat(s,".").concat(u)]||p[u]||d[u]||i;return a?n.createElement(m,r(r({ref:t},h),{},{components:a})):n.createElement(m,r({ref:t},h))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=a.length,r=new Array(i);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var c=2;c<i;c++)r[c]=a[c];return n.createElement.apply(null,r)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},3478:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const i={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"January 6, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"Tenets of Cwtch Stable",id:"tenets-of-cwtch-stable",level:3},{value:"Known Problems",id:"known-problems",level:3},{value:"Plan of Action",id:"plan-of-action",level:3},{value:"Goals and Timelines",id:"goals-and-timelines",level:3},{value:"Help us get there!",id:"help-us-get-there",level:3}],h={toc:c},p="wrapper";function d(e){let{components:t,...i}=e;return(0,o.kt)(p,(0,n.Z)({},h,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,o.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,o.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h3",{id:"tenets-of-cwtch-stable"},"Tenets of Cwtch Stable"),(0,o.kt)("p",null,"It is important to state that Cwtch Stable ",(0,o.kt)("strong",{parentName:"p"},"does not mean an end to Cwtch development"),". Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Consistent Interface")," \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Universal Availability and Cohesive Support")," \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Reproducible Builds")," \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Proven Security")," \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.")),(0,o.kt)("h3",{id:"known-problems"},"Known Problems"),(0,o.kt)("p",null,"To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of a Stable API for future feature development")," \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Special functionality in libCwtch-go")," \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"libCwtch-rs partial support")," - we currently do not officially consider ",(0,o.kt)("a",{parentName:"li",href:"https://lib.rs/crates/libcwtch"},"libCwtch-rs")," when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Reproducible Pipelines")," - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of up to date, and translated, Security Documentation")," \u2013 the ",(0,o.kt)("a",{parentName:"li",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Cwtch security handbook")," is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"No Automated UI Tests")," \u2013 we put a lot of work into ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"building out a testing framework for the UI"),", but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Code Signing Provider")," \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Second-class Android Support")," - while we have put ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/27-android-improvements/"},"a lot of effort behind Android support")," across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Fuzzing")," \u2013 while ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Fuzzbot")," sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Formal Release Acceptance Process")," \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Inconsistent Cwtch Information Discovery")," \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Incomplete Documentation")," \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)")),(0,o.kt)("h3",{id:"plan-of-action"},"Plan of Action"),(0,o.kt)("p",null,"Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Interface Specification Documentation")," \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Release Process")," \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Support Document")," - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Packaging Document")," - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Reproducible Builds Document")," \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand the Cwtch Documentation Site")," \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand our Automated Testing to include UI and Fuzzing")," - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Re-evaluate all Issues across all Cwtch related repositories")," \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define a Stable Feature Set")," \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)")),(0,o.kt)("h3",{id:"goals-and-timelines"},"Goals and Timelines"),(0,o.kt)("p",null,"With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.")),(0,o.kt)("p",null,"As these documents are written, and these goals met we will be posting them here! Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, Cwtch development."),(0,o.kt)("h3",{id:"help-us-get-there"},"Help us get there!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b125d866.72e91b4f.js b/build-staging/assets/js/b125d866.72e91b4f.js new file mode 100644 index 00000000..ce83a038 --- /dev/null +++ b/build-staging/assets/js/b125d866.72e91b4f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8799],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function c(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),p=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(a),d=n,m=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return a?r.createElement(m,i(i({ref:t},s),{},{components:a})):r.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=a[p];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}d.displayName="MDXCreateElement"},1595:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"June 30, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/blog/cwtch-nightly-1-12"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b1e57def.39caf8a6.js b/build-staging/assets/js/b1e57def.39caf8a6.js new file mode 100644 index 00000000..a6191f3d --- /dev/null +++ b/build-staging/assets/js/b1e57def.39caf8a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[266],{3905:(e,n,r)=>{r.d(n,{Zo:()=>l,kt:()=>f});var t=r(7294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){a(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,t,a=function(e,n){if(null==e)return{};var r,t,a={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=t.createContext({}),s=function(e){var n=t.useContext(p),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},l=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),m=s(r),d=a,f=m["".concat(p,".").concat(d)]||m[d]||u[d]||i;return r?t.createElement(f,o(o({ref:n},l),{},{components:r})):t.createElement(f,o({ref:n},l))}));function f(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var c={};for(var p in n)hasOwnProperty.call(n,p)&&(c[p]=n[p]);c.originalType=e,c[m]="string"==typeof e?e:a,o[1]=c;for(var s=2;s<i;s++)o[s]=r[s];return t.createElement.apply(null,o)}return t.createElement.apply(null,r)}d.displayName="MDXCreateElement"},8142:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var t=r(7462),a=(r(7294),r(3905));const i={},o="References",c={unversionedId:"references",id:"references",title:"References",description:'* Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."',source:"@site/security/references.md",sourceDirName:".",slug:"/references",permalink:"/security/references",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Development",permalink:"/security/development"}},p={},s=[],l={toc:s},m="wrapper";function u(e){let{components:n,...r}=e;return(0,a.kt)(m,(0,t.Z)({},l,r,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"references"},"References"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Brooks, John. Ricochet: Anonymous instant messaging for real privacy. ",(0,a.kt)("a",{parentName:"p",href:"https://ricochet.im."},"https://ricochet.im.")," Accessed: 2018-03-10")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata\u2014New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Langley, Adam. Pond. ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/agl/pond"},"https://github.com/agl/pond"),". Accessed: 2018-05-21.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Kalysch, A., Bove, D. and M\xfcller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn\u2019t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Unger, Nik et al. \u201cSoK: secure messaging\u201d. In: Security and Privacy (SP\n), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232\u2013249 ",(0,a.kt)("a",{parentName:"p",href:"http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf"},"link")))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b273a073.90186f14.js b/build-staging/assets/js/b273a073.90186f14.js new file mode 100644 index 00000000..a3bbf897 --- /dev/null +++ b/build-staging/assets/js/b273a073.90186f14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5940],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?s(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function a(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},s=Object.keys(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),c=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=c(e.components);return n.createElement(l.Provider,{value:r},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=c(t),m=o,v=d["".concat(l,".").concat(m)]||d[m]||u[m]||s;return t?n.createElement(v,i(i({ref:r},p),{},{components:t})):n.createElement(v,i({ref:r},p))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var s=t.length,i=new Array(s);i[0]=m;var a={};for(var l in r)hasOwnProperty.call(r,l)&&(a[l]=r[l]);a.originalType=e,a[d]="string"==typeof e?e:o,i[1]=a;for(var c=2;c<s;c++)i[c]=t[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},4069:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const s={sidebar_position:4},i="How to delete server",a={unversionedId:"servers/delete-server",id:"servers/delete-server",title:"How to delete server",description:"This feature requires Experiments Enabled and",source:"@site/docs/servers/delete-server.md",sourceDirName:"servers",slug:"/servers/delete-server",permalink:"/docs/servers/delete-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/delete-server.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"How to edit a server",permalink:"/docs/servers/edit-server"},next:{title:"How to share your Server Key Bundle",permalink:"/docs/servers/share-key"}},l={},c=[],p={toc:c},d="wrapper";function u(e){let{components:r,...t}=e;return(0,o.kt)(d,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-to-delete-server"},"How to delete server"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," turned on.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to the server Icon"),(0,o.kt)("li",{parentName:"ol"},"Select the server you want to delete"),(0,o.kt)("li",{parentName:"ol"},"Press the pencil icon"),(0,o.kt)("li",{parentName:"ol"},"Scroll down and input your password"),(0,o.kt)("li",{parentName:"ol"},"Press delete"),(0,o.kt)("li",{parentName:"ol"},"Press really delete"),(0,o.kt)("li",{parentName:"ol"},"Your server is deleted")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Delete.mp4"}))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b2b675dd.eb291241.js b/build-staging/assets/js/b2b675dd.eb291241.js new file mode 100644 index 00000000..4a0f07da --- /dev/null +++ b/build-staging/assets/js/b2b675dd.eb291241.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[533],{8017:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/blog/page/2","blogDescription":"The latest updated on Cwtch development.","blogTitle":"Development Log"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b2f554cd.89cd4a2e.js b/build-staging/assets/js/b2f554cd.89cd4a2e.js new file mode 100644 index 00000000..df05da1d --- /dev/null +++ b/build-staging/assets/js/b2f554cd.89cd4a2e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"cwtch-stable-roadmap-update-june","metadata":{"permalink":"/blog/cwtch-stable-roadmap-update-june","source":"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","date":"2023-06-30T00:00:00.000Z","formattedDate":"June 30, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/blog/tags/planning"}],"readingTime":5.26,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","slug":"cwtch-stable-roadmap-update-june","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"nextItem":{"title":"Cwtch Beta 1.12","permalink":"/blog/cwtch-nightly-1-12"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the Cwtch Stable Roadmap\\n\\nBack in March we extended and updated several goals from [our January roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document \u2705 - [Release Process](https://docs.cwtch.im/developing/release/#official-releases)\\n - A Cwtch Packaging Document \u2705 - [Packaging Documentation](https://docs.cwtch.im/developing/release/)\\n - Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new [documentation style guide](/docs/contribute/documentation), and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries \u2705 - [Building a Cwtch App](https://docs.cwtch.im/developing/category/building-a-cwtch-app)\\n - Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. \\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129) \ud83d\udfe1 - currently in [active development](https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information \u2705 - released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12)\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593) \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12). We now believe these changes will be complete in Cwtch Beta 1.13.\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms) \ud83d\udfe1 - we have already launched an environment for testing [Tails](/docs/platforms/tails). Other platforms are underway.\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\n\\n## Next Steps, Refinements, Additional Work\\n\\nAs you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. \\n\\nOther work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.\\n\\nHowever, [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12) featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.\\n\\nThe work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.\\n\\nWe are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-12","metadata":{"permalink":"/blog/cwtch-nightly-1-12","source":"@site/blog/2023-06-16-cwtch-1.12.md","title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","date":"2023-06-16T00:00:00.000Z","formattedDate":"June 16, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"release","permalink":"/blog/tags/release"}],"readingTime":2.455,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","slug":"cwtch-nightly-1-12","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog13_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/blog/cwtch-stable-roadmap-update-june"},"nextItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/blog/cwtch-nightly-v.11-74"}},"content":"[Cwtch 1.12 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new features like [profile attributes](https://docs.cwtch.im/docs/profiles/profile-info), support for new platforms like [Tails](https://docs.cwtch.im/docs/platforms/tails), and multiple improvements to performance and stability.\\n\\n![](/img/devlog13.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n<figure>\\n\\n[![](/img/picnic1.12.png)](/img/picnic1.12.png)\\n\\n<figcaption>A screenshot of Cwtch 1.12</figcaption>\\n</figure>\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Profile Attributes** - profiles can now be augmented with [additional public information](https://docs.cwtch.im/docs/profiles/profile-info)\\n - **Availability Status** - you can now notify contacts that you [are **away** or **busy**](https://docs.cwtch.im/docs/profiles/availability-status)\\n - **Five New Supported Localizations**: **Japanese**, **Korean**, **Slovak**, **Swahili** and **Swedish**\\n - **Support for Tails** - adds an [OnionGrater](https://docs.cwtch.im/docs/platforms/tails) configuration and a new `CWTCH_TAILS` environment variable that enables special Tor behaviour.\\n- **Bug Fixes / Improvements:**\\n - Based on Flutter 3.10\\n - Inter is now the main UI font\\n - New Font Scaling setting\\n - New Network Management code to better manage Tor on unstable networks\\n - File Sharing Experiment Fixes\\n \\t- Fix performance issues for file bubble\\n \\t- Allow restarting of file shares that have timed out\\n \\t- Fix NPE in FileBubble caused by deleting the underlying file\\n \\t- Move from RetVal to UpdateConversationAttributes to minimze UI thread issues\\n - Updates to Linux install scripts to support more distributions\\n - Add a Retry Peer connection to prioritize connection attempts for certain conversations\\n - Updates to `_FlDartProject` to allow custom setting of Flutter asset paths\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Slovak**, **Spanish**, **Swahili**, **Swedish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Japanese** (29%), **Korean** (23%), **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n## Reproducible Bindings\\n\\nCwtch 1.12 is based on libCwtch version `libCwtch-autobindings-2023-06-13-10-50-v0.0.5`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-v.11-74","metadata":{"permalink":"/blog/cwtch-nightly-v.11-74","source":"@site/blog/2023-06-07-new-nightly.md","title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","date":"2023-06-07T00:00:00.000Z","formattedDate":"June 7, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/blog/tags/developer-documentation"}],"readingTime":1.845,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","slug":"cwtch-nightly-v.11-74","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog10_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.12","permalink":"/blog/cwtch-nightly-1-12"},"nextItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/blog/cwtch-developer-documentation"}},"content":"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog10.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-06-05-17-36-v1.11.0-74-g0406](https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/).\\n\\nThis version has a large number of improvements and bug fixes including:\\n\\n* A new Font Scaling setting\\n* Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.\\n* Updated UI font styles\\n* Dependency updates, including a new base of Flutter 3.10.\\n* A fix for stuck file downloading notifications on Android\\n* A fix for missing profile images in certain edge cases on Android\\n* Japanese, Swedish, and Swahili translation options\\n* A new retry peer connection button for prompting Cwtch to prioritize specific connections\\n* [Tails support](/docs/platforms/tails)\\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-developer-documentation","metadata":{"permalink":"/blog/cwtch-developer-documentation","source":"@site/blog/2023-04-28-developer-docs.md","title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","date":"2023-04-28T00:00:00.000Z","formattedDate":"April 28, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/blog/tags/developer-documentation"}],"readingTime":2.595,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","slug":"cwtch-developer-documentation","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/blog/cwtch-nightly-v.11-74"},"nextItem":{"title":"Availability Status and Profile Attributes","permalink":"/blog/availability-status-profile-attributes"}},"content":"One of the larger remaining goals outlined in our [Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. \\n\\nIn this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!\\n\\nWe are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog9.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Cwtch Development Handbook\\n\\nWe have created a new documentation section, [the developers handbook](/developing/intro). This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).\\n\\n### Release and Packaging Process\\n\\nThe new handbook features a breakdown of [Cwtch release processes](/developing/release) - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.\\n\\n### Cwtch Application Development and Cwtchbot v0.1.0!\\n\\nFor the first time ever we now have [comprehensive documentation on how to build a Cwtch Application](/developing/category/building-a-cwtch-app). This section of the development handbook covers everything from [choosing a Cwtch library](/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library), to [building your first application](/developing/building-a-cwtch-app/building-an-echobot).\\n\\nTogether with this new documentation we have also [released version 0.1 of the Cwtchbot framework](https://git.openprivacy.ca/sarah/cwtchbot), updating calls to use the [new Cwtch Stable API](/blog/cwtch-stable-api-design).\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-04-26-20-57-v1.11.0-33-gb4371](https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/).\\n\\nThis version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the [in-development Tails support](/docs/platforms/tails). \\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"availability-status-profile-attributes","metadata":{"permalink":"/blog/availability-status-profile-attributes","source":"@site/blog/2023-04-06-availability-and-profile-attributes.md","title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","date":"2023-04-06T00:00:00.000Z","formattedDate":"April 6, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"nightly","permalink":"/blog/tags/nightly"}],"readingTime":1.445,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","slug":"availability-status-profile-attributes","tags":["cwtch","cwtch-stable","nightly"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/blog/cwtch-developer-documentation"},"nextItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/blog/cwtch-stable-roadmap-update"}},"content":"Two new Cwtch features are now available to test in nightly: [Availability Status](/docs/profiles/availability-status) and [Profile Information](/docs/profiles/profile-info).\\n\\nAdditionally, we have also published draft guidance on [running Cwtch on Tails](/docs/platforms/tails) that we would like volunteers to test and report back on.\\n \\nThe Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like\\nours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Availability Status\\n\\nNew in this nightly is the ability to notify your conversations that you are \\"Away\\" or \\"Busy\\".\\n\\n<figure>\\n\\n[![](/img/profiles/status-tooltip-busy-set.png)](/img/profiles/status-tooltip-busy-set.png)\\n\\n<figcaption></figcaption>\\n</figure>\\n\\nRead more: [Availability Status](/docs/profiles/availability-status)\\n\\n## Profile Attributes\\n\\nAlso new is the ability to augment your profile with a few small pieces of **public** information.\\n\\n<figure>\\n\\n[![](/img/profiles/attributes-set.png)](/img/profiles/attributes-set.png)\\n\\n<figcaption></figcaption>\\n</figure>\\n\\nRead more: [Profile Information](/docs/profiles/profile-info)\\n \\n## Downloading the Nightly\\n\\n[Nightly builds](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. Download links for **2023-04-05-18-28-v1.11.0-7-g0290** are available below.\\n\\n* Windows: [https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/)\\n* Linux: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n* Mac: [https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/)\\n* Android: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-roadmap-update","metadata":{"permalink":"/blog/cwtch-stable-roadmap-update","source":"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","date":"2023-03-31T00:00:00.000Z","formattedDate":"March 31, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/blog/tags/planning"}],"readingTime":5.61,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","slug":"cwtch-stable-roadmap-update","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Availability Status and Profile Attributes","permalink":"/blog/availability-status-profile-attributes"},"nextItem":{"title":"Cwtch Beta 1.11","permalink":"/blog/cwtch-nightly-1-11"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap](/blog/path-to-cwtch-stable) we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the January Roadmap\\n\\nBack in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)\\n\\n- By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705\\n- By **1st February 2023**, the Cwtch team will have [finalized a feature set that defines Cwtch Stable](/blog/cwtch-stable-api-design) and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705\\n- By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:\\n - [Security and Design Documents](/security/intro) \u2705\\n - Infrastructure and [Support](/docs/getting-started/supported_platforms) \ud83d\udfe1\\n - in addition to a new development blog. \u2705\\n- By **31st March 2023**, the Cwtch team will have created:\\n - a [style guide for documentation](/docs/contribute/documentation), and \u2705\\n - have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1\\n - with at least one screenshot (where applicable). \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have published: \\n - a Cwtch [Interface Specification Document](/blog/cwtch-stable-api-design) \u2705\\n - a Cwtch Release Process Document \ud83d\udfe1\\n - a Cwtch [Support Plan document](/blog/cwtch-platform-support) \u2705\\n - a Cwtch Packaging Document \ud83d\udfe1\\n - a document describing the [Reproducible Builds Process](/blog/cwtch-bindings-reproducible) \u2705\\n - These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705\\n- By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c\\n- By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)\\n\\nWhile we didn\'t hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:\\n\\n* [Cwtch Autobindings](/blog/autobindings) with [compile-time optional experiments](/blog/autobindings-ii)\\n* [Cwtch 1.11](/blog/cwtch-nightly-1-11) - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements.\\n* [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.\\n\\n## A Timeline for Cwtch Stable\\n\\nNow for the big news, we plan on releasing a candidate Cwtch Stable release during **Summer 2023**. Here is our plan for getting there:\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document\\n - A Cwtch Packaging Document\\n - Completion of documentation of existing Cwtch features, including relevant screenshots.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries\\n - Automatically generated API documentation for libCwtch\\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593)\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms)\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-11","metadata":{"permalink":"/blog/cwtch-nightly-1-11","source":"@site/blog/2023-03-29-cwtch-1.11.md","title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","date":"2023-03-29T00:00:00.000Z","formattedDate":"March 29, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"release","permalink":"/blog/tags/release"}],"readingTime":2.365,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","slug":"cwtch-nightly-1-11","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog12_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/blog/cwtch-stable-roadmap-update"},"nextItem":{"title":"Updates to Cwtch Documentation","permalink":"/blog/cwtch-documentation"}},"content":"[Cwtch 1.11 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new [reproducible](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) and [automatically generated](https://docs.cwtch.im/blog/autobindings) bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.\\n\\n![](/img/devlog12.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n<figure>\\n\\n[![](/img/picnic.png)](/img/picnic.png)\\n\\n<figcaption>A screenshot of Cwtch 1.11</figcaption>\\n</figure>\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Based on new Reproducible Cwtch Stable Autobuilds** - this is the first release of cwtch based on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) in addition to our new [automatically generated](https://docs.cwtch.im/blog/autobindings)\\n - **Two New Supported Localizations**: **Slovak** and **Korean**\\n- **Bug Fixes / Improvements:**\\n - When preserving a message draft, quoted messages are now also saved\\n - Layout issues caused by pathological unicode are now prevented\\n - Improved performance of message row rendering\\n - Clickable Links: Links in replies are now selectable\\n - Clickable Links: Fixed error when highlighting certain URIs \\n - File Downloading: Fixes for file downloading and exporting on 32bit Android devices\\n - Server Hosting: Fixes for several layout issues\\n - Build pipeline now runs automated UI tests\\n - Fix issues caused by scrollbar controller overriding\\n - Initial support for the Blodeuwedd Assistant (currently compile-time disabled)\\n - Cwtch Library:\\n - [New Stable Cwtch Peer API](/blog/cwtch-stable-api-design)\\n - Ported File Downloading and Image Previews experiments into Cwtch\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Spanish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n\\n\\n## Reproducible Bindings\\n\\nCwtch 1.11 is based on libCwtch version `2023-03-16-15-07-v0.0.3-1-g50c853a`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-documentation","metadata":{"permalink":"/blog/cwtch-documentation","source":"@site/blog/2023-03-10-cwtch-documentation.md","title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","date":"2023-03-10T00:00:00.000Z","formattedDate":"March 10, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"documentation","permalink":"/blog/tags/documentation"},{"label":"security-handbook","permalink":"/blog/tags/security-handbook"}],"readingTime":2.57,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","slug":"cwtch-documentation","tags":["cwtch","cwtch-stable","documentation","security-handbook"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.11","permalink":"/blog/cwtch-nightly-1-11"},"nextItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/blog/autobindings-ii"}},"content":"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.\\n\\n![](/img/devlog9.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Cwtch Secure Development Handbook\\n \\nOne of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.\\n\\nWe have [now ported the the handbook to this documentation site](/security/intro), along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. \\n\\n## Volunteer Development\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Next Steps\\n\\nWe still have more work to do on the documentation front:\\n\\n* Ensuring all pages [implement the new documentation style guide](/docs/contribute/documentation), and include appropriate screenshots and descriptions.\\n* Expanding the security handbook to provide information on [reproducible builds](/blog/cwtch-bindings-reproducible), [the new Cwtch Stable API](/blog/cwtch-stable-api-design) and upcoming improvements around fuzz testing.\\n* Creating new documentation sections on the [libCwtch autobindings API](/blog/autobindings) and building applications on top of Cwtch.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings-ii","metadata":{"permalink":"/blog/autobindings-ii","source":"@site/blog/2023-03-03-autobindings-optional-experiments.md","title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","date":"2023-03-03T00:00:00.000Z","formattedDate":"March 3, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/blog/tags/bindings"},{"label":"autobindings","permalink":"/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/blog/tags/libcwtch"}],"readingTime":4.655,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","slug":"autobindings-ii","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Updates to Cwtch Documentation","permalink":"/blog/cwtch-documentation"},"nextItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/blog/autobindings"}},"content":"[Last time we looked at autobindings](https://docs.cwtch.im/blog/autobindings) we mentioned that one of the next steps was introducing support for **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)**. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## The Structure of an Application Experiment\\n\\nAn application-level experiment consists of:\\n\\n1. A set of top-level APIs, e.g. `CreateServer`, `LoadServer`, `DeleteServer` - these are the APIs that we want to expose to calling applications.\\n2. An encapsulating structure for the set of APIs, e.g. `ServersFunctionality` - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.\\n3. A global variable that exists at the top level of libCwtch, e.g. `var serverExperiment *servers.ServersFunctionality servers` - our single pointer to the underlying functionality.\\n4. A set of management-related APIs, e.g. `Init`, `UpdateSettings`, `OnACNEvent` - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).\\n5. Management code within `_startCwtch` and `_reconnectCwtch` that calls the management APIs on the global variable.\\n\\nFrom a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\\nof on `application` or a specific `profile`.\\n\\nMost of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.\\n\\n### New Required Management APIs\\n\\nTo achieve this weaving, we now require application-level experiments to implement an `EventHandlerInterface` interface and expose itself via an\\ninitialize constructor `Init(acn, appDir) -> EventHandlerInterface`, and `Enable(app, acn)`.\\n\\nFor now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.\\n\\nWe can then generate, and optionally include blocks of code like:\\n\\n\\t\\t<experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)\\n\\t\\teventHandler.AddModule(<experimentGlobal>)\\n\\t\\t<experimentGlobal>.Enable(application, &globalACN)\\n\\nand place them at specific points in the code. `EventHandler` has also been extended to maintain a collection of `modules` so that it can\\npass on interesting events.\\n\\n### Adding Support for Application Experiments in the Spec File\\n\\nWe have introduced a new `!` operator which can be used to gate APIs behind a configured experiment. Along with a new\\ntemplating option `exp` which will call the function on the configured experiment, and `global` to allow the setting up\\nof a global functionality within the library.\\n\\n\\t\\t# Server Hosting Experiment\\n\\t\\t!serverExperiment import \\"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\\"\\n\\t\\t!serverExperiment global serverExperiment *servers.ServersFunctionality servers\\n\\t\\t!serverExperiment exp CreateServer application password string:description bool:autostart\\n\\t\\t!serverExperiment exp SetServerAttribute application string:handle string:key string:val\\n\\t\\t!serverExperiment exp LoadServers application acn password\\n\\t\\t!serverExperiment exp LaunchServers application acn\\n\\t\\t!serverExperiment exp LaunchServer application string:handle\\n\\t\\t!serverExperiment exp StopServer application string:handle\\n\\t\\t!serverExperiment exp StopServers application\\n\\t\\t!serverExperiment exp DestroyServers\\n\\t\\t!serverExperiment exp DeleteServer application string:handle password\\n\\n### Generation-Time Inclusion\\n\\n Without any arguments provided `generate-bindings` will not generate code for any experiments.\\n\\n In order to determine what experimental code to generate, `generate-bindings` now interprets arguments as enabled compile time experiments, e.g. `generate-bindings serverExperiment` will turn on\\n generation of server hosting code, per the spec file above.\\n\\n### Cwtch UI Integration\\n\\nThe UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. `c_LoadServers` - if it doesn\'t then the UI is safe to assume the\\nfeature is not available.\\n\\n<figure>\\n\\n![](/img/dev9-host-disabled.png)\\n\\n<figcaption>A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.</figcaption>\\n</figure>\\n\\n## Nightlies & Next Steps\\n\\nWe are now publishing [nightlies](https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/) of autobinding derived libCwtch-go, along with [Repliqate scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2) for reproducibility.\\n\\nWith application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.\\n\\nHowever, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:\\n\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs).\\n * **Documentation generation**: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings","metadata":{"permalink":"/blog/autobindings","source":"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md","title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","date":"2023-02-24T00:00:00.000Z","formattedDate":"February 24, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/blog/tags/bindings"},{"label":"autobindings","permalink":"/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/blog/tags/libcwtch"}],"readingTime":4.545,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","slug":"autobindings","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/blog/autobindings-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/blog/cwtch-testing-ii"}},"content":"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to **automatically generate** these bindings: [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings).\\n\\nThis this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the [path to Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable).\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## A Brief History of Cwtch Bindings\\n\\nPrior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by [therecipe/qt](https://github.com/therecipe/qt). However, after encountering numerous\\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.\\n\\nAs part of early prototyping efforts for Flutter we built out a first version of [libCwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go), and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.\\n\\nThis approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular [experimental features](https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape) - handle settings, [duplication of logic between Cwtch and libCwtch-go](https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings), and [special behaviour in libCwtch-go that better belongs in the core Cwtch library](https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go).\\n\\nAs part of a broader effort to [refine the Cwtch API in preparation for Cwtch Stable](https://docs.cwtch.im/blog/cwtch-stable-api-design) we have taken the opportunity to fix many of these problems.\\n\\n## Cwtch Autobindings\\n\\nThe current `lib.go` file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the `BlockContact` API implementation is:\\n\\n\\t//export c_BlockContact\\n\\tfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\\n\\t\\tBlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\\n\\t}\\n\\n\\tfunc BlockContact(profileOnion string, conversationID int) {\\n\\t\\tprofile := application.GetPeer(profileOnion)\\n\\t\\tif profile != nil {\\n\\t\\t\\tprofile.BlockConversation(conversationID)\\n\\t\\t}\\n\\t}\\n\\nAll that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.\\n\\nIn the new [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings) we reduce these multiple lines to [a single one](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19):\\n\\n\\tprofile BlockConversation conversation\\n\\nDefining a `profile`-level function, called `BlockConversation` which takes in a single parameter of type `conversation`.\\n\\nUsing a similar boilerplate-reduction for the reset of `lib.go` yields [5-basic function prototypes](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format):\\n\\n* Application-level functions e.g. `CreateProfile`\\n* Profile-level functions e.g. `BlockConversation`\\n* Profile-level functions that return data e.g. `GetMessage`\\n* Experimental Profile-level feature functions e.g. `DownloadFile`\\n* Experimental Profile-level feature functions that return data e.g. `ShareFile`\\n\\nOnce aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be [described in fewer than 50 lines, including comments](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec). Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).\\n\\n## Next Steps\\n\\nCwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:\\n\\n * **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)** (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on `cwtch-server`). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don\'t support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart-side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs)\\n * **Documentation generation**: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n * **Cwtch API**: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the [Cwtch Stable API redesign](https://docs.cwtch.im/blog/cwtch-stable-api-design). In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-ii","metadata":{"permalink":"/blog/cwtch-testing-ii","source":"@site/blog/2023-02-17-cwtch-testing-ii.md","title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","date":"2023-02-17T00:00:00.000Z","formattedDate":"February 17, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"support","permalink":"/blog/tags/support"},{"label":"testing","permalink":"/blog/tags/testing"}],"readingTime":1.75,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","slug":"cwtch-testing-ii","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog7_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/blog/autobindings"},"nextItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/blog/cwtch-android-reproducibility"}},"content":"In this development log, we investigate some text-based UI bugs encountered by [Fuzzbot](https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot), add more [automated UI tests](/blog/cwtch-testing-i) to the pipeline, and announce a new release of the Cwtchbot library.\\n\\n![](/img/devlog7.png)\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Constraining Cwtch UI Fields\\n\\nFuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\\ndoesn\'t pose a safety issue, it is unsightly.\\n\\n<figure>\\n\\n[![](/img/dl7-before.png)](/img/dl7-before.png)\\n\\n<figcaption>Screenshot demonstrating how certain strings would violate the bounds of their containers.</figcaption>\\n</figure>\\n\\nThese cases were fixed by parenting impacted elements in a `Container` with `clip: hardEdge` and `decoration:BoxDecoration()` (note that both of these are required as Container widgets in Flutter cannot set clipping logic\\nwithout an associated decoration).\\n\\n<figure>\\n\\n[![](/img/dl7-after.png)](/img/dl7-after.png)\\n\\n<figcaption>Now these clipped strings are tightly constrained to their container bounds.</figcaption>\\n</figure>\\n\\nThese fixes are available in the [latest Cwtch Nightly](/docs/contribute/testing#cwtch-nightlies), and will be officially released in Cwtch 1.11.\\n\\n## More Automated UI Tests\\n\\nWe have added two new sets of automated UI tests to our pipeline:\\n\\n- *02: Global Settings* - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. ([PR: 628](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628))\\n- *04: Profile Management* - these tests check that creating, unlocking, and deleting a profile work as expected. ([PR: 632](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632))\\n\\n## New Release of Cwtchbot\\n\\n[Cwtchbot](https://git.openprivacy.ca/sarah/cwtchbot) has been updated to use the latest Cwtch 0.18.10 API.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-android-reproducibility","metadata":{"permalink":"/blog/cwtch-android-reproducibility","source":"@site/blog/2023-02-10-android-reproducibility.md","title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","date":"2023-02-10T00:00:00.000Z","formattedDate":"February 10, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/blog/tags/bindings"},{"label":"repliqate","permalink":"/blog/tags/repliqate"}],"readingTime":2.92,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","slug":"cwtch-android-reproducibility","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog6_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/blog/cwtch-testing-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing","permalink":"/blog/cwtch-testing-i"}},"content":"In this development log, we continue our previous work on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible), uncovering the final few sources of variation between our [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!\\n\\n![](/img/devlog6.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Changes Necessary for Reproducible Android Bindings\\n\\nAfter a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:\\n\\n- **Insufficient path stripping introduced by Android NDK tools** - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 [changed the binutils and default linker](https://github.com/android/ndk/wiki/Changelog-r22) to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our [long term support plan](https://docs.cwtch.im/blog/cwtch-platform-support), we will be moving towards adopting the latest NDK in the future.\\n- **Paths in DWARF entries** - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.\\n\\n<figure>\\n\\n[![](/img/aar-diff.png)](/img/aar-diff.png)\\n\\n<figcaption>Vimdiff comparing the decoded (<code>readelf --debug-dump=line</code>) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.</figcaption>\\n</figure>\\n\\n- **Go Compiler Acquisition** - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there *was* a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.\\n\\n## Repliqate Scripts\\n\\nWith those issues now fixed, Cwtch Android bindings are **officially reproducible!** The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under [cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script) in the [Cwtch Repliqate scripts repository](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/).\\n\\nThis is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-i","metadata":{"permalink":"/blog/cwtch-testing-i","source":"@site/blog/2023-02-03-cwtch-testing-i.md","title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","date":"2023-02-03T00:00:00.000Z","formattedDate":"February 3, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"support","permalink":"/blog/tags/support"},{"label":"testing","permalink":"/blog/tags/testing"}],"readingTime":4.74,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","slug":"cwtch-testing-i","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog5_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/blog/cwtch-android-reproducibility"},"nextItem":{"title":"Cwtch UI Platform Support","permalink":"/blog/cwtch-platform-support"}},"content":"We first [introduced UI tests last January](https://openprivacy.ca/discreet-log/23-cucumber-testing/). At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.\\n\\nOne of the main threads of work that needs to be complete early in the [Cwtch Stable roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.\\n\\n![](/img/devlog5.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Current Limitations of Flutter Gherkin\\n\\nThe original [flutter_gherkin](https://pub.dev/packages/flutter_gherkin) is under semi-active development; however, the latest published versions don\'t support using it with `flutter test`.\\n\\n- **Flutter Test** was originally intended to run single widget/unit tests for a Flutter project.\\n- **Flutter Drive** was originally intended to run integration tests *on a device or an emulator*.\\n\\nHowever, in recent releases these lines have become blurred. The new [integration_test](https://docs.flutter.dev/testing/integration-tests) package that comes built into newer Flutter releases has support for both `flutter drive` and `flutter test`. This was a great change because it decreases the required overhead to run larger integration tests (`flutter drive` sets up a host-controller model that requires a dedicated control channel to be setup, whereas `flutter test` can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).\\n\\nThere is thankfully code in the `flutter_gherkin` repository that supports running tests with `flutter test`, however this code currently has a few issues:\\n\\n- The test code generation produces code that doesn\'t compile without minor changes.\\n- Certain functionality like \\"take a screenshot\\" does not work on desktop.\\n\\nAdditionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:\\n\\n- Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.\\n- Certain Flutter widgets like `DropdownButton` are not compatible with built-in steps like `tap` because they internally contain multiple copies of the same widget.\\n\\nBecause of the above issues we have chosen to [fork flutter_gherkin](https://git.openprivacy.ca/openprivacy/flutter_gherkin) to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.\\n\\n## Integrating Tests into the Pipeline\\n\\nOne of the major limitations of `flutter test` is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.\\n\\nThankfully it is possible to use [Xfvb](https://en.wikipedia.org/wiki/Xvfb) to create a virtual framebuffer, and set `DISPLAY` to render to that buffer:\\n\\n export DISPLAY=:99\\n Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\\n\\nThis allows us to neutralize our main issue with `flutter test`, and efficiently run tests in our pipeline.\\n\\n## Catching Bugs!\\n\\nThis small amount of integration work has already caught its first bug.\\n\\nOnce we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. [02_save_load.feature](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature) simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.\\n\\nThe cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory `$USER_HOME/Downloads` didn\'t exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.\\n\\nAs we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!\\n\\n## Next Steps\\n\\n- **More automated tests:** We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.\\n- **More platforms:** Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across [our target platforms](https://docs.cwtch.im/docs/getting-started/supported_platforms). We expect to start this work soon; expect more news in a future Cwtch Testing update!\\n\\n- **More steps:** One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the `expect to see the message` step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. `send a file` or `set profile picture`.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-platform-support","metadata":{"permalink":"/blog/cwtch-platform-support","source":"@site/blog/2023-01-27-platform-support.md","title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","date":"2023-01-27T00:00:00.000Z","formattedDate":"January 27, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"support","permalink":"/blog/tags/support"}],"readingTime":10.535,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","slug":"cwtch-platform-support","tags":["cwtch","cwtch-stable","support"],"image":"/img/devlog4_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing","permalink":"/blog/cwtch-testing-i"},"nextItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/blog/cwtch-bindings-reproducible"}},"content":"One of the [tenets for Cwtch Stable is **Universal Availability and Cohesive Support**](https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable):\\n\\n> \\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\"\\n\\nThis development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.\\n\\nThe questions we aim to answer in this post are: \\n\\n- What systems do we currently support?\\n- How do we decide what systems are supported?\\n- How do we handle new OS versions?\\n- How does application support differ from library support?\\n- What blockers exist for systems we wish to support, but currently cannot e.g ios?\\n\\n![](/img/devlog4.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Constraints on support\\n\\nFrom CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. \\n\\nIn this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.\\n\\n### Limitations on general-purpose computing \\n\\nIn order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to *other* onion services). \\n\\nOn desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, **blocked entirely**. \\n\\nThis is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.\\n\\nWhile we expect that [Arti](https://gitlab.torproject.org/tpo/core/arti) will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. \\n\\nAs Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.\\n\\nWe encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don\'t place restrictions on what you can do with your own device.\\n\\n### Constraints introduced by the Flutter SDK\\n\\nThe Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by [platforms that are supported by the Flutter SDK](https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms).\\n\\nTo summarize, as of writing this document those platforms are:\\n\\n- Android API 16 and above (arm, arm64, and amd64)\\n- Debian-based Linux Distributions (64-bit only)\\n- macOS El Capitan (10.11) and above\\n- Windows 7 & above (64-bit only)\\n\\nTo put it plainly, without porting Cwtch UI to a different UI platform **we cannot support a 32-bit desktop version**.\\n\\n### Constraints introduced by Appstore Policy \\n\\nAs of writing, [Google is pushing applications to target API 31 or above](https://developer.android.com/google/play/requirements/target-sdk). This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.\\n\\n### CPU Architecture and Cwtch Bindings\\n\\nWe currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.\\n\\nIt is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.\\n\\n| Architecture / Platform | Windows | Linux | macOS | Android |\\n|--------------------------|---------|-----|-------| -------------|\\n| arm | \u274c | \u274c | \u274c | \u2705\ufe0f| \\n| arm64 | \u274c | \ud83d\udfe1 | \u2705 | \u2705\ufe0f | \\n| x86-64 / amd64 | \u2705 | \u2705 | \u2705\ufe0f | \u2705\ufe0f |\\n\\n\\"\ud83d\udfe1\\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).\\n\\n### Testing and official support\\n\\nAs a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the [Cwtch Release Candidate Testers](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.\\n\\nWe officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.\\n\\n### End-of-life platforms\\n\\nOperating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. [Windows 7 fell out of support on January 14, 2020](https://www.microsoft.com/en-us/windows/end-of-support), Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.\\n\\nLikewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.\\n\\nThe same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. [Cwtch currently requires libc 2.31+](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations).\\n\\nAndroid versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our [Cwtch Release Candidate Testers groups](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to help us understand the limitations of Android support across different API versions.\\n\\n## How we decide to officially support a platform\\n\\nTo help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:\\n\\n1. **The target platform needs to be officially supported by our development tools** - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.\\n2. **The target operating system needs to be supported by the Vendor** - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).\\n3. **The target platform must be backwards compatible with the most recent version in general use** - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch *may* run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).\\n4. **People want to use Cwtch on that platform** - We will generally only consider new platform support if people ask us about it. If Cwtch isn\'t available for a platform you want to use it on, then please get in touch and ask us about it!\\n\\n## Summary of official support\\n\\nThe table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). \\n\\nIn many cases we are looking for testers to confirm that various functionality works. A version of this table will be [maintained as part of the Cwtch Handbook](/docs/getting-started/supported_platforms).\\n\\n**Legend:**\\n\\n- \u2705: **Officially Supported**. Cwtch should work on these platforms without issue. Regressions are treated as high priority.\\n- \ud83d\udfe1: **Best Effort Support**. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.\\n- \u274c: **Not Supported**. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.\\n\\n\\n\\n| Platform | Official Cwtch Builds | Source Support | Notes |\\n|-----------------------------|-----------------------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------|\\n| Windows 11 | \u2705 | \u2705 | 64-bit amd64 only. |\\n| Windows 10 |\u2705 | \u2705 | 64-bit amd64 only. Not officially supported, but official builds may work. |\\n| Windows 8 and below | \u274c | \ud83d\udfe1 | Not supported. Dedicated builds from source may work. Testing Needed. |\\n| OSX 10 and below | \u274c | \ud83d\udfe1 | 64-bit Only. Official builds have been reported to work on Catalina but not High Sierra |\\n| OSX 11 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 12 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 13 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| Debian 11 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Debian 10 | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. |\\n| Debian 9 and below | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies. |\\n| Ubuntu 22.04 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Other Ubuntu | \ud83d\udfe1 | \u2705 | 64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies. | \\n| CentOS | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Gentoo | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Arch | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Whonix | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support. ](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550) |\\n| Raspian (arm64) | \ud83d\udfe1 | \u2705 | Builds from source work. |\\n| Other Linux Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Android 9 and below | \ud83d\udfe1 | \ud83d\udfe1 | Official builds may work. |\\n| Android 10 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 11 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 12 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 13 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| LineageOS | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support.](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607) |\\n| Other Android Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-bindings-reproducible","metadata":{"permalink":"/blog/cwtch-bindings-reproducible","source":"@site/blog/2023-01-20-reproducible-builds-bindings.md","title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","date":"2023-01-20T00:00:00.000Z","formattedDate":"January 20, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/blog/tags/bindings"},{"label":"repliqate","permalink":"/blog/tags/repliqate"}],"readingTime":7.915,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","slug":"cwtch-bindings-reproducible","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog3_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch UI Platform Support","permalink":"/blog/cwtch-platform-support"},"nextItem":{"title":"Cwtch Stable API Design","permalink":"/blog/cwtch-stable-api-design"}},"content":"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.\\n\\nBut open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.\\n\\nThe whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can **independently verify** that the binaries we release are built from the Cwtch source code.\\n\\nIn this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.\\n\\n\x3c!--truncate--\x3e\\n\\n## How Cwtch Bindings are Built\\n\\nSince we launched Cwtch Beta we have used Docker containers as part of our continuous build process.\\n\\nWhen a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.\\n\\nThe Cwtch Bindings build pipeline results in four compiled libraries:\\n\\n- **libcwtch.so** \u2013 For Linux Platforms, built using the [official golang:1.19.X Docker Image](https://hub.docker.com/_/golang)\\n- **libcwtch.dll** \u2013 For Windows Platforms, built using our own [mingw-go Docker Image](https://git.openprivacy.ca/openprivacy/mingw-go)\\n- **libcwtch.ld** \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)\\n- **cwtch.aar** \u2013 For Android Platforms, built using our own [Android/GoMobile Docker Image](https://git.openprivacy.ca/openprivacy/android-go-mobile)\\n\\nThese compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.\\n\\n## Making libCwtch Reproducible\\n\\nDocker containers alone aren\'t enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:\\n\\n* **Go Build ID**: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.\\n* **Build Paths and Go Environment Variables**: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the `trimPath` option, which we now specify for all bindings builds.\\n\\n### Linux Specific Considerations\\n\\nAfter the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.\\n\\nOur Drone/Docker build environments are based on [Debian Bullseye](https://www.debian.org/releases/bullseye/) which provides [libc6-dev version 2.31](https://packages.debian.org/bullseye/i386/libc6-dev). Other development setups will likely link libc-dev 2.34+.\\n\\nlibc6-dev 2.34 is notable [because it removed dependencies on libpthread and libdl](https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread) \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.\\n\\nThis means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on [Next Steps](#next-steps) for more information).\\n\\n### Windows Specific Considerations\\n\\nThe headers of PE files technically contain a timestamp field. In recent years an [effort has been made to use this field for other purposes](https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705), but by default `go build` will still include the timestamp of the file when producing a DLL file (at least when using CGO).\\n\\nFortunately this field can be zeroed out through passing `-Xlinker \u2013no-insert-timestamp` into the `mingw32-gcc` process.\\n\\nWith that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.\\n\\n\\n### Android Specific Considerations\\n\\nWith the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:\\n\\n* Cwtch makes use of [GoMobile](https://github.com/golang/mobile) for compiling Android libraries. We pin to a specific version `43a0384520996c8376bfb8637390f12b44773e65` in our Docker containers. Unlike `go build`, the `trimpPath` parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized `/tmp/go-build*` references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.\\n* We still use [sdk-tools](https://developer.android.com/studio/releases/sdk-tools) instead of the new [commandline-tools](https://developer.android.com/studio/command-line). The latest version of sdk-tools is `4333796` and available from: [https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip](https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip). As part of our plans for Cwtch Stable we will be updating this dependency.\\n* Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated `openjdk:8` image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. \\n\\nAll of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.\\n\\n### OSX Specific Considerations\\n\\nPerhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.\\n\\nAs with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.\\n\\nIn order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.\\n\\nIn an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a [proprietary SDK](https://www.apple.com/legal/sla/docs/xcode.pdf). There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.\\n\\nBecause of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.\\n\\n## Introducing Repliqate!\\n\\nWith all the above changes, **Cwtch Bindings for Linux and Windows are fully reproducible!**\\n\\nThat alone is great, but we also want to make it easier for **you** to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.\\n\\nTo make this process accessible we are releasing a new tool called [repliqate](https://git.openprivacy.ca/openprivacy/repliqate).\\n\\nRepliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.\\n\\nRepliqate runs [build-scripts](https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script) to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from [builds.openprivacy.ca](https://build.openprivacy.ca/files/).\\n\\nWe now provide [Repliqate build-scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts) for reproducible both [Linux libCwtch.so builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script), [Windows libCwtch.dll builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script)!\\n\\nWe also have a partially repeatable [Android cwtch.aar build](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script) script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.\\n\\nYou can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.\\n\\n## Next Steps\\n\\nReproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.\\n\\nAs we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-api-design","metadata":{"permalink":"/blog/cwtch-stable-api-design","source":"@site/blog/2023-01-13-cwtch-stable-api-design.md","title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","date":"2023-01-13T00:00:00.000Z","formattedDate":"January 13, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/blog/tags/planning"},{"label":"api","permalink":"/blog/tags/api"}],"readingTime":17.28,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","slug":"cwtch-stable-api-design","tags":["cwtch","cwtch-stable","planning","api"],"image":"/img/devlog2_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/blog/cwtch-bindings-reproducible"},"nextItem":{"title":"Path to Cwtch Stable","permalink":"/blog/path-to-cwtch-stable"}},"content":"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. \\n\\nAs we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.\\n\\nAs we move out of Beta and [towards Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable) it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.\\n\\nIn this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.\\n\\n![](/img/devlog2.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Clarifying Terminology\\n\\nOver the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:\\n\\n- **Cwtch** refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. \\n- **Cwtchlib** refers to the [reference implementation of the Cwtch Protocol](https://git.openprivacy.ca/cwtch.im/cwtch) / Application framework, currently written in Go.\\n- **Bindings** refers to C/Java/Kotlin/Rust bindings (primarily [libcwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go)) that act as an interface between Cwtchlib and downstream applications.\\n- `CwtchPeer` is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).\\n- `ProtocolEngine` is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, `ProtocolEngine` is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.\\n\\n\\n### Tenets of the Cwtch API Design\\n\\nBased on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:\\n\\n- **Robustness** - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.\\n- **Completeness** - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.\\n- **Security** \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.\\n\\n### The Cwtch Experiment Landscape\\n\\nA summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.\\n\\n- **Groups** \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized `ProtocolEngine` functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. \\n - **Hybrid Groups** - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.\\n- **Filesharing** \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in `ProtocolEngine`.\\n- **Profile Images** \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.\\n- **Server Hosting** \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.\\n- **Message Formatting** \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history\\n- **Search / Microblogging** \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.\\n- **Status / Profile Metadata** \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.\\n\\n### The Problem with Experiments\\n\\nWe have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the `SendMessages` interface that only allows callers to send messages.\\n\\nWe have also worked to package experimental functionality into so-called **Gated Functionalities** that are only available if a given experiment is turned on.\\n\\nTogether, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:\\n\\n- The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. `SendMessages` \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).\\n- The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.\\n- This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.\\n\\n### Restricting Powerful Cwtch APIs\\n\\nTo carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:\\n\\n- Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through `Application` and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.\\n- Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a `RestrictedCwtchConversationInterface` which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact.\\n- Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow `CwtchPeer` to control which experiments get access to which events at a given time.\\n\\n#### Pre-Registered Hooks\\n\\nIn order to implement certain functionality actions need to take place in-between events handled by `CwtchPeer`. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).\\n\\nThis is currently only possible with invasive changes to the `CwtchPeer` interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.\\n\\nWe are introducing a new set of Cwtch APIs designed for this purpose:\\n\\n- `OnNewPeerMessage` - hooked prior to inserting the message into the database.\\n- `OnPeerMessageConfirmed` \u2013 hooked after a peer message has been inserted into the database.\\n- `OnEncryptedGroupMessage` \u2013 hooked after receiving an encrypted message from a group server.\\n- `OnGroupMessageReceived` \u2013 hooked after a successful decryption of a group message, but before inserting it into the database.\\n- `OnContactRequestValue` \u2013 hooked on request of a scoped (the permission level of the attribute e.g. `public` or `conversation` level attributes), zoned ( relating to a specific feature e.g. `filesharing` or `chat`), and keyed (the name of the attribute e.g. `name` or `manifest`) value from a contact.\\n- `OnContactReceiveValue` \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.\\n\\nIncluding the following APIs for managing hooked functionality:\\n\\n- `RegisterEvents` - returns a set of events that the extension is interested processing.\\n- `RegisterExperiments` - returns a set of experiments that the extension is interested in being notified about\\n- `OnEvent` - to be called by `CwtchPeer` whenever an event registered with `RegisterEvents` is called (assuming all experiments registered through `RegisterExperiments` is active)\\n\\n#### `ProtocolEngine` Subsystems\\n\\nAs mentioned in our experiment summary, some functionality needs to be implemented directly in the `ProtocolEngine`. The `ProtocolEngine` is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).\\n\\nSome types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a `ProtocolEngine`.\\n\\nAt the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to `ProtocolEngine` that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider `ProtocolEngine` ecosystem. \\n\\nWe are formalizing this subsystem into an interface, similar to the hooked functionality in `CwtchPeer`:\\n\\n- `RegisterEvents` - returns a set of events that the subsystem needs to consume to operate.\\n- `OnEvent` \u2013 to be called by `ProtocolEngine` whenever an event registered with `RegisterEvents` is called (when all the experiments registered through `RegisterExperiments` are active)\\n- `RegisterContexts` - returns the set of contexts that the subsystem implements e.g. `im.cwtch.filesharing`\\n\\nThis also requires a formalization of two *engine specific* events (for use on the event bus):\\n\\n- `SendCwtchMessage` \u2013 encapsulating the existing `CwtchPeerMessage` that is used internally in `ProtocolEngine` for messages between subsystems.\\n- `CwtchMessageReceived` \u2013 encapsulating the existing `handlePeerMessage` function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.\\n\\nAnd the introduction of three **additional** `ProtocolEnine` specific events:\\n\\n- `StartEngineSubsystem` \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.\\n- `StopEngineSubsystem` \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.\\n- `SubsystemStatus` \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging\\n\\nThis will allow us to move the following functionality, currently part of `ProtocolEngine` itself, into generic subsystems:\\n\\n- **Attribute Lookup Handling** - this functionality is currently part of the overloaded `handlePeerMessage` function, filtered using the `Context` parameter of the `CwtchPeerMessage`. As such it can be entirely delegated to a subsystem. \\n- **Filesharing Chunk Request Handling** \u2013 this is also part of handlePeerMessage, also filtered using the `Context` parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by `handlePeerMessage`)\\n- **Filesharing Start File Share/Stop File Share** \u2013 this is currently part of the `handleEvent` behaviour of `ProtocolEngine` and can be moved into an `OnEvent` handler of the file sharing subsystem (where such events are already processed).\\n\\nThe introduction of pre-registered hooks in combination with the formalizations of `ProtocolEngine` subsystems will allow the follow functionality, currently implemented in `CwtchPeer` or libcwtch-go to be moved to standalone packages:\\n\\n- **Filesharing** makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. \\n - Filesharing also depends on the file sharing subsystem to be enabled in a `ProtocolEngine`. This subsystem is responsible for processing chunk requests.\\n- **Profile Images** \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)\\n- **Legacy Groups** \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.\\n- **Status/Profile Metadata** \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.\\n \\n#### Impact on Enabling (Powerful) New Functionality\\n\\nNone of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:\\n\\n- **Search** \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.\\n- **Non Chat Conversation Contexts** - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.\\n\\n## Application Experiments\\n\\nOne kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers.\\n\\nThis kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library.\\n\\nThis functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.\\n\\n## Bindings\\n\\nThe last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.\\n\\nWe can split the bindings into four core areas:\\n\\n- **Application Management** - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.\\n- **Application Experiments** - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.\\n- **Core Profile Management** - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.\\n- **Experimental Profile Features** \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.\\n\\nThe flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.\\n\\nIn an ideal future, all of these bindings could be **generated automatically** from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)\\n\\nWe can define three types of C/Java/Kotlin interface function templates:\\n\\n- `ProfileMethodName(profilehandle String, args...)` \u2013 which directly resolves the Cwtch Profile and calls the function.\\n- `ProfileExperimentalMethodName(profilehandle String, args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.\\n- `ApplicationExperimentalMethodName(args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.\\n\\nAll we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context `ProfileInterface` for the first, exported methods of the various `Functionalities` for the second, and `ApplicationExperiment` definitions for the third.\\n\\n## Timelines and Next Actions\\n\\n- **Freeze any changes to the bindings interface** - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib.\\n- As part of Cwtch 1.11 and 1.12 Release Cycles\\n - Implement the `ProtocolEngine` Subsystem Design as outlined above.\\n - Implement the Hooks API.\\n - Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting).\\n - Move event handling from the bindings into Application.\\n - Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions.\\n- Once Automated UI Tests have been integrated into the Cwtch UI Repository:\\n - Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings **and** a dart calling convention library from cwtchlib and any configured application experiments libraries\\n - Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).\\n - At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)\\n\\n## Appendix A: Special Behaviour Defined by libcwtch-go\\n\\nThe following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:\\n\\n- Application Settings\\n - Including Enabling / Disabling Experiment\\n- ACN Process Management - starting/stopping/restarting/configuring Tor.\\n- Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)\\n- Logging Levels - configuring appropriate logging levels (e.g. `INFO` or `DEBUG`)\\n- Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.\\n- UI Contact Structures - aggregating contact information for the main Cwtch UI.\\n- Group Experiment Functionality\\n - Experiment Gating\\n - GetServerInfoList\\n - GetServerInfo\\n - UI Server Struct Definition\\n- Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.\\n- \\"Unencrypted\\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \\"unencrypted\\".\\n- Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).\\n- Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.\\n- Cwtch Profile Engine Activation - starting/stopping a `ProtocolEngine` when requested by the UI, or in response to changes in ACN state.\\n- UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.\\n- File sharing restarts \\n- UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn\'t directly embedded within the event (e.g. converting `handle` to a `conversation id`). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.\\n- Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)"},{"id":"path-to-cwtch-stable","metadata":{"permalink":"/blog/path-to-cwtch-stable","source":"@site/blog/2023-01-06-path-to-cwtch-stable.md","title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","date":"2023-01-06T00:00:00.000Z","formattedDate":"January 6, 2023","tags":[{"label":"cwtch","permalink":"/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/blog/tags/planning"}],"readingTime":9.995,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","slug":"path-to-cwtch-stable","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable API Design","permalink":"/blog/cwtch-stable-api-design"}},"content":"As of December 2022 we have released 10 versions of Cwtch Beta since the [initial launch, 18 months ago, in June 2021](https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/).\\n\\nThere is a consensus among the team that the next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable.\\n\\nThis post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.\\n\\n![](/img/devlog1.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Tenets of Cwtch Stable\\n\\nIt is important to state that Cwtch Stable **does not mean an end to Cwtch development**. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:\\n\\n1. **Consistent Interface** \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.\\n2. **Universal Availability and Cohesive Support** \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\n3. **Reproducible Builds** \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.\\n4. **Proven Security** \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.\\n\\n### Known Problems\\n\\nTo begin, let\'s outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.\\n\\n1. **Lack of a Stable API for future feature development** \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)\\n2. **Special functionality in libCwtch-go** \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)\\n3. **libCwtch-rs partial support** - we currently do not officially consider [libCwtch-rs](https://lib.rs/crates/libcwtch) when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)\\n4. **Lack of Reproducible Pipelines** - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)\\n5. **Lack of up to date, and translated, Security Documentation** \u2013 the [Cwtch security handbook](https://docs.openprivacy.ca/cwtch-security-handbook/) is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)\\n6. **No Automated UI Tests** \u2013 we put a lot of work into [building out a testing framework for the UI](https://openprivacy.ca/discreet-log/23-cucumber-testing/), but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)\\n7. **Code Signing Provider** \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)\\n8. **Second-class Android Support** - while we have put [a lot of effort behind Android support](https://openprivacy.ca/discreet-log/27-android-improvements/) across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)\\n9. **Lack of Fuzzing** \u2013 while [Fuzzbot](https://openprivacy.ca/discreet-log/07-fuzzbot/) sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)\\n10. **Lack of Formal Release Acceptance Process** \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)\\n11. **Inconsistent Cwtch Information Discovery** \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)\\n12. **Incomplete Documentation** \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)\\n\\n### Plan of Action\\n\\nOutside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:\\n\\n1. **Define, Publish, and Implement a Cwtch Interface Specification Documentation** \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)\\n2. **Define, Publish, and Implement a Cwtch Release Process** \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)\\n3. **Define, Publish, and Implement a Cwtch Support Document** - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)\\n4. **Define, Publish, and Implement a Cwtch Packaging Document** - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)\\n5. **Define, Publish, and Implement a Reproducible Builds Document** \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)\\n6. **Expand the Cwtch Documentation Site** \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)\\n7. **Expand our Automated Testing to include UI and Fuzzing** - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)\\n8. **Re-evaluate all Issues across all Cwtch related repositories** \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.\\n9. **Define a Stable Feature Set** \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)\\n\\n### Goals and Timelines\\n\\nWith all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:\\n\\n1. By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).\\n2. By **1st February 2023**, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.\\n3. By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.\\n4. By **31st March 2023**, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).\\n5. By **31st March 2023** the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.\\n6. By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.\\n7. By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.\\n8. By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.\\n\\nAs these documents are written, and these goals met we will be posting them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, Cwtch development.\\n\\n### Help us get there!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"}]}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b59bb8da.f0b56cc8.js b/build-staging/assets/js/b59bb8da.f0b56cc8.js new file mode 100644 index 00000000..a6729e8c --- /dev/null +++ b/build-staging/assets/js/b59bb8da.f0b56cc8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4729],{6693:t=>{t.exports=JSON.parse('{"title":"Conversations","slug":"/category/conversations","permalink":"/docs/category/conversations","navigation":{"previous":{"title":"Setting Profile Attributes","permalink":"/docs/profiles/profile-info"},"next":{"title":"An Introduction to Cwtch P2P Chat","permalink":"/docs/chat/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/b5c61d38.b2aae603.js b/build-staging/assets/js/b5c61d38.b2aae603.js new file mode 100644 index 00000000..93b88345 --- /dev/null +++ b/build-staging/assets/js/b5c61d38.b2aae603.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8849],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(r),m=o,f=p["".concat(l,".").concat(m)]||p[m]||h[m]||a;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,s=new Array(a);s[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,s[1]=i;for(var c=2;c<a;c++)s[c]=r[c];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},3159:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const a={},s="Cwtch Server",i={unversionedId:"components/cwtch/server",id:"components/cwtch/server",title:"Cwtch Server",description:"The goal of the Cwtch protocol is to enable group communication through",source:"@site/security/components/cwtch/server.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/server",permalink:"/security/components/cwtch/server",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/security/components/cwtch/groups"},next:{title:"Cwtch UI",permalink:"/security/category/cwtch-ui"}},l={},c=[{value:"Malicious Servers",id:"malicious-servers",level:2},{value:"Detectable Faults",id:"detectable-faults",level:3},{value:"Efficiency",id:"efficiency",level:2}],u={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cwtch-server"},"Cwtch Server"),(0,o.kt)("p",null,"The goal of the Cwtch protocol is to enable group communication through\n",(0,o.kt)("strong",{parentName:"p"},"Untrusted Infrastructure"),"."),(0,o.kt)("p",null,"Unlike in relay-based schemes where the groups assign a leader, set of\nleaders, or a trusted third party server to ensure that every member of the\ngroup can send and receive messages in a timely manner (even if members are\noffline) - untrusted infrastructure has a goal of realizing those properties\nwithout the assumption of trust."),(0,o.kt)("p",null,"The original Cwtch paper defined a set of properties that Cwtch Servers were\nexpected to provide:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Cwtch Server may be used by multiple groups or just one."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server, without collaboration of a group member, should\nnever learn the identity of participants within a group."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server should never learn the content of any communication."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server should never be able to distinguish messages as belonging\nto a particular group.")),(0,o.kt)("p",null,"We note here that these properties are a superset of the design aims of Private\nInformation Retrieval structures."),(0,o.kt)("h2",{id:"malicious-servers"},"Malicious Servers"),(0,o.kt)("p",null,"We expect the presence of malicious entities within the Cwtch ecosystem."),(0,o.kt)("p",null,"We also prioritize decentralization and permissionless entry into the\necosystem and as such we do not base any security claims on the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Any non-collusion assumptions between a set of Cwtch servers"),(0,o.kt)("li",{parentName:"ul"},"Any third-party defined verification process")),(0,o.kt)("p",null,"Peers themselves are encouraged to set up and run Cwtch servers where they can\nguarantee more efficient properties by relaxing trust and security\nassumptions - however, by default, we design the protocol to be secure without\nthese assumptions - sacrificing efficiency where necessary."),(0,o.kt)("h3",{id:"detectable-faults"},"Detectable Faults"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"If a Cwtch server fails to relay a specific message to a subset of group\nmembers then there will be a detectable gap in the message tree of certain\npeers that can be discovered through peer-to-peer gossip."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch server cannot modify any message without the key material known to\nthe group (any attempt to do so for a subset of group members will result in\nidentical behavior to failing to relay a message)."),(0,o.kt)("li",{parentName:"ul"},"While a server ",(0,o.kt)("em",{parentName:"li"},"can")," duplicate messages, these will have no impact on the\ngroup message tree (because of encryption, nonces and message identities) -\nthe source of the duplication is not knowable to a peer.\n")),(0,o.kt)("h2",{id:"efficiency"},"Efficiency"),(0,o.kt)("p",null,'As of writing, only 1 protocol is known for achieving the desired properties,\nnaive PIR or "the server sends everything, and the peers sift through it".'),(0,o.kt)("p",null,"This has an obvious impact on bandwidth efficiency, especially for peers using\nmobile devices, as such we are actively developing new protocols in which the\nprivacy and efficiency guarantees can be traded-off in different ways."),(0,o.kt)("p",null,"As of writing, the servers allow both a complete download of all stored messages, and a\nrequest to download messages from a certain specified message."),(0,o.kt)("p",null,"All peers when they first join a group on a new server download all messages from the server, and\nfrom then on download only new messages."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note"),": This behaviour does permit a mild form of metadata analysis. The server can new messages for each\nsuspected unique profile, and then use these unique message signatures to track unique sessions over time (\nvia requests for new messages). "),(0,o.kt)("p",null,"This is mitigated by 2 confounding factors:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Profiles can refresh their connections at any time - resulting in fresh server session."),(0,o.kt)("li",{parentName:"ol"},'Profiles can "resync" from a server at any time - resulting in a new call to download all messages. The most\ncommon usecase for this behaviour is to fetch older messages from a group.\n')),(0,o.kt)("p",null,"In combination, these 2 mitigations place bounds on what the server is able to infer however we still cannot\nprovide full metadata-resistance. "),(0,o.kt)("p",null,"For potential future solutions to this problem see ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/niwl"},"Niwl")),(0,o.kt)("h1",{id:"protecting-the-server-from-malicious-peers"},"Protecting the Server from Malicious Peers"),(0,o.kt)("p",null,"The main risk to servers come in the form of spam generated by peers. In the\nprototype of Cwtch a spamguard mechanism was put in place that required\npeers to conduct some arbitrary proof of work given a server-specified\nparameter."),(0,o.kt)("p",null,"This is not a robust solution in the presence of a determined adversary with\na significant amount of resources, and thus one of the main external risks to\nthe Cwtch system becomes censorship-via-resource exhaustion."),(0,o.kt)("p",null,"We have outlined a potential solution to this in\n",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/research/OPTR2019-01/"},"token based services")," but note\nthat this also requires further development."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/bb772baa.ee2022e0.js b/build-staging/assets/js/bb772baa.ee2022e0.js new file mode 100644 index 00000000..7829a373 --- /dev/null +++ b/build-staging/assets/js/bb772baa.ee2022e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6341],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,s=a(e,["components","mdxType","originalType","parentName"]),f=c(r),d=o,m=f["".concat(p,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(m,l(l({ref:t},s),{},{components:r})):n.createElement(m,l({ref:t},s))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,l=new Array(i);l[0]=d;var a={};for(var p in t)hasOwnProperty.call(t,p)&&(a[p]=t[p]);a.originalType=e,a[f]="string"==typeof e?e:o,l[1]=a;for(var c=2;c<i;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},1020:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:6},l="Deleting a Profile",a={unversionedId:"profiles/delete-profile",id:"profiles/delete-profile",title:"Deleting a Profile",description:"This feature will result in irreversible deletion of key material. This cannot be undone.",source:"@site/docs/profiles/delete-profile.md",sourceDirName:"profiles",slug:"/profiles/delete-profile",permalink:"/docs/profiles/delete-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/delete-profile.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Unlocking Encrypted Profiles",permalink:"/docs/profiles/unlock-profile"},next:{title:"Backup or Exporting a Profile",permalink:"/docs/profiles/exporting-profile"}},p={},c=[],s={toc:c},f="wrapper";function u(e){let{components:t,...r}=e;return(0,o.kt)(f,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"deleting-a-profile"},"Deleting a Profile"),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,o.kt)("strong",{parentName:"p"},"irreversible")," deletion of key material. This ",(0,o.kt)("strong",{parentName:"p"},"cannot be undone"),".")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Press the pencil next to the profile you want to edit"),(0,o.kt)("li",{parentName:"ol"},"Scroll down to the bottom of the screen"),(0,o.kt)("li",{parentName:"ol"},"Press delete"),(0,o.kt)("li",{parentName:"ol"},"Press really delete profile")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/bf059cf9.125608d5.js b/build-staging/assets/js/bf059cf9.125608d5.js new file mode 100644 index 00000000..cdbd591e --- /dev/null +++ b/build-staging/assets/js/bf059cf9.125608d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5273],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>b});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,i,n=function(e,t){if(null==e)return{};var r,i,n={},a=Object.keys(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=i.createContext({}),s=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=s(e.components);return i.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=s(r),g=n,b=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return r?i.createElement(b,o(o({ref:t},p),{},{components:r})):i.createElement(b,o({ref:t},p))}));function b(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=g;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[d]="string"==typeof e?e:n,o[1]=c;for(var s=2;s<a;s++)o[s]=r[s];return i.createElement.apply(null,o)}return i.createElement.apply(null,r)}g.displayName="MDXCreateElement"},2626:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"February 10, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"repliqate",permalink:"/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/blog/cwtch-testing-i"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},d="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(d,(0,i.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(4756).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},4756:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/bfc2e843.2c458193.js b/build-staging/assets/js/bfc2e843.2c458193.js new file mode 100644 index 00000000..011e190f --- /dev/null +++ b/build-staging/assets/js/bfc2e843.2c458193.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[610],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=p(r),d=a,f=m["".concat(c,".").concat(d)]||m[d]||u[d]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:a,i[1]=s;for(var p=2;p<o;p++)i[p]=r[p];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},296:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:4},i="Streamer/Presentation Mode",s={unversionedId:"settings/appearance/streamer-mode",id:"settings/appearance/streamer-mode",title:"Streamer/Presentation Mode",description:"Streamer/Presentation mode makes the app more visually private. In this mode, Cwtch will not display",source:"@site/docs/settings/appearance/streamer-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/streamer-mode",permalink:"/docs/settings/appearance/streamer-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/streamer-mode.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"UI columns",permalink:"/docs/settings/appearance/ui-columns"},next:{title:"Behaviour",permalink:"/docs/category/behaviour"}},c={},p=[],l={toc:p},m="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"streamerpresentation-mode"},"Streamer/Presentation Mode"),(0,a.kt)("p",null,"Streamer/Presentation mode makes the app more visually private. In this mode, Cwtch will not display\nauxiliary information like Cwtch addresses and other sensitive information on the main screens."),(0,a.kt)("p",null,"This is useful when taking screenshots or otherwise displaying Cwtch in a more public way."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Press the settings icon"),(0,a.kt)("li",{parentName:"ol"},'Toggle "Streamer Mode" to On'),(0,a.kt)("li",{parentName:"ol"},"Check it works by looking at your profile or at your contact list")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c063e42f.ebf0125c.js b/build-staging/assets/js/c063e42f.ebf0125c.js new file mode 100644 index 00000000..67e6820e --- /dev/null +++ b/build-staging/assets/js/c063e42f.ebf0125c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8589],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),h=o,d=u["".concat(s,".").concat(h)]||u[h]||m[h]||i;return n?r.createElement(d,a(a({ref:t},l),{},{components:n})):r.createElement(d,a({ref:t},l))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},4463:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={},a="Input",c={unversionedId:"components/ui/input",id:"components/ui/input",title:"Input",description:"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices",source:"@site/security/components/ui/input.md",sourceDirName:"components/ui",slug:"/components/ui/input",permalink:"/security/components/ui/input",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Image Previews",permalink:"/security/components/ui/image_previews"},next:{title:"Message Overlays",permalink:"/security/components/ui/overlays"}},s={},p=[{value:"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices",id:"risk-interception-of-cwtch-content-or-metadata-through-an-ime-on-mobile-devices",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"input"},"Input"),(0,o.kt)("h2",{id:"risk-interception-of-cwtch-content-or-metadata-through-an-ime-on-mobile-devices"},"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")),(0,o.kt)("p",null,"Any component that has the potential to intercept data between a person, and the Cwtch app is a\npotential security risk."),(0,o.kt)("p",null,"One of the most likely interceptors is a 3rd party IME (Input Method Editor) commonly used\nby people to generate characters not natively supported by their device."),(0,o.kt)("p",null,"Even benign and stock IME apps may unintentionally leak information about the contents of a persons message e.g.\nthrough cloud synchronization, cloud translation or personal dictionaries."),(0,o.kt)("p",null,"Ultimately, this problem cannot be solved by Cwtch alone, and is a wider risk impacting the entire mobile\necosystem."),(0,o.kt)("p",null,"A similar risk exists on desktop through the use of similar input applications (in addition to software keyloggers),\nhowever we consider that fully outside the scope of Cwtch risk assessment (in line with other attacks on the security of the underlying\noperating system itself)."),(0,o.kt)("p",null,"This is partially mitigated in Cwtch 1.2 through the use of ",(0,o.kt)("inlineCode",{parentName:"p"},"enableIMEPersonalizedLearning: false"),". See\n",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/142"},"this PR")," for more information."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c11bf3c5.171064ae.js b/build-staging/assets/js/c11bf3c5.171064ae.js new file mode 100644 index 00000000..81b9e60b --- /dev/null +++ b/build-staging/assets/js/c11bf3c5.171064ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7322],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=o,f=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p<i;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},8085:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:1},a="An Introduction to Cwtch App Settings",s={unversionedId:"settings/introduction",id:"settings/introduction",title:"An Introduction to Cwtch App Settings",description:"Appearance",source:"@site/docs/settings/introduction.md",sourceDirName:"settings",slug:"/settings/introduction",permalink:"/docs/settings/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Settings",permalink:"/docs/category/settings"},next:{title:"Appearance",permalink:"/docs/category/appearance"}},c={},p=[{value:"Appearance",id:"appearance",level:2},{value:"Behaviour",id:"behaviour",level:2},{value:"Experiments",id:"experiments",level:2}],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"an-introduction-to-cwtch-app-settings"},"An Introduction to Cwtch App Settings"),(0,o.kt)("h2",{id:"appearance"},"Appearance"),(0,o.kt)("p",null,"These are settings which effect how Cwtch looks, including themes and localization. "),(0,o.kt)("h2",{id:"behaviour"},"Behaviour"),(0,o.kt)("p",null,"These settings impact how Cwtch responds to certain events e.g. notifications for new messages, or requests\nfrom unknown public addresses."),(0,o.kt)("h2",{id:"experiments"},"Experiments"),(0,o.kt)("p",null,"There are many features in Cwtch that people would like to have but whose implementation requires additional metadata, or\nrisk, beyond the minimum that Cwtch requires for basic operations."),(0,o.kt)("p",null,"As such under ",(0,o.kt)("strong",{parentName:"p"},"Experiments")," you will find a number of ",(0,o.kt)("strong",{parentName:"p"},"optional")," settings which, when enables, provide\nadditional features like group chat, file sharing or message formatting."),(0,o.kt)("p",null,"You should think carefully when enabling these features about the new risks that might be involved, and if you\nare comfortable opting-in to those risks. For many the benefits of file sharing, image previews and group chat\nfar outweigh the potential harms - but for other we require everyone to opt-in to these features."),(0,o.kt)("p",null,"You can opt-out at any time, all features are implemented locally within the Cwtch app."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c14f15fd.884891e7.js b/build-staging/assets/js/c14f15fd.884891e7.js new file mode 100644 index 00000000..98744c1f --- /dev/null +++ b/build-staging/assets/js/c14f15fd.884891e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7649],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,f=u["".concat(s,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},3071:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:2},i="Core Concepts",c={unversionedId:"building-a-cwtch-app/core-concepts",id:"building-a-cwtch-app/core-concepts",title:"Core Concepts",description:"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.",source:"@site/developing/building-a-cwtch-app/core-concepts.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/core-concepts",permalink:"/developing/building-a-cwtch-app/core-concepts",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Getting Started",permalink:"/developing/building-a-cwtch-app/intro"},next:{title:"Building a Cwtch Echobot",permalink:"/developing/building-a-cwtch-app/building-an-echobot"}},s={},l=[{value:"Cwtch Home Directory",id:"cwtch-home-directory",level:2},{value:"Profiles",id:"profiles",level:2},{value:"The Event Bus",id:"the-event-bus",level:2},{value:"Settings",id:"settings",level:2},{value:"Experiments",id:"experiments",level:3}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"core-concepts"},"Core Concepts"),(0,a.kt)("p",null,"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently."),(0,a.kt)("h2",{id:"cwtch-home-directory"},"Cwtch Home Directory"),(0,a.kt)("p",null,"Often referred to as ",(0,a.kt)("inlineCode",{parentName:"p"},"$CWTCH_HOME"),", the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application."),(0,a.kt)("h2",{id:"profiles"},"Profiles"),(0,a.kt)("p",null,"Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations."),(0,a.kt)("h2",{id:"the-event-bus"},"The Event Bus"),(0,a.kt)("p",null,"Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"NewMessageFromPeer")," and setup an event handler to run code in response to such a message."),(0,a.kt)("p",null,"For an example see the Echo Bot tutorial."),(0,a.kt)("h2",{id:"settings"},"Settings"),(0,a.kt)("p",null,"Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration."),(0,a.kt)("h3",{id:"experiments"},"Experiments"),(0,a.kt)("p",null,"Certain Cwtch features are ",(0,a.kt)("a",{parentName:"p",href:"/docs/category/experiments"},"gated behind experiments"),". These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c2081115.5e6d9476.js b/build-staging/assets/js/c2081115.5e6d9476.js new file mode 100644 index 00000000..0751ccf6 --- /dev/null +++ b/build-staging/assets/js/c2081115.5e6d9476.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8194],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>y});var i=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,i,o=function(e,t){if(null==e)return{};var n,i,o={},r=Object.keys(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=i.createContext({}),p=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(n),h=o,y=u["".concat(l,".").concat(h)]||u[h]||m[h]||r;return n?i.createElement(y,a(a({ref:t},s),{},{components:n})):i.createElement(y,a({ref:t},s))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,a=new Array(r);a[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<r;p++)a[p]=n[p];return i.createElement.apply(null,a)}return i.createElement.apply(null,n)}h.displayName="MDXCreateElement"},7047:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>c,toc:()=>p});var i=n(7462),o=(n(7294),n(3905));const r={sidebar_position:1.5},a="Component Ecosystem Overview",c={unversionedId:"components/ecosystem-overview",id:"components/ecosystem-overview",title:"Component Ecosystem Overview",description:"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of",source:"@site/security/components/ecosystem-overview.md",sourceDirName:"components",slug:"/components/ecosystem-overview",permalink:"/security/components/ecosystem-overview",draft:!1,tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Cwtch Technical Basics",permalink:"/security/components/intro"},next:{title:"Connectivity & Tor",permalink:"/security/category/connectivity--tor"}},l={},p=[{value:"openprivacy/connectivity",id:"openprivacyconnectivity",level:2},{value:"cwtch.im/tapir",id:"cwtchimtapir",level:2},{value:"cwtch.im/cwtch",id:"cwtchimcwtch",level:2},{value:"cwtch.im/libcwtch-go",id:"cwtchimlibcwtch-go",level:2},{value:"cwtch-ui",id:"cwtch-ui",level:2},{value:"Auxiliary Components",id:"auxiliary-components",level:2},{value:"openprivacy/log",id:"openprivacylog",level:3}],s={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,i.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"component-ecosystem-overview"},"Component Ecosystem Overview"),(0,o.kt)("p",null,"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of\neach component and how it relates to the wider Cwtch ecosystem."),(0,o.kt)("h2",{id:"openprivacyconnectivity"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity")),(0,o.kt)("p",null,"Summary: A library providing an ACN (Anonymous Communication Network ) networking abstraction."),(0,o.kt)("p",null,"The goal of connectivity is to abstract away the underlying libraries/software needed to communicate with a\nspecific ACN. Right now we only support Tor and so the job of connectivity is to:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Start and Stop the Tor Process"),(0,o.kt)("li",{parentName:"ul"},"Provide configuration to the Tor process"),(0,o.kt)("li",{parentName:"ul"},"Allow raw connections to endpoints via the Tor process (e.g. connect to onion services)"),(0,o.kt)("li",{parentName:"ul"},"Host endpoints via the Tor process (e.g. host onion services)"),(0,o.kt)("li",{parentName:"ul"},"Provide status updates about the underlying Tor process")),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/connectivity/intro"},"connectivity")),(0,o.kt)("h2",{id:"cwtchimtapir"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/tapir"},"cwtch.im/tapir")),(0,o.kt)("p",null,"Summary: Tapir is a small library for building p2p applications over anonymous communication systems."),(0,o.kt)("p",null,"The goal of tapir is to abstract away ",(0,o.kt)("strong",{parentName:"p"},"applications")," over a particular ACN. Tapir supports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Creating a cryptographic identity (including ephemeral identities)"),(0,o.kt)("li",{parentName:"ul"},"Maintaining a connection pool of inbound and outbound connections to services"),(0,o.kt)("li",{parentName:"ul"},"Handling various application-layers including cryptographic transcripts, ",(0,o.kt)("a",{parentName:"li",href:"/security/components/tapir/authentication_protocol"},"authentication and authorization protocols"),", and\n",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"token-based services via PrivacyPass"),",")),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/tapir/authentication_protocol"},"tapir")),(0,o.kt)("h2",{id:"cwtchimcwtch"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"cwtch.im/cwtch")),(0,o.kt)("p",null,"Summary: Cwtch is the main library for implementing the Cwtch protocol / system."),(0,o.kt)("p",null,"The goal of Cwtch is to provide implementations for cwtch-specific applications e.g.\nmessage sending, groups, and file sharing(implemented as Tapir applications), provide interfaces for managing and storing Cwtch profiles, provide an event bus for subsystem splutting and building plugins with new functionality, in addition to managing other core functionality."),(0,o.kt)("p",null,"The Cwtch library is also responsible for maintaining canonical model representations for wire formats and overlays."),(0,o.kt)("h2",{id:"cwtchimlibcwtch-go"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"cwtch.im/libcwtch-go")),(0,o.kt)("p",null,"Summary: libcwtch-go provides C (including Android) bindings for Cwtch for use in UI implementations."),(0,o.kt)("p",null,"The goal of libcwtch-go is to bridge the gap between the backend Cwtch library and any front end systems which\nmay be written in a different language."),(0,o.kt)("p",null,"The API provided by libcwtch is much more restricted than the one provided by Cwtch directly, each libcwtch API typically\npackages up several calls to Cwtch."),(0,o.kt)("p",null,"libcwtch-go is also responsible for managing UI settings and experimental gating. It is also often used as a staging ground\nfor experimental features and code that may eventually end up in Cwtch."),(0,o.kt)("h2",{id:"cwtch-ui"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui"},"cwtch-ui")),(0,o.kt)("p",null,"Summary: A flutter based UI for Cwtch."),(0,o.kt)("p",null,"Cwtch UI uses libcwtch-go to provide a complete UI for Cwtch, allowing people to create and manage profiles,\nadd contacts and groups, message people, share files (coming soon) and more."),(0,o.kt)("p",null,"The UI is also responsible for managing localization and translations."),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"Cwtch UI")),(0,o.kt)("h2",{id:"auxiliary-components"},"Auxiliary Components"),(0,o.kt)("p",null,"Occasionally, Open Privacy will factor out parts of Cwtch into standalone libraries that are not Cwtch specific.\nThese are briefly summarized here:"),(0,o.kt)("h3",{id:"openprivacylog"},(0,o.kt)("a",{parentName:"h3",href:"https://git.openprivacy.ca/openprivacy/log"},"openprivacy/log")),(0,o.kt)("p",null,"An Open Privacy specific logging framework that is used throughout Cwtch packages."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c33e2c0d.e031ee49.js b/build-staging/assets/js/c33e2c0d.e031ee49.js new file mode 100644 index 00000000..4ff06e77 --- /dev/null +++ b/build-staging/assets/js/c33e2c0d.e031ee49.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9936],{6629:e=>{e.exports=JSON.parse('{"title":"Cwtch UI","slug":"/category/cwtch-ui","permalink":"/security/category/cwtch-ui","navigation":{"previous":{"title":"Cwtch Server","permalink":"/security/components/cwtch/server"},"next":{"title":"Android Service","permalink":"/security/components/ui/android"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c42e2be1.c4a9586b.js b/build-staging/assets/js/c42e2be1.c4a9586b.js new file mode 100644 index 00000000..94274e5b --- /dev/null +++ b/build-staging/assets/js/c42e2be1.c4a9586b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4842],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>y});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},a=Object.keys(e);for(o=0;o<a.length;o++)r=a[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o<a.length;o++)r=a[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=o.createContext({}),s=function(e){var t=o.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=s(r),u=n,y=d["".concat(c,".").concat(u)]||d[u]||f[u]||a;return r?o.createElement(y,i(i({ref:t},p),{},{components:r})):o.createElement(y,i({ref:t},p))}));function y(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,i=new Array(a);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[d]="string"==typeof e?e:n,i[1]=l;for(var s=2;s<a;s++)i[s]=r[s];return o.createElement.apply(null,i)}return o.createElement.apply(null,r)}u.displayName="MDXCreateElement"},7771:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var o=r(7462),n=(r(7294),r(3905));const a={sidebar_position:1.5},i="Creating a New Profile",l={unversionedId:"profiles/create-a-profile",id:"profiles/create-a-profile",title:"Creating a New Profile",description:'1. Press the + action button in the right bottom corner and select "New Profile"',source:"@site/docs/profiles/create-a-profile.md",sourceDirName:"profiles",slug:"/profiles/create-a-profile",permalink:"/docs/profiles/create-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/create-a-profile.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"An Introduction to Cwtch Profiles",permalink:"/docs/profiles/introduction"},next:{title:"Changing Your Display Name",permalink:"/docs/profiles/change-name"}},c={},s=[{value:"A note on Password Protected (Encrypted) Profiles",id:"a-note-on-password-protected-encrypted-profiles",level:2}],p={toc:s},d="wrapper";function f(e){let{components:t,...r}=e;return(0,n.kt)(d,(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"creating-a-new-profile"},"Creating a New Profile"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Press the ",(0,n.kt)("inlineCode",{parentName:"li"},"+"),' action button in the right bottom corner and select "New Profile"'),(0,n.kt)("li",{parentName:"ol"},"Select a display name"),(0,n.kt)("li",{parentName:"ol"},"Select if you want to protect this profile locally with strong encryption:",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"Password: your account is protected from other people who may use this device"),(0,n.kt)("li",{parentName:"ul"},"No Password: anyone who has access to this device may be able to access this profile"))),(0,n.kt)("li",{parentName:"ol"},"Fill in your password and re-enter it"),(0,n.kt)("li",{parentName:"ol"},"Click add new profile")),(0,n.kt)("h2",{id:"a-note-on-password-protected-encrypted-profiles"},"A note on Password Protected (Encrypted) Profiles"),(0,n.kt)("p",null,"Profiles are stored locally on disk and encrypted using a key derived from user-known password (via pbkdf2)."),(0,n.kt)("p",null,"Note that, once encrypted and stored on disk, the only way to recover a profile is by rederiving the key from the password - as such it isn't possible to provide a full list of profiles a user might have access to until they enter a password."),(0,n.kt)("p",null,"See also: ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Cwtch Security Handbook: Profile Encryption & Storage")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c4773fe1.81d125b1.js b/build-staging/assets/js/c4773fe1.81d125b1.js new file mode 100644 index 00000000..c9231529 --- /dev/null +++ b/build-staging/assets/js/c4773fe1.81d125b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2612],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function i(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?o(Object(n),!0).forEach((function(e){a(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function c(t,e){if(null==t)return{};var n,r,a=function(t,e){if(null==t)return{};var n,r,a={},o=Object.keys(t);for(r=0;r<o.length;r++)n=o[r],e.indexOf(n)>=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r<o.length;r++)n=o[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var l=r.createContext({}),s=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},p=function(t){var e=s(t.components);return r.createElement(l.Provider,{value:e},t.children)},u="mdxType",h={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,o=t.originalType,l=t.parentName,p=c(t,["components","mdxType","originalType","parentName"]),u=s(n),d=a,m=u["".concat(l,".").concat(d)]||u[d]||h[d]||o;return n?r.createElement(m,i(i({ref:e},p),{},{components:n})):r.createElement(m,i({ref:e},p))}));function m(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var o=n.length,i=new Array(o);i[0]=d;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[u]="string"==typeof t?t:a,i[1]=c;for(var s=2;s<o;s++)i[s]=n[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},4457:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:2},i="Translating Cwtch",c={unversionedId:"contribute/translate",id:"contribute/translate",title:"Translating Cwtch",description:"If you would like to contribute translations to Cwtch the application or this handbook here is how",source:"@site/docs/contribute/translate.md",sourceDirName:"contribute",slug:"/contribute/translate",permalink:"/docs/contribute/translate",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/translate.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Testing Cwtch",permalink:"/docs/contribute/testing"},next:{title:"Documentation Style Guide",permalink:"/docs/contribute/documentation"}},l={},s=[{value:"Contributing Translations to the Cwtch Application",id:"contributing-translations-to-the-cwtch-application",level:2},{value:"Join our Lokalise Team",id:"join-our-lokalise-team",level:3},{value:"Directly via Git",id:"directly-via-git",level:3},{value:"Cwtch User's Handbook",id:"cwtch-users-handbook",level:2}],p={toc:s},u="wrapper";function h(t){let{components:e,...n}=t;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"translating-cwtch"},"Translating Cwtch"),(0,a.kt)("p",null,"If you would like to contribute translations to Cwtch the application or this handbook here is how"),(0,a.kt)("h2",{id:"contributing-translations-to-the-cwtch-application"},"Contributing Translations to the Cwtch Application"),(0,a.kt)("p",null,"There are two ways to contribute to Cwtch applications."),(0,a.kt)("h3",{id:"join-our-lokalise-team"},"Join our Lokalise Team"),(0,a.kt)("p",null,"We use ",(0,a.kt)("a",{parentName:"p",href:"https://lokalise.com"},"Lokalise")," for managing translations for the Cwtch application. "),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Sign up for a Lokalise account"),(0,a.kt)("li",{parentName:"ol"},"Email ",(0,a.kt)("a",{parentName:"li",href:"mailto:team@cwtch.im"},"team@cwtch.im")," with the language you are interested in translating and an email we can use to invite you to our Lokalise team.")),(0,a.kt)("h3",{id:"directly-via-git"},"Directly via Git"),(0,a.kt)("p",null,"For new translations, you can make a copy of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb")," and begin translating - you can then either ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing#cwtch-pull-request-process"},"submit pull requests or directly")," send updates to us (",(0,a.kt)("a",{parentName:"p",href:"mailto:team@cwtch.im"},"team@cwtch.im"),") and we will merge them in."),(0,a.kt)("p",null,"For adding to existing translations you can make pull requests directly on any file in ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/")," and we will review and merge them in."),(0,a.kt)("h2",{id:"cwtch-users-handbook"},"Cwtch User's Handbook"),(0,a.kt)("p",null,"This handbook is translated through ",(0,a.kt)("a",{parentName:"p",href:"https://crowdin.com"},"Crowdin"),"."),(0,a.kt)("p",null,"To join our Crowdin project:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Sign up for an account on ",(0,a.kt)("a",{parentName:"li",href:"https://crowdin.com"},"Crowdin"),"."),(0,a.kt)("li",{parentName:"ol"},"Join the ",(0,a.kt)("a",{parentName:"li",href:"https://crowdin.com/project/cwtch-users-handbook"},"cwtch-users-handbook project"),".")),(0,a.kt)("p",null,"We bundle up changes to the documentation in batches and sync them with the Crowdin project on a regular basis."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"All contributions are ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c4f5d8e4.ea3b76f3.js b/build-staging/assets/js/c4f5d8e4.ea3b76f3.js new file mode 100644 index 00000000..a46a88c5 --- /dev/null +++ b/build-staging/assets/js/c4f5d8e4.ea3b76f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4195],{3261:(e,t,n)=>{n.r(t),n.d(t,{default:()=>m});var a=n(7294),l=n(6010),r=n(7961),o=n(9960),s=n(2263);const c={heroBanner:"heroBanner_qdFl",buttons:"buttons_AeoN",button:"button_JGCe"};var i=n(5999);const u=[{id:1,title:a.createElement(i.Z,null,"The Cwtch Handbook")},{id:2,title:a.createElement(i.Z,null,"Your Guide to setting up, and using, Surveillance Resistant Infrastructure")},{id:3,title:a.createElement(i.Z,null,"Get Started With Cwtch")}];function h(){const{siteConfig:e}=(0,s.Z)();return a.createElement("header",{className:(0,l.Z)("hero hero--primary",c.heroBanner)},a.createElement("div",{className:"container"},a.createElement("h1",{className:"hero__title"},u[0].title),a.createElement("p",{className:"hero__subtitle"},u[1].title),a.createElement("div",{className:c.buttons},a.createElement(o.Z,{className:"button button--secondary button--lg",to:"/docs/intro"},u[2].title))))}function m(){const{siteConfig:e}=(0,s.Z)();return a.createElement(r.Z,{title:`${e.title}`,description:"The Cwtch Handbook"},a.createElement(h,null),a.createElement("main",null))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c747432f.a1ef6af4.js b/build-staging/assets/js/c747432f.a1ef6af4.js new file mode 100644 index 00000000..054200f4 --- /dev/null +++ b/build-staging/assets/js/c747432f.a1ef6af4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8835],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>d});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),p=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(c.Provider,{value:t},e.children)},m="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=p(n),u=a,d=m["".concat(c,".").concat(u)]||m[u]||g[u]||o;return n?i.createElement(d,r(r({ref:t},s),{},{components:n})):i.createElement(d,r({ref:t},s))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[m]="string"==typeof e?e:a,r[1]=l;for(var p=2;p<o;p++)r[p]=n[p];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},2090:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const o={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"March 3, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/blog/tags/bindings"},{label:"autobindings",permalink:"/blog/tags/autobindings"},{label:"libcwtch",permalink:"/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/blog/autobindings"}},c={authorsImageUrls:[void 0]},p=[],s={toc:p},m="wrapper";function g(e){let{components:t,...o}=e;return(0,a.kt)(m,(0,i.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c94c4dfb.5e3bcaf2.js b/build-staging/assets/js/c94c4dfb.5e3bcaf2.js new file mode 100644 index 00000000..2d748b75 --- /dev/null +++ b/build-staging/assets/js/c94c4dfb.5e3bcaf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9146],{4469:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c96c5262.b335245d.js b/build-staging/assets/js/c96c5262.b335245d.js new file mode 100644 index 00000000..59d0bcac --- /dev/null +++ b/build-staging/assets/js/c96c5262.b335245d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3761],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=c(a),h=r,u=m["".concat(s,".").concat(h)]||m[h]||d[h]||i;return a?n.createElement(u,o(o({ref:t},p),{},{components:a})):n.createElement(u,o({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:r,o[1]=l;for(var c=2;c<i;c++)o[c]=a[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},5426:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"March 29, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"release",permalink:"/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/blog/cwtch-documentation"}},s={authorsImageUrls:[void 0]},c=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},m="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(m,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(5595).Z},(0,r.kt)("img",{src:a(9573).Z,width:"1341",height:"866"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.11")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Based on new Reproducible Cwtch Stable Autobuilds")," - this is the first release of cwtch based on ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings")," in addition to our new ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Two New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Slovak")," and ",(0,r.kt)("strong",{parentName:"li"},"Korean")))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"When preserving a message draft, quoted messages are now also saved"),(0,r.kt)("li",{parentName:"ul"},"Layout issues caused by pathological unicode are now prevented"),(0,r.kt)("li",{parentName:"ul"},"Improved performance of message row rendering"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Links in replies are now selectable"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Fixed error when highlighting certain URIs "),(0,r.kt)("li",{parentName:"ul"},"File Downloading: Fixes for file downloading and exporting on 32bit Android devices"),(0,r.kt)("li",{parentName:"ul"},"Server Hosting: Fixes for several layout issues"),(0,r.kt)("li",{parentName:"ul"},"Build pipeline now runs automated UI tests"),(0,r.kt)("li",{parentName:"ul"},"Fix issues caused by scrollbar controller overriding"),(0,r.kt)("li",{parentName:"ul"},"Initial support for the Blodeuwedd Assistant (currently compile-time disabled)"),(0,r.kt)("li",{parentName:"ul"},"Cwtch Library:",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"New Stable Cwtch Peer API")),(0,r.kt)("li",{parentName:"ul"},"Ported File Downloading and Image Previews experiments into Cwtch"))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.11 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"2023-03-16-15-07-v0.0.3-1-g50c853a"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},5595:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},6094:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"},9573:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/c9a691cf.bfed5992.js b/build-staging/assets/js/c9a691cf.bfed5992.js new file mode 100644 index 00000000..7a45e11a --- /dev/null +++ b/build-staging/assets/js/c9a691cf.bfed5992.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2221],{2426:e=>{e.exports=JSON.parse('{"title":"Behaviour","slug":"/category/behaviour","permalink":"/docs/category/behaviour","navigation":{"previous":{"title":"Streamer/Presentation Mode","permalink":"/docs/settings/appearance/streamer-mode"},"next":{"title":"Block Unknown Connections","permalink":"/docs/settings/behaviour/block-unknown-connections"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/cc8d20ec.cf2d6d7c.js b/build-staging/assets/js/cc8d20ec.cf2d6d7c.js new file mode 100644 index 00000000..48082b26 --- /dev/null +++ b/build-staging/assets/js/cc8d20ec.cf2d6d7c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5035],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>b});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),f=c(n),d=i,b=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return n?r.createElement(b,a(a({ref:t},p),{},{components:n})):r.createElement(b,a({ref:t},p))}));function b(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[f]="string"==typeof e?e:i,a[1]=s;for(var c=2;c<o;c++)a[c]=n[c];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},7672:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:15},a="Setting Profile Attributes",s={unversionedId:"profiles/profile-info",id:"profiles/profile-info",title:"Setting Profile Attributes",description:"New in Cwtch 1.12",source:"@site/docs/profiles/profile-info.md",sourceDirName:"profiles",slug:"/profiles/profile-info",permalink:"/docs/profiles/profile-info",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/profile-info.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_position:15},sidebar:"tutorialSidebar",previous:{title:"Setting Availability Status",permalink:"/docs/profiles/availability-status"},next:{title:"Conversations",permalink:"/docs/category/conversations"}},l={},c=[],p={toc:c},f="wrapper";function u(e){let{components:t,...o}=e;return(0,i.kt)(f,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-profile-attributes"},"Setting Profile Attributes"),(0,i.kt)("admonition",{title:"New Feature",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"New in ",(0,i.kt)("a",{parentName:"p",href:"/blog/cwtch-nightly-1-12"},"Cwtch 1.12")),(0,i.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,i.kt)("p",null,"On the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/introduction#manage-profiles"},"profile management pane")," there are three free-form text fields below your profile picture."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(92).Z},(0,i.kt)("img",{src:n(6852).Z,width:"783",height:"354"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"You can fill these fields with any information your would like potential contacts to know. ",(0,i.kt)("strong",{parentName:"p"},"This information is public")," - do not put any information in here that you do not want to share with everyone."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(2243).Z},(0,i.kt)("img",{src:n(3506).Z,width:"730",height:"342"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Contacts will be able to see this information in ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/conversation-settings"},"conversation settings")),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(5637).Z},(0,i.kt)("img",{src:n(136).Z,width:"294",height:"195"}))),(0,i.kt)("figcaption",null)))}u.isMDXComponent=!0},5637:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},92:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png"},2243:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},136:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},6852:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png"},3506:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ccc49370.c18e6548.js b/build-staging/assets/js/ccc49370.c18e6548.js new file mode 100644 index 00000000..d1c27295 --- /dev/null +++ b/build-staging/assets/js/ccc49370.c18e6548.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6103],{5203:(e,t,n)=>{n.r(t),n.d(t,{default:()=>h});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),i=n(9460),c=n(9058),s=n(1286),m=n(7462),d=n(5999),u=n(2244);function g(e){const{nextItem:t,prevItem:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,d.I)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"})},n&&a.createElement(u.Z,(0,m.Z)({},n,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post"},"Newer Post")})),t&&a.createElement(u.Z,(0,m.Z)({},t,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post"},"Older Post"),isNext:!0})))}function f(){const{assets:e,metadata:t}=(0,i.C)(),{title:n,description:l,date:r,tags:c,authors:s,frontMatter:m}=t,{keywords:d}=m,u=e.image??m.image;return a.createElement(o.d,{title:n,description:l,keywords:d,image:u},a.createElement("meta",{property:"og:type",content:"article"}),a.createElement("meta",{property:"article:published_time",content:r}),s.some((e=>e.url))&&a.createElement("meta",{property:"article:author",content:s.map((e=>e.url)).filter(Boolean).join(",")}),c.length>0&&a.createElement("meta",{property:"article:tag",content:c.map((e=>e.label)).join(",")}))}var v=n(9407);function p(e){let{sidebar:t,children:n}=e;const{metadata:l,toc:o}=(0,i.C)(),{nextItem:r,prevItem:m,frontMatter:d}=l,{hide_table_of_contents:u,toc_min_heading_level:f,toc_max_heading_level:p}=d;return a.createElement(c.Z,{sidebar:t,toc:!u&&o.length>0?a.createElement(v.Z,{toc:o,minHeadingLevel:f,maxHeadingLevel:p}):void 0},a.createElement(s.Z,null,n),(r||m)&&a.createElement(g,{nextItem:r,prevItem:m}))}function h(e){const t=e.content;return a.createElement(i.n,{content:e.content,isBlogPostPage:!0},a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.blogPages,r.k.page.blogPostPage)},a.createElement(f,null),a.createElement(p,{sidebar:e.sidebar},a.createElement(t,null))))}},9407:(e,t,n)=>{n.d(t,{Z:()=>m});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",s="table-of-contents__link--active";function m(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(i.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:s})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>f});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function s(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(c(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function m(){const e=(0,l.useRef)(0),{navbar:{hideOnScroll:t}}=(0,o.L)();return(0,l.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,l.useRef)(void 0),n=m();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function i(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),i=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=s(i,{anchorTopOffset:n.current}),m=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===m)}))}return document.addEventListener("scroll",i),document.addEventListener("resize",i),i(),()=>{document.removeEventListener("scroll",i),document.removeEventListener("resize",i)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const g=l.memo(u);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:s,minHeadingLevel:m,maxHeadingLevel:u,...f}=e;const v=(0,o.L)(),p=m??v.tableOfContents.minHeadingLevel,h=u??v.tableOfContents.maxHeadingLevel,b=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:p,maxHeadingLevel:h});return d((0,l.useMemo)((()=>{if(c&&s)return{linkClassName:c,linkActiveClassName:s,minHeadingLevel:p,maxHeadingLevel:h}}),[c,s,p,h])),l.createElement(g,(0,a.Z)({toc:b,className:n,linkClassName:c},f))}}}]); \ No newline at end of file diff --git a/build-staging/assets/js/cda43b61.56b225ab.js b/build-staging/assets/js/cda43b61.56b225ab.js new file mode 100644 index 00000000..e8958970 --- /dev/null +++ b/build-staging/assets/js/cda43b61.56b225ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6539],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>y});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(n),f=o,y=u["".concat(s,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(y,c(c({ref:t},l),{},{components:n})):r.createElement(y,c({ref:t},l))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=f;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[u]="string"==typeof e?e:o,c[1]=i;for(var p=2;p<a;p++)c[p]=n[p];return r.createElement.apply(null,c)}return r.createElement.apply(null,n)}f.displayName="MDXCreateElement"},7206:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:2},c="Accepting/Denying New Conversations",i={unversionedId:"chat/accept-deny-new-conversation",id:"chat/accept-deny-new-conversation",title:"Accepting/Denying New Conversations",description:"1. Go to your profile",source:"@site/docs/chat/accept-deny-new-conversation.md",sourceDirName:"chat",slug:"/chat/accept-deny-new-conversation",permalink:"/docs/chat/accept-deny-new-conversation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/accept-deny-new-conversation.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Starting a New Conversation",permalink:"/docs/chat/add-contact"},next:{title:"Sharing Cwtch Addresses",permalink:"/docs/chat/share-address-with-friends"}},s={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"acceptingdenying-new-conversations"},"Accepting/Denying New Conversations"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to your profile"),(0,o.kt)("li",{parentName:"ol"},"If someone added you a new name will appear and two options",(0,o.kt)("ol",{parentName:"li"},(0,o.kt)("li",{parentName:"ol"},"Click heart icon to accept this new connection"),(0,o.kt)("li",{parentName:"ol"},"Click the trash icon to block them")))),(0,o.kt)("p",null,"See also: ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/behaviour/block-unknown-connections"},"Setting: Block Unknown Connections")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ce314f92.81151742.js b/build-staging/assets/js/ce314f92.81151742.js new file mode 100644 index 00000000..dc14a92c --- /dev/null +++ b/build-staging/assets/js/ce314f92.81151742.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6965],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>h});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,h=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(h,i(i({ref:t},p),{},{components:n})):r.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var l=2;l<o;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},6672:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1},i="Running Cwtch on Tails",s={unversionedId:"platforms/tails",id:"platforms/tails",title:"Running Cwtch on Tails",description:"New in Cwtch 1.12",source:"@site/docs/platforms/tails.md",sourceDirName:"platforms",slug:"/platforms/tails",permalink:"/docs/platforms/tails",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/platforms/tails.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Platforms",permalink:"/docs/category/platforms"}},c={},l=[{value:"Onion Grater Configuration",id:"onion-grater-configuration",level:2},{value:"Persistence",id:"persistence",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"running-cwtch-on-tails"},"Running Cwtch on Tails"),(0,a.kt)("admonition",{title:"New Feature",type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"New in ",(0,a.kt)("a",{parentName:"p",href:"/blog/cwtch-nightly-1-12"},"Cwtch 1.12")),(0,a.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,a.kt)("p",null,"The following steps require that Tails has been launched with an ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/first_steps/welcome_screen/administration_password/"},"Administration Password"),"."),(0,a.kt)("p",null,"Tails uses ",(0,a.kt)("a",{parentName:"p",href:"https://gitlab.tails.boum.org/tails/tails/-/blob/master/config/chroot_local-includes/usr/local/lib/onion-grater#L3"},"Onion Grater")," to guard access to the control port. We have packaged\nan oniongrater configuration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," and setup script (",(0,a.kt)("inlineCode",{parentName:"p"},"install-tails.sh"),") with Cwtch on Linux."),(0,a.kt)("p",null,"The tails-specific part of the script is reproduced below:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," # Tails needs to be have been setup up with an Administration account\n # \n # Make Auth Cookie Readable\n sudo chmod o+r /var/run/tor/control.authcookie\n # Copy Onion Grater Config\n sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml\n # Restart Onion Grater so the Config Takes effect\n sudo systemctl restart onion-grater.service\n")),(0,a.kt)("p",null,"When launching, Cwtch on Tails should be passed the ",(0,a.kt)("inlineCode",{parentName:"p"},"CWTCH_TAILS=true")," environment variable to automatically configure Cwtch for running in a Tails-like environment:"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch")),(0,a.kt)("admonition",{title:"Install Location",type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The above command, and the below onion grater configuration assume that Cwtch was installed in ",(0,a.kt)("inlineCode",{parentName:"p"},"~/.local/lib/cwtch/cwtch")," - if Cwtch was installed somewhere else (or if you are running directly from the download folder) then you will need to adjust the commands.")),(0,a.kt)("h2",{id:"onion-grater-configuration"},"Onion Grater Configuration"),(0,a.kt)("p",null,"The oniongrater configuration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," is reproduced below. As noted this configuration is can likely be restricted much\nfurther. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," ---\n # TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern\n - apparmor-profiles:\n - '/home/amnesia/.local/lib/cwtch/cwtch'\n users:\n - 'amnesia'\n commands:\n AUTHCHALLENGE:\n - 'SAFECOOKIE .*'\n SETEVENTS:\n - 'CIRC WARN ERR'\n - 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'\n GETINFO:\n - '.*'\n GETCONF:\n - 'DisableNetwork'\n SETCONF:\n - 'DisableNetwork.*'\n ADD_ONION:\n - '.*'\n DEL_ONION:\n - '.+'\n HSFETCH:\n - '.+'\n events:\n CIRC:\n suppress: true\n ORCONN:\n suppress: true\n INFO:\n suppress: true\n NOTICE:\n suppress: true\n WARN:\n suppress: true\n ERR:\n suppress: true\n HS_DESC:\n response:\n - pattern: '650 HS_DESC CREATED (\\S+) (\\S+) (\\S+) \\S+ (.+)'\n replacement: '650 HS_DESC CREATED {} {} {} redacted {}'\n - pattern: '650 HS_DESC UPLOAD (\\S+) (\\S+) .*'\n replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'\n - pattern: '650 HS_DESC UPLOADED (\\S+) (\\S+) .+'\n replacement: '650 HS_DESC UPLOADED {} {} redacted'\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH'\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'\n - pattern: '650 HS_DESC RECEIVED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'\n - pattern: '.*'\n replacement: ''\n HS_DESC_CONTENT:\n suppress: true\n")),(0,a.kt)("h2",{id:"persistence"},"Persistence"),(0,a.kt)("p",null,"By default, Cwtch creates ",(0,a.kt)("inlineCode",{parentName:"p"},"$HOME/.cwtch")," and saves all encrypted profiles and settings files there. In order to save any profiles/conversations in Cwtch on Tails you will have to backup this folder to a non-volatile home."),(0,a.kt)("p",null,"See the Tails documentation for setting up ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/persistent_storage/"},"persistent storage")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ce4b3243.db7c61a0.js b/build-staging/assets/js/ce4b3243.db7c61a0.js new file mode 100644 index 00000000..7e2e0033 --- /dev/null +++ b/build-staging/assets/js/ce4b3243.db7c61a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1179],{1250:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/autobindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/d39fd6c2.0adaf6be.js b/build-staging/assets/js/d39fd6c2.0adaf6be.js new file mode 100644 index 00000000..c98d61ee --- /dev/null +++ b/build-staging/assets/js/d39fd6c2.0adaf6be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5230],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),h=p(n),u=r,m=h["".concat(c,".").concat(u)]||h[u]||d[u]||o;return n?a.createElement(m,i(i({ref:t},l),{},{components:n})):a.createElement(m,i({ref:t},l))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[h]="string"==typeof e?e:r,i[1]=s;for(var p=2;p<o;p++)i[p]=n[p];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}u.displayName="MDXCreateElement"},1007:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const o={sidebar_position:1},i="Cwtch Security Handbook",s={unversionedId:"intro",id:"intro",title:"Cwtch Security Handbook",description:"Welcome to the Cwtch Secure Development Handbook! The purpose of this",source:"@site/security/intro.md",sourceDirName:".",slug:"/intro",permalink:"/security/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Risk Model",permalink:"/security/risk"}},c={},p=[{value:"What is Cwtch?",id:"what-is-cwtch",level:2},{value:"A (Brief) History of Metadata Resistant Chat",id:"a-brief-history-of-metadata-resistant-chat",level:2}],l={toc:p},h="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(h,(0,a.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"cwtch-security-handbook"},"Cwtch Security Handbook"),(0,r.kt)("p",null,"Welcome to the Cwtch Secure Development Handbook! The purpose of this\nhandbook is to provide a guide to the various components of the Cwtch\necosystem, to document the known risks and mitigations, and to enable\ndiscussion about improvements and updates to Cwtch secure development\nprocesses."),(0,r.kt)("p",null,(0,r.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/2.png",alt:null})),(0,r.kt)("h2",{id:"what-is-cwtch"},"What is Cwtch?"),(0,r.kt)("p",null,"Cwtch (/k\u028at\u0283/ - a Welsh word roughly translating to \u201ca hug that creates a safe place\u201d) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Decentralized and Open"),": There is no \u201cCwtch service\u201d or \u201cCwtch network\u201d. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Privacy Preserving"),": All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Metadata Resistant"),": Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.")),(0,r.kt)("h2",{id:"a-brief-history-of-metadata-resistant-chat"},"A (Brief) History of Metadata Resistant Chat"),(0,r.kt)("p",null,"In recent years, public awareness of the need and benefits of end-to-end\nencrypted solutions has increased with applications like ",(0,r.kt)("a",{parentName:"p",href:"https://signalapp.org"},"Signal"),",\n",(0,r.kt)("a",{parentName:"p",href:"https://whatsapp.com"},"Whatsapp")," and ",(0,r.kt)("a",{parentName:"p",href:"https://wire.org"},"Wire")," now providing\nusers with secure communications."),(0,r.kt)("p",null,"However, these tools require various levels of metadata exposure to function,\nand much of this metadata can be used to gain details about how and why a person\nis using a tool to communicate. ",(0,r.kt)("a",{parentName:"p",href:"https://www.researchgate.net/profile/Peter_Kieseberg/publication/299984940_Privacy_and_data_protection_in_smartphone_messengers/links/5a1a9c29a6fdcc50adeb1335/Privacy-and-data-protection-in-smartphone-messengers.pdf"},"[rottermanner2015privacy]"),"."),(0,r.kt)("p",null,"One tool that did seek to reduce metadata is ",(0,r.kt)("a",{parentName:"p",href:"https://ricochet.im"},"Ricochet")," first released in 2014.\nRicochet used Tor v2 onion services to provide secure end-to-end encrypted communication,\nand to protect the metadata of communications."),(0,r.kt)("p",null,"There were no centralized servers that assist in routing Ricochet\nconversations. No one other than the parties involved in a conversation could\nknow that such a conversation is taking place."),(0,r.kt)("p",null,"Ricochet wasn't without limitations; there was no multi-device support, nor is\nthere a mechanism for supporting group communication or for a user to send\nmessages while a contact is offline."),(0,r.kt)("p",null,"This made adoption of Ricochet a difficult proposition; with even those in\nenvironments that would be served best by metadata resistance unaware that it\nexists ",(0,r.kt)("a",{parentName:"p",href:"https://www.academia.edu/download/53192589/ermoshina-12.pdf"},"[ermoshina2017can]"),"\n",(0,r.kt)("a",{parentName:"p",href:"https://eprints.gla.ac.uk/116203/1/116203.pdf"},"[renaud2014doesn]"),"."),(0,r.kt)("p",null,"Additionally, any solution to decentralized, metadata resistant communication faces ",(0,r.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"fundamental problems"),"\nwhen it comes to efficiency, privacy and group security (as defined by ",(0,r.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"transcript consensus and consistency"),")."),(0,r.kt)("p",null,"Modern alternatives to Ricochet include ",(0,r.kt)("a",{parentName:"p",href:"https://briarproject.org"},"Briar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://www.zbay.app/"},"Zbay"),"\nand ",(0,r.kt)("a",{parentName:"p",href:"https://www.ricochetrefresh.net/"},"Ricochet Refresh")," - each tool seeks to optimize for a different\nset of trade-offs e.g. Briar seeks to allow people to communicate ",(0,r.kt)("a",{parentName:"p",href:"https://briarproject.org/how-it-works/"},"even when underlying network infrastructure\nis down")," while providing resistant to metadata surveillance."),(0,r.kt)("hr",null),(0,r.kt)("p",null,"The Cwtch project began in 2017 as an extension protocol for Ricochet providing group conversations via\nuntrusted servers, with an eye to enabling decentralized, metadata resistant applications (like shared lists\nand bulletin board)"),(0,r.kt)("p",null,"An alpha version of Cwtch was ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/blog/2019/02/14/cwtch-alpha/"},"was launched in February 2019"),", and\nsince then the Cwtch team (run by the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca"},"Open Privacy Research Society"),") has conducted\nresearch and development into Cwtch and the underlying protocols and libraries and problem spaces."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/d5f314f9.1dc05f26.js b/build-staging/assets/js/d5f314f9.1dc05f26.js new file mode 100644 index 00000000..02f13a12 --- /dev/null +++ b/build-staging/assets/js/d5f314f9.1dc05f26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5869],{9317:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-developer"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/d66d73fd.ef585879.js b/build-staging/assets/js/d66d73fd.ef585879.js new file mode 100644 index 00000000..18179c3a --- /dev/null +++ b/build-staging/assets/js/d66d73fd.ef585879.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8858],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(r),m=o,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return r?n.createElement(h,s(s({ref:t},p),{},{components:r})):n.createElement(h,s({ref:t},p))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:o,s[1]=a;for(var c=2;c<i;c++)s[c]=r[c];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},6089:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={},s="Development",a={unversionedId:"development",id:"development",title:"Development",description:"The main process to counter malicious actors in development of Cwtch is the",source:"@site/security/development.md",sourceDirName:".",slug:"/development",permalink:"/security/development",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Deployment",permalink:"/security/deployment"},next:{title:"References",permalink:"/security/references"}},l={},c=[{value:"Risk: Developer Directly Pushes Malicious Code",id:"risk-developer-directly-pushes-malicious-code",level:3},{value:"Risk: Code Regressions",id:"risk-code-regressions",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"development"},"Development"),(0,o.kt)("p",null,"The main process to counter malicious actors in development of Cwtch is the\nopenness of the process."),(0,o.kt)("p",null,"To enhance this openness, automated builds, testing and packaging are defined\nas part of the repositories - improving te robustness of the code base at every\nstage."),(0,o.kt)("p",null,(0,o.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/1.png",alt:null})),(0,o.kt)("p",null,"While individual tests aren't perfect, and all processes have gaps, we should be\ncommitted to make it as easy as possible to contribute to Cwtch while also\nbuilding pipelines and processes that catch errors (unintential or malicious)\nas soon as possible."),(0,o.kt)("h3",{id:"risk-developer-directly-pushes-malicious-code"},"Risk: Developer Directly Pushes Malicious Code"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Mitigated")," "),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"trunk")," is currently locked and only 3 Open Privacy staff members have permission\nto override it, in addition the responsibility of monitoring changes."),(0,o.kt)("p",null,"Further every new pull request and merge triggered automated builds & tests\nwhich trigger emails and audit logs."),(0,o.kt)("p",null,"The code is also open source and inspectable by anyone."),(0,o.kt)("h3",{id:"risk-code-regressions"},"Risk: Code Regressions"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (See individual project entries in this\nhandbook for more information)"),(0,o.kt)("p",null,"Our automated pipelines have the ability to catch regressions when that\nbehaviour is detectable."),(0,o.kt)("p",null,"The greatest challenge is in defining how such regressions are detected for the\n",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," - where behaviour isn't as strictly defined as it is for the\nindividual libraries."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/d6a44406.32dd75f8.js b/build-staging/assets/js/d6a44406.32dd75f8.js new file mode 100644 index 00000000..51fc9d38 --- /dev/null +++ b/build-staging/assets/js/d6a44406.32dd75f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3213],{3260:a=>{a.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/blog/tags/cwtch-stable","allTagsPath":"/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/dc098020.5e625d3e.js b/build-staging/assets/js/dc098020.5e625d3e.js new file mode 100644 index 00000000..fee1c0b5 --- /dev/null +++ b/build-staging/assets/js/dc098020.5e625d3e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6682],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>y});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=c(r),m=i,y=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(y,a(a({ref:t},u),{},{components:r})):n.createElement(y,a({ref:t},u))}));function y(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:i,a[1]=l;for(var c=2;c<o;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},258:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={},a="Deployment",l={unversionedId:"deployment",id:"deployment",title:"Deployment",description:"Risk: Binaries are replaced on the website with malicious ones",source:"@site/security/deployment.md",sourceDirName:".",slug:"/deployment",permalink:"/security/deployment",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Message Overlays",permalink:"/security/components/ui/overlays"},next:{title:"Development",permalink:"/security/development"}},s={},c=[{value:"Risk: Binaries are replaced on the website with malicious ones",id:"risk-binaries-are-replaced-on-the-website-with-malicious-ones",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deployment"},"Deployment"),(0,i.kt)("h2",{id:"risk-binaries-are-replaced-on-the-website-with-malicious-ones"},"Risk: Binaries are replaced on the website with malicious ones"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Partially-mitigated")),(0,i.kt)("p",null,"While this process is now mostly automated, should this automation ever be\ncompromised then there is nothing in our current process that would detect this."),(0,i.kt)("p",null,"We need:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Reproducible Builds - we currently use public docker containers for all builds\nwhich should allow anyone to compare distributed builds with ones built from source."),(0,i.kt)("li",{parentName:"ul"},"Signed Releases - Open Privacy does not yet maintain a public record of staff\npublic keys. This is likely a necessity for signing released builds and\ncreating an audit chain backed by the organization. This process must be\nmanual by definition.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/dc3c323e.a0698420.js b/build-staging/assets/js/dc3c323e.a0698420.js new file mode 100644 index 00000000..9448f4d7 --- /dev/null +++ b/build-staging/assets/js/dc3c323e.a0698420.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[564],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=s(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:o,i[1]=p;for(var s=2;s<a;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},2909:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:3},i="Creating a New Group",p={unversionedId:"groups/create-group",id:"groups/create-group",title:"Creating a New Group",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/create-group.md",sourceDirName:"groups",slug:"/groups/create-group",permalink:"/docs/groups/create-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/create-group.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"An Introduction to Cwtch Groups",permalink:"/docs/groups/introduction"},next:{title:"Sending Invites to a Group",permalink:"/docs/groups/send-invite"}},c={},s=[],u={toc:s},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"creating-a-new-group"},"Creating a New Group"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"On your contacts pane"),(0,o.kt)("li",{parentName:"ol"},"Press on the plus action button"),(0,o.kt)("li",{parentName:"ol"},"Press on Create Group"),(0,o.kt)("li",{parentName:"ol"},"Name your Group"),(0,o.kt)("li",{parentName:"ol"},"Press on Create")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Create.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/df814c0d.33d74f39.js b/build-staging/assets/js/df814c0d.33d74f39.js new file mode 100644 index 00000000..0eac4f07 --- /dev/null +++ b/build-staging/assets/js/df814c0d.33d74f39.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6494],{2637:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/developer-documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/e4fed92d.91dd9f20.js b/build-staging/assets/js/e4fed92d.91dd9f20.js new file mode 100644 index 00000000..5702e933 --- /dev/null +++ b/build-staging/assets/js/e4fed92d.91dd9f20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4995],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),y=a,f=u["".concat(c,".").concat(y)]||u[y]||m[y]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=y;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var l=2;l<o;l++)i[l]=r[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}y.displayName="MDXCreateElement"},6142:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:5},i="Replying to a Message",s={unversionedId:"chat/reply-to-message",id:"chat/reply-to-message",title:"Replying to a Message",description:"1. Select a message you want to reply to",source:"@site/docs/chat/reply-to-message.md",sourceDirName:"chat",slug:"/chat/reply-to-message",permalink:"/docs/chat/reply-to-message",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/reply-to-message.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Accessing Conversation Settings",permalink:"/docs/chat/conversation-settings"},next:{title:"Sharing a File",permalink:"/docs/chat/share-file"}},c={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"replying-to-a-message"},"Replying to a Message"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Select a message you want to reply to"),(0,a.kt)("li",{parentName:"ol"},"Pull a message right"),(0,a.kt)("li",{parentName:"ol"},"Write an answer to the quoted message"),(0,a.kt)("li",{parentName:"ol"},"Hit send")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/e62fac9c.692a9f49.js b/build-staging/assets/js/e62fac9c.692a9f49.js new file mode 100644 index 00000000..dfe7e153 --- /dev/null +++ b/build-staging/assets/js/e62fac9c.692a9f49.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8292],{4572:e=>{e.exports=JSON.parse('{"label":"reproducible-builds","permalink":"/blog/tags/reproducible-builds","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/e88d32a9.ff20b8ba.js b/build-staging/assets/js/e88d32a9.ff20b8ba.js new file mode 100644 index 00000000..e319e33e --- /dev/null +++ b/build-staging/assets/js/e88d32a9.ff20b8ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6585],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/e92b958d.0d8dfab1.js b/build-staging/assets/js/e92b958d.0d8dfab1.js new file mode 100644 index 00000000..d12010c7 --- /dev/null +++ b/build-staging/assets/js/e92b958d.0d8dfab1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7011],{1954:a=>{a.exports=JSON.parse('{"label":"planning","permalink":"/blog/tags/planning","allTagsPath":"/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/eb09219a.8186cc5c.js b/build-staging/assets/js/eb09219a.8186cc5c.js new file mode 100644 index 00000000..bb6fe156 --- /dev/null +++ b/build-staging/assets/js/eb09219a.8186cc5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5327],{2242:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/security-handbook","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/eb183be6.523c05ca.js b/build-staging/assets/js/eb183be6.523c05ca.js new file mode 100644 index 00000000..f895b944 --- /dev/null +++ b/build-staging/assets/js/eb183be6.523c05ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1596],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},f="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),f=s(r),u=o,d=f["".concat(p,".").concat(u)]||f[u]||m[u]||i;return r?n.createElement(d,a(a({ref:t},c),{},{components:r})):n.createElement(d,a({ref:t},c))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=u;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[f]="string"==typeof e?e:o,a[1]=l;for(var s=2;s<i;s++)a[s]=r[s];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},5940:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:11},a="Importing a Profile",l={unversionedId:"profiles/importing-a-profile",id:"profiles/importing-a-profile",title:"Importing a Profile",description:'1. Press the + action button in the right bottom corner and select "Import Profile"',source:"@site/docs/profiles/importing-a-profile.md",sourceDirName:"profiles",slug:"/profiles/importing-a-profile",permalink:"/docs/profiles/importing-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/importing-a-profile.md",tags:[],version:"current",sidebarPosition:11,frontMatter:{sidebar_position:11},sidebar:"tutorialSidebar",previous:{title:"Backup or Exporting a Profile",permalink:"/docs/profiles/exporting-profile"},next:{title:"Setting Availability Status",permalink:"/docs/profiles/availability-status"}},p={},s=[],c={toc:s},f="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(f,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"importing-a-profile"},"Importing a Profile"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Press the ",(0,o.kt)("inlineCode",{parentName:"li"},"+"),' action button in the right bottom corner and select "Import Profile"'),(0,o.kt)("li",{parentName:"ol"},"Select an ",(0,o.kt)("a",{parentName:"li",href:"/docs/profiles/exporting-profile"},"exported Cwtch profile file")," to import"),(0,o.kt)("li",{parentName:"ol"},"Enter the ",(0,o.kt)("a",{parentName:"li",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"password")," associated with the profile\nand confirm.")),(0,o.kt)("p",null,"Once confirmed, Cwtch will attempt to decrypt the provided file using a key derived from the given password. If successful\nthe profile will appear on the Profile Management screen and will be ready to use."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"While a profile can be imported onto multiple devices, currently only one version of a profile can be in-use across all devices at any one time."),(0,o.kt)("p",{parentName:"admonition"},"Attempts to use the same profile across multiple devices may result in availability issues and messaging failures.")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ebdffa2e.d46295b6.js b/build-staging/assets/js/ebdffa2e.d46295b6.js new file mode 100644 index 00000000..06347b61 --- /dev/null +++ b/build-staging/assets/js/ebdffa2e.d46295b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4710],{5797:a=>{a.exports=JSON.parse('{"label":"libcwtch","permalink":"/blog/tags/libcwtch","allTagsPath":"/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ed85aa58.fdf5814c.js b/build-staging/assets/js/ed85aa58.fdf5814c.js new file mode 100644 index 00000000..ec56a1a9 --- /dev/null +++ b/build-staging/assets/js/ed85aa58.fdf5814c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1987],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>h});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?s(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function i(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},s=Object.keys(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},y=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(t),y=o,h=u["".concat(c,".").concat(y)]||u[y]||d[y]||s;return t?n.createElement(h,a(a({ref:r},l),{},{components:t})):n.createElement(h,a({ref:r},l))}));function h(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var s=t.length,a=new Array(s);a[0]=y;var i={};for(var c in r)hasOwnProperty.call(r,c)&&(i[c]=r[c]);i.originalType=e,i[u]="string"==typeof e?e:o,a[1]=i;for(var p=2;p<s;p++)a[p]=t[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}y.displayName="MDXCreateElement"},274:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const s={sidebar_position:5},a="How to share your Server Key Bundle",i={unversionedId:"servers/share-key",id:"servers/share-key",title:"How to share your Server Key Bundle",description:"This feature requires Experiments Enabled and",source:"@site/docs/servers/share-key.md",sourceDirName:"servers",slug:"/servers/share-key",permalink:"/docs/servers/share-key",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/share-key.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"How to delete server",permalink:"/docs/servers/delete-server"},next:{title:"How to Unlock a server",permalink:"/docs/servers/unlock-server"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"how-to-share-your-server-key-bundle"},"How to share your Server Key Bundle"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," turned on.")),(0,o.kt)("p",null,"Your server key bundle is the package of data a Cwtch app needs in order to use a server. If you just want to make other Cwtch users aware of your server, you can share this with them. Then they will have the ability to create their own groups on the server."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to the server Icon"),(0,o.kt)("li",{parentName:"ol"},"Select the server you want"),(0,o.kt)("li",{parentName:"ol"},"Use the copy address icon to copy the server keys"),(0,o.kt)("li",{parentName:"ol"},"Don\u2019t share the keys with people you don\u2019t trust")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Keys.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ed9713f0.54ba7352.js b/build-staging/assets/js/ed9713f0.54ba7352.js new file mode 100644 index 00000000..a3899340 --- /dev/null +++ b/build-staging/assets/js/ed9713f0.54ba7352.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7820],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),s=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(n),m=a,g=u["".concat(p,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(g,i(i({ref:t},c),{},{components:n})):r.createElement(g,i({ref:t},c))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[u]="string"==typeof e?e:a,i[1]=l;for(var s=2;s<o;s++)i[s]=n[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},7887:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:2},i="Light/Dark and themes Breakdown",l={unversionedId:"settings/appearance/light-dark-mode",id:"settings/appearance/light-dark-mode",title:"Light/Dark and themes Breakdown",description:"1. Press the setting icon",source:"@site/docs/settings/appearance/light-dark-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/light-dark-mode",permalink:"/docs/settings/appearance/light-dark-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/light-dark-mode.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Change Language",permalink:"/docs/settings/appearance/change-language"},next:{title:"UI columns",permalink:"/docs/settings/appearance/ui-columns"}},p={},s=[],c={toc:s},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"lightdark-and-themes-breakdown"},"Light/Dark and themes Breakdown"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Press the setting icon"),(0,a.kt)("li",{parentName:"ol"},"You can choose light or dark theme by toggling the \u201cuse light themes\u201d switch"),(0,a.kt)("li",{parentName:"ol"},"Using the \u201ccolor theme\u201d drop down menu, pick a theme you like"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("ol",{parentName:"li"},(0,a.kt)("li",{parentName:"ol"},"Cwtch: purple tones "),(0,a.kt)("li",{parentName:"ol"},"Ghost: Grey tones"),(0,a.kt)("li",{parentName:"ol"},"Mermaid: Turquoise and\npurple tones"),(0,a.kt)("li",{parentName:"ol"},"Midnight: Black and gray tones"),(0,a.kt)("li",{parentName:"ol"},"Neon 1: purple and pink tones"),(0,a.kt)("li",{parentName:"ol"},"Neon 2: purple and turquoise tones"),(0,a.kt)("li",{parentName:"ol"},"Pumpkin: purple and orange tones"),(0,a.kt)("li",{parentName:"ol"},"Witch: Green and pink tones"),(0,a.kt)("li",{parentName:"ol"},"Vampire: Purple and red tones")))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ef243df7.f9f0874b.js b/build-staging/assets/js/ef243df7.f9f0874b.js new file mode 100644 index 00000000..f22f5caf --- /dev/null +++ b/build-staging/assets/js/ef243df7.f9f0874b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7667],{4354:e=>{e.exports=JSON.parse('{"permalink":"/blog/tags/planning","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/ef78badf.d2787367.js b/build-staging/assets/js/ef78badf.d2787367.js new file mode 100644 index 00000000..749cd31b --- /dev/null +++ b/build-staging/assets/js/ef78badf.d2787367.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5532],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var a=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,a,o=function(e,t){if(null==e)return{};var r,a,o={},n=Object.keys(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=a.createContext({}),s=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,o=e.mdxType,n=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=s(r),h=o,f=u["".concat(p,".").concat(h)]||u[h]||m[h]||n;return r?a.createElement(f,l(l({ref:t},c),{},{components:r})):a.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=r.length,l=new Array(n);l[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var s=2;s<n;s++)l[s]=r[s];return a.createElement.apply(null,l)}return a.createElement.apply(null,r)}h.displayName="MDXCreateElement"},5481:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>m,frontMatter:()=>n,metadata:()=>i,toc:()=>s});var a=r(7462),o=(r(7294),r(3905));const n={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"January 27, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"support",permalink:"/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/blog/cwtch-bindings-reproducible"}},p={authorsImageUrls:[void 0]},s=[],c={toc:s},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"One of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,o.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,o.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,o.kt)("p",null,"The questions we aim to answer in this post are: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,o.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,o.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,o.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,o.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(6149).Z,width:"1005",height:"481"})))}m.isMDXComponent=!0},6149:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/efb69e30.634fd7c7.js b/build-staging/assets/js/efb69e30.634fd7c7.js new file mode 100644 index 00000000..5fbb2f39 --- /dev/null +++ b/build-staging/assets/js/efb69e30.634fd7c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4003],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),g=o,d=u["".concat(s,".").concat(g)]||u[g]||f[g]||a;return n?r.createElement(d,i(i({ref:t},p),{},{components:n})):r.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var l=2;l<a;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}g.displayName="MDXCreateElement"},2676:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:5},i="Accessing Conversation Settings",c={unversionedId:"chat/conversation-settings",id:"chat/conversation-settings",title:"Accessing Conversation Settings",description:"In a conversation window, click on the Settings icon in the top bar.",source:"@site/docs/chat/conversation-settings.md",sourceDirName:"chat",slug:"/chat/conversation-settings",permalink:"/docs/chat/conversation-settings",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/conversation-settings.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Message Formatting",permalink:"/docs/chat/message-formatting"},next:{title:"Replying to a Message",permalink:"/docs/chat/reply-to-message"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:t,...a}=e;return(0,o.kt)(u,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accessing-conversation-settings"},"Accessing Conversation Settings"),(0,o.kt)("p",null,"In a conversation window, click on the Settings icon in the top bar."),(0,o.kt)("figure",null,(0,o.kt)("p",null,(0,o.kt)("a",{target:"_blank",href:n(671).Z},(0,o.kt)("img",{src:n(6305).Z,width:"624",height:"257"}))),(0,o.kt)("figcaption",null)),(0,o.kt)("p",null,"This action will open up a new screen where you can view and manage the contact."),(0,o.kt)("figure",null,(0,o.kt)("p",null,(0,o.kt)("a",{target:"_blank",href:n(4306).Z},(0,o.kt)("img",{src:n(2289).Z,width:"937",height:"689"}))),(0,o.kt)("figcaption",null)))}f.isMDXComponent=!0},4306:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png"},671:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png"},2289:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png"},6305:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f041e880.789e430d.js b/build-staging/assets/js/f041e880.789e430d.js new file mode 100644 index 00000000..8f614b7b --- /dev/null +++ b/build-staging/assets/js/f041e880.789e430d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5226],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=n,d=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return a?r.createElement(d,i(i({ref:t},p),{},{components:a})):r.createElement(d,i({ref:t},p))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s<o;s++)i[s]=a[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},3291:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"March 31, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"planning",permalink:"/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/blog/cwtch-nightly-1-11"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f146017a.7693dec7.js b/build-staging/assets/js/f146017a.7693dec7.js new file mode 100644 index 00000000..19472545 --- /dev/null +++ b/build-staging/assets/js/f146017a.7693dec7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6241],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),m=o,h=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(h,i(i({ref:t},u),{},{components:n})):r.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l<a;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},1354:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:6},i="Documentation Style Guide",s={unversionedId:"contribute/documentation",id:"contribute/documentation",title:"Documentation Style Guide",description:"This section documents the expected structure and quality of Cwtch documentation.",source:"@site/docs/contribute/documentation.md",sourceDirName:"contribute",slug:"/contribute/documentation",permalink:"/docs/contribute/documentation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/documentation.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Translating Cwtch",permalink:"/docs/contribute/translate"},next:{title:"Stickers",permalink:"/docs/contribute/stickers"}},c={},l=[{value:"Screenshots and Cast of Characters",id:"screenshots-and-cast-of-characters",level:2},{value:"Dialogue and Content",id:"dialogue-and-content",level:2},{value:"Experiments",id:"experiments",level:2},{value:"Risks",id:"risks",level:2}],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"documentation-style-guide"},"Documentation Style Guide"),(0,o.kt)("p",null,"This section documents the expected structure and quality of Cwtch documentation."),(0,o.kt)("h2",{id:"screenshots-and-cast-of-characters"},"Screenshots and Cast of Characters"),(0,o.kt)("p",null,"Most Cwtch documentation should feature at least one screenshot or animated image. Screenshots of the Cwtch application should be focused on the feature being described by the documentation. "),(0,o.kt)("p",null,"To ensure consistency between screenshots we suggest that the profile involved should serve particular, constant, roles. "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Alice")," - used to represent the primary profile. "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Bob")," - the primary contact, useful when demonstrating peer-to-peer features"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Carol")," - a secondary contact, useful when demonstrating group features"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mallory")," - representing a malicious peer (to be used when demonstrating blocking functionality) ")),(0,o.kt)("h2",{id:"dialogue-and-content"},"Dialogue and Content"),(0,o.kt)("p",null,"Where screenshots and demonstrations show dialogue, conversations, and/or images please keep the conversations short, on a casual topic. Examples include:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Organizing a picnic"),(0,o.kt)("li",{parentName:"ul"},"Sharing photos from a vacation"),(0,o.kt)("li",{parentName:"ul"},"Sending a document for review")),(0,o.kt)("h2",{id:"experiments"},"Experiments"),(0,o.kt)("p",null,"All features that rely on an experiment being enabled should all this out prominently at the top of the page e.g.:"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Example Experiment")," turned on.")),(0,o.kt)("h2",{id:"risks"},"Risks"),(0,o.kt)("p",null,"If a feature might result in destruction of key material or permanent deletion of state, then these should also be called out\nat the top of the documentation e.g.:"),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,o.kt)("strong",{parentName:"p"},"irreversible")," deletion of key material. This ",(0,o.kt)("strong",{parentName:"p"},"cannot be undone"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f47fcb38.8650616e.js b/build-staging/assets/js/f47fcb38.8650616e.js new file mode 100644 index 00000000..4b19d7cc --- /dev/null +++ b/build-staging/assets/js/f47fcb38.8650616e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4325],{1837:o=>{o.exports=JSON.parse('{"title":"Groups","slug":"/category/groups","permalink":"/docs/category/groups","navigation":{"previous":{"title":"Removing a Conversation","permalink":"/docs/chat/delete-contact"},"next":{"title":"An Introduction to Cwtch Groups","permalink":"/docs/groups/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f4bfc819.56ce47de.js b/build-staging/assets/js/f4bfc819.56ce47de.js new file mode 100644 index 00000000..25c599ef --- /dev/null +++ b/build-staging/assets/js/f4bfc819.56ce47de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8430],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=c(r),m=o,f=l["".concat(s,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:o,a[1]=p;for(var c=2;c<i;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},5096:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:4},a="Sending Invites to a Group",p={unversionedId:"groups/send-invite",id:"groups/send-invite",title:"Sending Invites to a Group",description:"This feature requires Experiments Enabled and",source:"@site/docs/groups/send-invite.md",sourceDirName:"groups",slug:"/groups/send-invite",permalink:"/docs/groups/send-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/send-invite.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Creating a New Group",permalink:"/docs/groups/create-group"},next:{title:"Accepting a Group Invite",permalink:"/docs/groups/accept-group-invite"}},s={},c=[],u={toc:c},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"sending-invites-to-a-group"},"Sending Invites to a Group"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and\nthe ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Group Experiment")," turned on.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Go to a chat with a friend"),(0,o.kt)("li",{parentName:"ol"},"Press on the invite icon"),(0,o.kt)("li",{parentName:"ol"},"Select the group you want to invite them to"),(0,o.kt)("li",{parentName:"ol"},"Press Invite"),(0,o.kt)("li",{parentName:"ol"},"You have sent an invite")),(0,o.kt)("div",null,(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Invite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f76a3b8e.18e5a4dd.js b/build-staging/assets/js/f76a3b8e.18e5a4dd.js new file mode 100644 index 00000000..22ab6b9f --- /dev/null +++ b/build-staging/assets/js/f76a3b8e.18e5a4dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2184],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},g="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),g=l(n),m=a,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[g]="string"==typeof e?e:a,o[1]=c;for(var l=2;l<i;l++)o[l]=n[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3103:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"February 17, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"support",permalink:"/blog/tags/support"},{label:"testing",permalink:"/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/blog/cwtch-android-reproducibility"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},g="wrapper";function u(e){let{components:t,...i}=e;return(0,a.kt)(g,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,a.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(6097).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},6097:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f928e8d9.6c170e10.js b/build-staging/assets/js/f928e8d9.6c170e10.js new file mode 100644 index 00000000..2495e5e6 --- /dev/null +++ b/build-staging/assets/js/f928e8d9.6c170e10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8786],{7160:e=>{e.exports=JSON.parse('{"pluginId":"docs-developer","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Introduction to Cwtch Development","href":"/developing/intro","docId":"intro"},{"type":"link","label":"Release and Packaging Process","href":"/developing/release","docId":"release"},{"type":"category","label":"Building a Cwtch App","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/developing/building-a-cwtch-app/intro","docId":"building-a-cwtch-app/intro"},{"type":"link","label":"Core Concepts","href":"/developing/building-a-cwtch-app/core-concepts","docId":"building-a-cwtch-app/core-concepts"},{"type":"link","label":"Building a Cwtch Echobot","href":"/developing/building-a-cwtch-app/building-an-echobot","docId":"building-a-cwtch-app/building-an-echobot"}],"href":"/developing/category/building-a-cwtch-app"}]},"docs":{"building-a-cwtch-app/building-an-echobot":{"id":"building-a-cwtch-app/building-an-echobot","title":"Building a Cwtch Echobot","description":"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/core-concepts":{"id":"building-a-cwtch-app/core-concepts","title":"Core Concepts","description":"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/intro":{"id":"building-a-cwtch-app/intro","title":"Getting Started","description":"Choosing A Cwtch Library","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Introduction to Cwtch Development","description":"- Core Concepts","sidebar":"tutorialSidebar"},"release":{"id":"release","title":"Release and Packaging Process","description":"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f92b996b.b1944282.js b/build-staging/assets/js/f92b996b.b1944282.js new file mode 100644 index 00000000..7f61f553 --- /dev/null +++ b/build-staging/assets/js/f92b996b.b1944282.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4059],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>g});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},s=Object.keys(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,p=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=c(n),m=a,g=u["".concat(p,".").concat(m)]||u[m]||d[m]||s;return n?r.createElement(g,o(o({ref:t},l),{},{components:n})):r.createElement(g,o({ref:t},l))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[u]="string"==typeof e?e:a,o[1]=i;for(var c=2;c<s;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},1763:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const s={sidebar_position:2},o="Message Formats",i={unversionedId:"components/cwtch/message_formats",id:"components/cwtch/message_formats",title:"Message Formats",description:"Peer to Peer Messages",source:"@site/security/components/cwtch/message_formats.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/message_formats",permalink:"/security/components/cwtch/message_formats",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch",permalink:"/security/category/cwtch"},next:{title:"Key Bundles",permalink:"/security/components/cwtch/key_bundles"}},p={},c=[{value:"Peer to Peer Messages",id:"peer-to-peer-messages",level:2},{value:"Context Identifiers",id:"context-identifiers",level:3},{value:"Plaintext / Decrypted Group Messages",id:"plaintext--decrypted-group-messages",level:2},{value:"Encrypted Group Messages",id:"encrypted-group-messages",level:2}],l={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"message-formats"},"Message Formats"),(0,a.kt)("h2",{id:"peer-to-peer-messages"},"Peer to Peer Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"PeerMessage {\n ID string // A unique Message ID (primarily used for acknowledgments)\n Context string // A unique context identifier i.e. im.cwtch.chat\n Data []byte // The context-dependent serialized data packet.\n}\n")),(0,a.kt)("h3",{id:"context-identifiers"},"Context Identifiers"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.raw")," - Data contains a plain text chat message (see: ",(0,a.kt)("a",{parentName:"p",href:"/security/components/ui/overlays"},"overlays")," for more information)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.acknowledgement")," - Data is empty and ID references a previously sent message")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.getVal")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.retVal")," - Used for requesting / returning specific information about a peer. Data\ncontains a serialized ",(0,a.kt)("inlineCode",{parentName:"p"},"peerGetVal")," structure and ",(0,a.kt)("inlineCode",{parentName:"p"},"peerRetVal")," respectively."),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre"}," peerGetVal struct {\n Scope string\n Path string\n }\n\n type peerRetVal struct {\n Val string // Serialized path-dependent value\n Exists bool\n }\n")))),(0,a.kt)("h2",{id:"plaintext--decrypted-group-messages"},"Plaintext / Decrypted Group Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'type DecryptedGroupMessage struct {\n Text string // plaintext of the message\n Onion string // The Cwtch address of the sender\n Timestamp uint64 // A user specified timestamp\n // NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages\n // We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.\n // respect particular group constitutions) can be built on top of group messages, but the underlying groups are\n // now agnostic to those models.\n SignedGroupID []byte \n PreviousMessageSig []byte // A reference to a previous message\n Padding []byte // random bytes of length = 1800 - len(Text)\n}\n')),(0,a.kt)("p",null,"DecryptedGroupMessage contains random padding to a fixed size that is equal to the length of all fixed length fields + 1800.\nThis ensures that all encrypted group messages are equal length."),(0,a.kt)("h2",{id:"encrypted-group-messages"},"Encrypted Group Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server\ntype EncryptedGroupMessage struct {\n Ciphertext []byte\n Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key\n}\n")),(0,a.kt)("p",null,"Calculating the signature requires knowing the groupID of the message, the server the group is associated with\nand the decrypted group message (and thus, the Group Key). It is (ed25519) signed by the sender of the message, and can be\nverified using their public Cwtch address key."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/f96ae61b.6149bc06.js b/build-staging/assets/js/f96ae61b.6149bc06.js new file mode 100644 index 00000000..b82e9eba --- /dev/null +++ b/build-staging/assets/js/f96ae61b.6149bc06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2700],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>y});var o=t(7294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function l(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){n(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function a(e,r){if(null==e)return{};var t,o,n=function(e,r){if(null==e)return{};var t,o,n={},i=Object.keys(e);for(o=0;o<i.length;o++)t=i[o],r.indexOf(t)>=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)t=i[o],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var c=o.createContext({}),p=function(e){var r=o.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):l(l({},r),e)),t},s=function(e){var r=p(e.components);return o.createElement(c.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},d=o.forwardRef((function(e,r){var t=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,s=a(e,["components","mdxType","originalType","parentName"]),u=p(t),d=n,y=u["".concat(c,".").concat(d)]||u[d]||f[d]||i;return t?o.createElement(y,l(l({ref:r},s),{},{components:t})):o.createElement(y,l({ref:r},s))}));function y(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var i=t.length,l=new Array(i);l[0]=d;var a={};for(var c in r)hasOwnProperty.call(r,c)&&(a[c]=r[c]);a.originalType=e,a[u]="string"==typeof e?e:n,l[1]=a;for(var p=2;p<i;p++)l[p]=t[p];return o.createElement.apply(null,l)}return o.createElement.apply(null,t)}d.displayName="MDXCreateElement"},4802:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>l,default:()=>f,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var o=t(7462),n=(t(7294),t(3905));const i={sidebar_position:5},l="Unlocking Encrypted Profiles",a={unversionedId:"profiles/unlock-profile",id:"profiles/unlock-profile",title:"Unlocking Encrypted Profiles",description:"When you restart Cwtch, if you used a password to protect your profile, it will not be loaded by default, and you will need to unlock it.",source:"@site/docs/profiles/unlock-profile.md",sourceDirName:"profiles",slug:"/profiles/unlock-profile",permalink:"/docs/profiles/unlock-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/unlock-profile.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Changing Your Profile Image",permalink:"/docs/profiles/change-profile-image"},next:{title:"Deleting a Profile",permalink:"/docs/profiles/delete-profile"}},c={},p=[],s={toc:p},u="wrapper";function f(e){let{components:r,...t}=e;return(0,n.kt)(u,(0,o.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"unlocking-encrypted-profiles"},"Unlocking Encrypted Profiles"),(0,n.kt)("p",null,"When you restart Cwtch, if you used a ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/change-password/"},"password")," to protect your profile, it will not be loaded by default, and you will need to unlock it."),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Press the pink unlock icon ",(0,n.kt)("img",{src:"/img/lock_open-24px.webp",className:"ui-button",alt:"unlock icon"})),(0,n.kt)("li",{parentName:"ol"},"Input your password"),(0,n.kt)("li",{parentName:"ol"},"Click \u201cunlock your profile\u201d")),(0,n.kt)("p",null,"See also: ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Cwtch Security Handbook: Profile Encryption & Storage")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/fb3c1916.6ddb0beb.js b/build-staging/assets/js/fb3c1916.6ddb0beb.js new file mode 100644 index 00000000..a1a99200 --- /dev/null +++ b/build-staging/assets/js/fb3c1916.6ddb0beb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[276],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),s=p(r),f=o,b=s["".concat(l,".").concat(f)]||s[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},8886:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},a="Introduction to Cwtch Development",c={unversionedId:"intro",id:"intro",title:"Introduction to Cwtch Development",description:"- Core Concepts",source:"@site/developing/intro.md",sourceDirName:".",slug:"/intro",permalink:"/developing/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Release and Packaging Process",permalink:"/developing/release"}},l={},p=[{value:"Contributing to Cwtch Core",id:"contributing-to-cwtch-core",level:2},{value:"Building Cwtch Bots",id:"building-cwtch-bots",level:2}],u={toc:p},s="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introduction-to-cwtch-development"},"Introduction to Cwtch Development"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/core-concepts"},"Core Concepts")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/intro"},"Security Handbook"))),(0,o.kt)("h2",{id:"contributing-to-cwtch-core"},"Contributing to Cwtch Core"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/release"},"Release and Packaging Process"))),(0,o.kt)("h2",{id:"building-cwtch-bots"},"Building Cwtch Bots"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"Choosing a Library")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/building-an-echobot"},"Echobot Tutorial"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/fc0ce2b3.be0538c9.js b/build-staging/assets/js/fc0ce2b3.be0538c9.js new file mode 100644 index 00000000..0a250cc9 --- /dev/null +++ b/build-staging/assets/js/fc0ce2b3.be0538c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6363],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),m=i,h=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(h,o(o({ref:t},u),{},{components:n})):r.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:i,o[1]=s;for(var l=2;l<a;l++)o[l]=n[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},7266:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:1},o="Testing Cwtch",s={unversionedId:"contribute/testing",id:"contribute/testing",title:"Testing Cwtch",description:"This section documents some ways to get started with Cwtch Testing.",source:"@site/docs/contribute/testing.md",sourceDirName:"contribute",slug:"/contribute/testing",permalink:"/docs/contribute/testing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/testing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Developing Cwtch",permalink:"/docs/contribute/developing"},next:{title:"Translating Cwtch",permalink:"/docs/contribute/translate"}},c={},l=[{value:"Running Fuzzbot",id:"running-fuzzbot",level:3},{value:"Join the Cwtch Release Candidate Testers Group",id:"join-the-cwtch-release-candidate-testers-group",level:3},{value:"Cwtch Nightlies",id:"cwtch-nightlies",level:3},{value:"Submitting Feedback",id:"submitting-feedback",level:3}],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"testing-cwtch"},"Testing Cwtch"),(0,i.kt)("p",null,"This section documents some ways to get started with Cwtch Testing."),(0,i.kt)("h3",{id:"running-fuzzbot"},"Running Fuzzbot"),(0,i.kt)("p",null,"FuzzBot is our development testing bot. You can add FuzzBot as a contact: ",(0,i.kt)("inlineCode",{parentName:"p"},"cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad"),"."),(0,i.kt)("admonition",{title:"FuzzBot Help",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Sending FuzzBot a ",(0,i.kt)("inlineCode",{parentName:"p"},"help")," message will trigger it to send a reply with all the currently available testing commands. ")),(0,i.kt)("p",null,"For more information on FuzzBot see our ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Discreet Log development blog"),"."),(0,i.kt)("h3",{id:"join-the-cwtch-release-candidate-testers-group"},"Join the Cwtch Release Candidate Testers Group"),(0,i.kt)("p",null,"Sending Fuzzbot the command ",(0,i.kt)("inlineCode",{parentName:"p"},"testgroup-invite")," will cause FuzzBot to invite you to the ",(0,i.kt)("strong",{parentName:"p"},"Cwtch Testers Group"),"! There\nyou can ask questions, post bug reports and offer feedback."),(0,i.kt)("h3",{id:"cwtch-nightlies"},"Cwtch Nightlies"),(0,i.kt)("p",null,"Cwtch Nightly builds are development builds that contain new features that are ready for testing."),(0,i.kt)("p",null,"The most recent few development versions of Cwtch are available from our ",(0,i.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"build server"),"."),(0,i.kt)("p",null,"We ",(0,i.kt)("strong",{parentName:"p"},"do not")," recommend that testers always upgrade to the latest nightly, Instead, we will post a message to the Cwtch Release Candidate Testers group\nwhen a significant nightly becomes available. A nightly is considered significant if it contains a new feature or a major bug fix."),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"All contributions are ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))),(0,i.kt)("h3",{id:"submitting-feedback"},"Submitting Feedback"),(0,i.kt)("p",null,"There are three main ways of submitting testing feedback to the team:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Via Cwtch: Either via the Release Candidate Testers Group or directly to a Cwtch team member."),(0,i.kt)("li",{parentName:"ul"},"Via Gitea: Please open an issue in ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues")," - please do not worry about duplicate issues, we will de-duplicate as part of our triage process."),(0,i.kt)("li",{parentName:"ul"},"Via Email: Email ",(0,i.kt)("inlineCode",{parentName:"li"},"team@cwtch.im")," with the bug report and one of our team will look into it.")),(0,i.kt)("admonition",{type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/fd27e325.8533fcdc.js b/build-staging/assets/js/fd27e325.8533fcdc.js new file mode 100644 index 00000000..e4590af9 --- /dev/null +++ b/build-staging/assets/js/fd27e325.8533fcdc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1199],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=r,d=u["".concat(s,".").concat(m)]||u[m]||h[m]||i;return n?o.createElement(d,c(c({ref:t},p),{},{components:n})):o.createElement(d,c({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,c=new Array(i);c[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:r,c[1]=a;for(var l=2;l<i;l++)c[l]=n[l];return o.createElement.apply(null,c)}return o.createElement.apply(null,n)}m.displayName="MDXCreateElement"},9327:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:3},c="Building a Cwtch Echobot",a={unversionedId:"building-a-cwtch-app/building-an-echobot",id:"building-a-cwtch-app/building-an-echobot",title:"Building a Cwtch Echobot",description:"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.",source:"@site/developing/building-a-cwtch-app/building-an-echobot.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/building-an-echobot",permalink:"/developing/building-a-cwtch-app/building-an-echobot",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Core Concepts",permalink:"/developing/building-a-cwtch-app/core-concepts"}},s={},l=[{value:"Using CwtchBot (Go)",id:"using-cwtchbot-go",level:2},{value:"Using Imp (Rust)",id:"using-imp-rust",level:2}],p={toc:l},u="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"building-a-cwtch-echobot"},"Building a Cwtch Echobot"),(0,r.kt)("p",null,"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent."),(0,r.kt)("p",null,"For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or\nframework."),(0,r.kt)("h2",{id:"using-cwtchbot-go"},"Using CwtchBot (Go)"),(0,r.kt)("admonition",{title:"CwtchBot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the CwtchBot framework.")),(0,r.kt)("p",null,"Start by creating a new Go project, and a file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.go"),". In the ",(0,r.kt)("inlineCode",{parentName:"p"},"main")," function:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "cwtch.im/cwtch/event"\n "cwtch.im/cwtch/model"\n "cwtch.im/cwtch/model/attr"\n "cwtch.im/cwtch/model/constants"\n "fmt"\n "git.openprivacy.ca/sarah/cwtchbot"\n _ "github.com/mutecomm/go-sqlcipher/v4"\n "os/user"\n "path"\n)\n\nfunc main() {\n user, _ := user.Current()\n cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")\n cwtchbot.Launch()\n\n // Set Some Profile Information\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")\n\n fmt.Printf("echobot address: %v\\n", cwtchbot.Peer.GetOnion())\n\n for {\n message := cwtchbot.Queue.Next()\n cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])\n switch message.EventType {\n case event.NewMessageFromPeer:\n msg := cwtchbot.UnpackMessage(message.Data[event.Data])\n fmt.Printf("Message: %v\\n", msg)\n reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n case event.ContactCreated:\n fmt.Printf("Auto approving stranger %v %v\\n", cid, message.Data[event.RemotePeer])\n // accept the stranger as a new contact\n cwtchbot.Peer.AcceptConversation(cid.ID)\n // Send Hello...\n reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n }\n }\n}\n')),(0,r.kt)("h2",{id:"using-imp-rust"},"Using Imp (Rust)"),(0,r.kt)("admonition",{title:"Imp (Rust) Bot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'use std::borrow::BorrowMut;\nuse std::thread;\nuse chrono::{DateTime, FixedOffset};\nuse libcwtch;\nuse libcwtch::CwtchLib;\nuse libcwtch::structs::*;\nuse libcwtch::event::*;\nuse cwtch_imp::imp;\nuse cwtch_imp::behaviour::*;\nuse cwtch_imp::imp::Imp;\n\nconst BOT_HOME: &str = "~/.cwtch/bots/echobot";\nconst BOT_NAME: &str = "echobot";\n\nstruct Echobot {}\n\nfn main() {\n let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();\n let event_loop_handle = thread::spawn(move || {\n let mut echobot = Echobot {};\n let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());\n bot.event_loop::<Echobot>(echobot.borrow_mut());\n });\n event_loop_handle.join().expect("Error running event loop");\n}\n\nimpl imp::EventHandler for Echobot {\n fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {\n let response = Message {\n o: MessageType::TextMessage,\n d: message.d,\n };\n cwtch.send_message(&profile.profile_id, conversation_id, &response);\n }\n\n fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {\n match event {\n Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {\n println!(\n "\\n***** {} at {} *****\\n",\n name, profile_id.as_str()\n );\n }\n _ => (),\n };\n }\n}\n')))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/assets/js/fe1dd7ae.81e23f94.js b/build-staging/assets/js/fe1dd7ae.81e23f94.js new file mode 100644 index 00000000..5aa5d4cb --- /dev/null +++ b/build-staging/assets/js/fe1dd7ae.81e23f94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1979],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>u});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,a,n=function(e,t){if(null==e)return{};var r,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(r),m=n,u=h["".concat(l,".").concat(m)]||h[m]||g[m]||o;return r?a.createElement(u,i(i({ref:t},s),{},{components:r})):a.createElement(u,i({ref:t},s))}));function u(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=r[p];return a.createElement.apply(null,i)}return a.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1501:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"June 7, 2023",tags:[{label:"cwtch",permalink:"/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/blog/cwtch-developer-documentation"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function g(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(9964).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},9964:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"}}]); \ No newline at end of file diff --git a/build-staging/assets/js/main.d97936a9.js b/build-staging/assets/js/main.d97936a9.js new file mode 100644 index 00000000..5378aade --- /dev/null +++ b/build-staging/assets/js/main.d97936a9.js @@ -0,0 +1,2 @@ +/*! For license information please see main.d97936a9.js.LICENSE.txt */ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),l=n(6887);const s={"003ad223":[()=>n.e(8073).then(n.t.bind(n,6533,19)),"~docs/default/category-docs-tutorialsidebar-category-appearance-f0b.json",6533],"017f0ba6":[()=>n.e(9398).then(n.bind(n,9707)),"@site/security/components/ui/image_previews.md",9707],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"06a743f0":[()=>n.e(3080).then(n.t.bind(n,6502,19)),"~blog/default/blog-tags-bindings-021.json",6502],"081d7fe1":[()=>n.e(5696).then(n.bind(n,3518)),"@site/docs/groups/introduction.md",3518],"09058439":[()=>n.e(4186).then(n.bind(n,3818)),"@site/security/components/ui/overlays.md",3818],"0a9e402c":[()=>n.e(6562).then(n.bind(n,2617)),"@site/docs/chat/share-file.md",2617],"0be9de06":[()=>n.e(7222).then(n.t.bind(n,390,19)),"~blog/default/blog-tags-api-ce2-list.json",390],"0d64c1d9":[()=>n.e(8710).then(n.bind(n,9133)),"@site/blog/2023-01-20-reproducible-builds-bindings.md",9133],"0e384e19":[()=>n.e(9671).then(n.bind(n,9881)),"@site/docs/intro.md",9881],"0e3e2a9e":[()=>n.e(9038).then(n.bind(n,4247)),"@site/docs/chat/delete-contact.md",4247],"1075f7cd":[()=>n.e(9899).then(n.bind(n,5478)),"@site/security/components/tapir/authentication_protocol.md",5478],"1252ef76":[()=>n.e(815).then(n.t.bind(n,5566,19)),"~blog/default/blog-tags-developer-documentation-72f.json",5566],"13bbad87":[()=>n.e(7531).then(n.bind(n,1075)),"@site/security/components/cwtch/key_bundles.md",1075],"141cdfa9":[()=>n.e(7293).then(n.bind(n,677)),"@site/blog/2023-04-06-availability-and-profile-attributes.md?truncated=true",677],"142f86d0":[()=>n.e(7538).then(n.t.bind(n,959,19)),"~blog/default/blog-tags-autobindings-56d.json",959],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],"15b89b76":[()=>n.e(8392).then(n.t.bind(n,9610,19)),"~blog/default/blog-tags-testing-92e.json",9610],"15d993af":[()=>n.e(1174).then(n.t.bind(n,3170,19)),"~blog/default/blog-tags-cwtch-30e-list.json",3170],"16838ca5":[()=>n.e(4704).then(n.t.bind(n,4674,19)),"~blog/default/blog-tags-cwtch-30e.json",4674],17896441:[()=>Promise.all([n.e(532),n.e(9785),n.e(7918)]).then(n.bind(n,5154)),"@theme/DocItem",5154],"1944a0c9":[()=>n.e(9140).then(n.t.bind(n,2796,19)),"~blog/default/blog-tags-security-handbook-f46.json",2796],"1a25c548":[()=>n.e(5732).then(n.bind(n,1202)),"@site/blog/2023-01-06-path-to-cwtch-stable.md?truncated=true",1202],"1af46bd3":[()=>n.e(962).then(n.bind(n,374)),"@site/docs/settings/appearance/ui-columns.md",374],"1b4ba274":[()=>n.e(4052).then(n.bind(n,4061)),"@site/docs/settings/behaviour/notification-policy.md",4061],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1ebd8798":[()=>n.e(4788).then(n.bind(n,5558)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md?truncated=true",5558],"22069e6c":[()=>n.e(2852).then(n.bind(n,6951)),"@site/docs/servers/unlock-server.md",6951],"238b6b00":[()=>n.e(129).then(n.bind(n,3874)),"@site/docs/settings/experiments/clickable-links.md",3874],"2853a99a":[()=>n.e(6297).then(n.bind(n,8915)),"@site/docs/groups/leave-group.md",8915],"2c8522e6":[()=>n.e(7499).then(n.t.bind(n,712,19)),"~docs/default/category-docs-tutorialsidebar-category-experiments-7d0.json",712],"2ffd7dc7":[()=>n.e(2073).then(n.bind(n,5360)),"@site/docs/settings/behaviour/notification-content.md",5360],"3152febb":[()=>n.e(225).then(n.t.bind(n,3492,19)),"~docs/default/category-docs-tutorialsidebar-category-getting-started-3f9.json",3492],"34cd4dc6":[()=>n.e(3429).then(n.bind(n,1172)),"@site/docs/chat/save-conversation-history.md",1172],"38f00f86":[()=>n.e(9667).then(n.t.bind(n,2686,19)),"~blog/default/blog-tags-documentation-944.json",2686],"39c54b43":[()=>n.e(8793).then(n.t.bind(n,4990,19)),"~blog/default/blog-tags-cwtch-page-2-dca-list.json",4990],"3a109bd3":[()=>n.e(7782).then(n.bind(n,877)),"@site/blog/2023-03-10-cwtch-documentation.md?truncated=true",877],"3b599162":[()=>n.e(7294).then(n.t.bind(n,2159,19)),"~blog/default/blog-tags-libcwtch-b3a-list.json",2159],"3ce57273":[()=>n.e(6972).then(n.bind(n,7548)),"@site/docs/settings/experiments/file-sharing.md",7548],"3db42865":[()=>n.e(7139).then(n.t.bind(n,3769,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"3e7ae638":[()=>n.e(9595).then(n.bind(n,8255)),"@site/security/components/tapir/packet_format.md",8255],"414c86b4":[()=>n.e(730).then(n.bind(n,3798)),"@site/docs/groups/accept-group-invite.md",3798],"41c638ee":[()=>n.e(8266).then(n.t.bind(n,8129,19)),"~blog/default/blog-tags-nightly-7a1-list.json",8129],43521719:[()=>n.e(9376).then(n.bind(n,4134)),"@site/docs/chat/message-formatting.md",4134],"437de1b1":[()=>n.e(2562).then(n.t.bind(n,4785,19)),"~docs/docs-security/category-security-tutorialsidebar-category-cwtch-aa0.json",4785],"43b107c1":[()=>n.e(9200).then(n.bind(n,1168)),"@site/blog/2023-02-03-cwtch-testing-i.md",1168],"442b4cb8":[()=>n.e(6971).then(n.t.bind(n,3157,19)),"~blog/default/blog-tags-bindings-021-list.json",3157],"44fbbcc6":[()=>n.e(1088).then(n.bind(n,7079)),"@site/docs/profiles/exporting-profile.md",7079],"48119dbc":[()=>n.e(4998).then(n.bind(n,5847)),"@site/docs/servers/create-server.md",5847],"4912a2e0":[()=>n.e(1598).then(n.t.bind(n,5814,19)),"~blog/default/blog-tags-cwtch-stable-07c.json",5814],"49ced744":[()=>n.e(5006).then(n.t.bind(n,592,19)),"~docs/docs-security/category-security-tutorialsidebar-category-cwtch-components-abf.json",592],"4aa555c3":[()=>n.e(7797).then(n.bind(n,3449)),"@site/blog/2023-06-16-cwtch-1.12.md?truncated=true",3449],"4bb443f0":[()=>n.e(4078).then(n.t.bind(n,9731,19)),"~blog/default/blog-tags-testing-92e-list.json",9731],"4d27f429":[()=>n.e(788).then(n.bind(n,7362)),"@site/blog/2023-01-20-reproducible-builds-bindings.md?truncated=true",7362],"4e8da046":[()=>n.e(6368).then(n.bind(n,9497)),"@site/docs/profiles/introduction.md",9497],"4e96e24f":[()=>n.e(9726).then(n.bind(n,8732)),"@site/docs/chat/block-contact.md",8732],"4f68bcc6":[()=>n.e(3516).then(n.t.bind(n,4289,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-security/plugin-route-context-module-100.json",4289],"53cc4802":[()=>n.e(7594).then(n.bind(n,3109)),"@site/blog/2023-02-03-cwtch-testing-i.md?truncated=true",3109],"5420a7ba":[()=>n.e(6515).then(n.bind(n,3962)),"@site/docs/settings/experiments/message-formatting.md",3962],"553b7761":[()=>n.e(732).then(n.bind(n,4465)),"@site/docs/getting-started/supported_platforms.md",4465],"55d4c988":[()=>n.e(6946).then(n.t.bind(n,9048,19)),"~blog/default/blog-tags-cwtch-page-2-dca.json",9048],"5a3f34f2":[()=>n.e(7143).then(n.bind(n,1739)),"@site/docs/settings/behaviour/block-unknown-connections.md",1739],"5a5e3510":[()=>n.e(1315).then(n.bind(n,6185)),"@site/docs/profiles/change-password.md",6185],"5b041459":[()=>n.e(7710).then(n.bind(n,2650)),"@site/security/risk.md",2650],"5b4e4bee":[()=>n.e(3171).then(n.t.bind(n,8340,19)),"~docs/docs-security/category-security-tutorialsidebar-category-connectivity-tor-2eb.json",8340],"5beee875":[()=>n.e(9444).then(n.bind(n,2724)),"@site/blog/2023-06-07-new-nightly.md",2724],"5cb298ca":[()=>n.e(2909).then(n.bind(n,4673)),"@site/blog/2023-04-28-developer-docs.md?truncated=true",4673],"5dc151e9":[()=>n.e(923).then(n.bind(n,2320)),"@site/developing/release.md",2320],"5e5faacc":[()=>n.e(8192).then(n.bind(n,9655)),"@site/blog/2023-01-27-platform-support.md",9655],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"5f6192c8":[()=>n.e(7479).then(n.t.bind(n,8271,19)),"~docs/docs-security/category-security-tutorialsidebar-category-tapir-5d2.json",8271],"6015355d":[()=>n.e(198).then(n.t.bind(n,4978,19)),"~blog/default/blog-tags-cwtch-stable-page-2-9bf-list.json",4978],61794344:[()=>n.e(6232).then(n.bind(n,4669)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",4669],"6275ceb4":[()=>n.e(6555).then(n.bind(n,248)),"@site/blog/2023-03-10-cwtch-documentation.md",248],"628b3074":[()=>n.e(3478).then(n.t.bind(n,827,19)),"~docs/default/category-docs-tutorialsidebar-category-contribute-357.json",827],"6575cef9":[()=>n.e(8588).then(n.bind(n,2723)),"@site/docs/contribute/stickers.md",2723],"663d5f0b":[()=>n.e(7992).then(n.bind(n,3361)),"@site/docs/groups/manage-known-servers.md",3361],"67152af3":[()=>n.e(2322).then(n.bind(n,1887)),"@site/docs/groups/edit-group-name.md",1887],"6875c492":[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"693f9c9e":[()=>n.e(6927).then(n.t.bind(n,7822,19)),"~docs/default/category-docs-tutorialsidebar-category-servers-afb.json",7822],"697a71fd":[()=>n.e(712).then(n.bind(n,432)),"@site/docs/profiles/change-profile-image.md",432],"6a78f460":[()=>n.e(439).then(n.bind(n,2982)),"@site/blog/2023-04-06-availability-and-profile-attributes.md",2982],"6b72ab5e":[()=>n.e(8017).then(n.t.bind(n,2306,19)),"~blog/default/blog-tags-reproducible-builds-973-list.json",2306],"6d453d64":[()=>n.e(9287).then(n.t.bind(n,794,19)),"~blog/default/blog-tags-api-ce2.json",794],"709d36d8":[()=>n.e(176).then(n.bind(n,5722)),"@site/security/components/ui/android.md",5722],"7285d864":[()=>n.e(3965).then(n.bind(n,3166)),"@site/docs/chat/add-contact.md",3166],"76493ef6":[()=>n.e(6033).then(n.t.bind(n,4438,19)),"~docs/default/category-docs-tutorialsidebar-category-platforms-081.json",4438],"7650afbf":[()=>n.e(1586).then(n.bind(n,3233)),"@site/docs/chat/share-address-with-friends.md",3233],"76913e45":[()=>n.e(9072).then(n.t.bind(n,6271,19)),"~blog/default/blog-tags-repliqate-4c9-list.json",6271],"7daa3c80":[()=>n.e(1970).then(n.bind(n,4229)),"@site/docs/servers/edit-server.md",4229],"7df3f7bb":[()=>n.e(5586).then(n.bind(n,7092)),"@site/docs/contribute/developing.md",7092],"7dfbf03e":[()=>n.e(1234).then(n.t.bind(n,6784,19)),"~docs/docs-developer/category-developing-tutorialsidebar-category-building-a-cwtch-app-355.json",6784],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],"824a28c6":[()=>n.e(5905).then(n.bind(n,9347)),"@site/developing/building-a-cwtch-app/intro.md",9347],"83d480e9":[()=>n.e(205).then(n.t.bind(n,3672,19)),"~blog/default/blog-tags-release-b5c.json",3672],"840bb092":[()=>n.e(8351).then(n.bind(n,576)),"@site/docs/profiles/change-name.md",576],"89c52e74":[()=>n.e(8655).then(n.bind(n,8052)),"@site/docs/profiles/availability-status.md",8052],"89f86a37":[()=>n.e(9759).then(n.bind(n,9366)),"@site/blog/2023-03-29-cwtch-1.11.md?truncated=true",9366],"8eb4e46b":[()=>n.e(1).then(n.t.bind(n,2638,19)),"~blog/default/blog-page-2-677.json",2638],"8ec965fd":[()=>n.e(6471).then(n.bind(n,4645)),"@site/docs/tor.md",4645],"8fe7a387":[()=>n.e(5233).then(n.bind(n,9667)),"@site/blog/2023-03-03-autobindings-optional-experiments.md",9667],"917e8196":[()=>n.e(5497).then(n.bind(n,6933)),"@site/docs/settings/experiments/qrcodes.md",6933],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"947e3a34":[()=>n.e(7875).then(n.bind(n,1823)),"@site/security/components/connectivity/intro.md",1823],"975564ee":[()=>n.e(8389).then(n.bind(n,4777)),"@site/docs/chat/introduction.md",4777],"97a045eb":[()=>n.e(3838).then(n.t.bind(n,4869,19)),"~blog/default/blog-tags-nightly-7a1.json",4869],"986bf1b5":[()=>n.e(3625).then(n.t.bind(n,8327,19)),"~docs/default/category-docs-tutorialsidebar-category-profiles-9d3.json",8327],"98da7451":[()=>n.e(8141).then(n.t.bind(n,8777,19)),"~docs/default/category-docs-tutorialsidebar-category-settings-aa6.json",8777],"992a3bb7":[()=>n.e(1415).then(n.t.bind(n,8229,19)),"~blog/default/blog-tags-documentation-944-list.json",8229],"9b12a270":[()=>n.e(9249).then(n.bind(n,9816)),"@site/blog/2023-02-10-android-reproducibility.md",9816],"9bb37799":[()=>n.e(9767).then(n.bind(n,2957)),"@site/security/components/intro.md",2957],"9c021584":[()=>n.e(7438).then(n.t.bind(n,8055,19)),"~blog/default/blog-tags-release-b5c-list.json",8055],"9d21518d":[()=>n.e(3628).then(n.bind(n,1335)),"@site/docs/settings/experiments/image-previews-and-profile-pictures.md",1335],"9dd8190d":[()=>n.e(2688).then(n.bind(n,7561)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",7561],"9e2a7473":[()=>n.e(1258).then(n.bind(n,8725)),"@site/blog/2023-01-13-cwtch-stable-api-design.md",8725],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],"9f1c7621":[()=>n.e(1312).then(n.bind(n,4387)),"@site/blog/2023-02-17-cwtch-testing-ii.md",4387],a02b4022:[()=>n.e(3492).then(n.bind(n,4889)),"@site/blog/2023-06-16-cwtch-1.12.md",4889],a08943ae:[()=>n.e(1800).then(n.bind(n,2661)),"@site/docs/settings/appearance/change-language.md",2661],a19b8c23:[()=>n.e(6435).then(n.bind(n,5487)),"@site/docs/servers/introduction.md",5487],a34f2ac7:[()=>n.e(6291).then(n.t.bind(n,1683,19)),"~blog/default/blog-tags-support-474-list.json",1683],a430b379:[()=>n.e(1367).then(n.t.bind(n,8595,19)),"~blog/default/blog-tags-repliqate-4c9.json",8595],a65a3c47:[()=>n.e(7591).then(n.bind(n,5432)),"@site/blog/2023-04-28-developer-docs.md",5432],a6882456:[()=>n.e(4415).then(n.bind(n,5937)),"@site/docs/chat/unblock-contact.md",5937],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(3089)]).then(n.bind(n,46)),"@theme/BlogListPage",46],a6fe627e:[()=>n.e(9239).then(n.bind(n,2577)),"@site/docs/settings/experiments/group-experiment.md",2577],a7023ddc:[()=>n.e(1713).then(n.t.bind(n,3457,19)),"~blog/default/blog-tags-tags-4c2.json",3457],a79c88c2:[()=>n.e(9976).then(n.bind(n,8553)),"@site/blog/2023-01-13-cwtch-stable-api-design.md?truncated=true",8553],a8c7fdc6:[()=>n.e(1602).then(n.t.bind(n,6454,19)),"~docs/docs-security/version-current-metadata-prop-751.json",6454],a9159543:[()=>n.e(5941).then(n.bind(n,8986)),"@site/docs/settings/experiments/server-hosting.md",8986],a9d2d00e:[()=>n.e(6126).then(n.bind(n,1528)),"@site/security/components/cwtch/groups.md",1528],ac6c2a1e:[()=>n.e(8639).then(n.t.bind(n,6086,19)),"~blog/default/blog-tags-support-474.json",6086],acb99df2:[()=>n.e(10).then(n.t.bind(n,1892,19)),"~blog/default/blog-tags-cwtch-stable-07c-list.json",1892],af23c5f9:[()=>n.e(3218).then(n.bind(n,4958)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",4958],b0404c31:[()=>n.e(7860).then(n.bind(n,3478)),"@site/blog/2023-01-06-path-to-cwtch-stable.md",3478],b125d866:[()=>n.e(8799).then(n.bind(n,1595)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md?truncated=true",1595],b1e57def:[()=>n.e(266).then(n.bind(n,8142)),"@site/security/references.md",8142],b273a073:[()=>n.e(5940).then(n.bind(n,4069)),"@site/docs/servers/delete-server.md",4069],b2b675dd:[()=>n.e(533).then(n.t.bind(n,8017,19)),"~blog/default/blog-c06.json",8017],b2f554cd:[()=>n.e(1477).then(n.t.bind(n,10,19)),"~blog/default/blog-archive-80c.json",10],b59bb8da:[()=>n.e(4729).then(n.t.bind(n,6693,19)),"~docs/default/category-docs-tutorialsidebar-category-conversations-a1f.json",6693],b5c61d38:[()=>n.e(8849).then(n.bind(n,3159)),"@site/security/components/cwtch/server.md",3159],bb772baa:[()=>n.e(6341).then(n.bind(n,1020)),"@site/docs/profiles/delete-profile.md",1020],bf059cf9:[()=>n.e(5273).then(n.bind(n,2626)),"@site/blog/2023-02-10-android-reproducibility.md?truncated=true",2626],bfc2e843:[()=>n.e(610).then(n.bind(n,296)),"@site/docs/settings/appearance/streamer-mode.md",296],c063e42f:[()=>n.e(8589).then(n.bind(n,4463)),"@site/security/components/ui/input.md",4463],c11bf3c5:[()=>n.e(7322).then(n.bind(n,8085)),"@site/docs/settings/introduction.md",8085],c14f15fd:[()=>n.e(7649).then(n.bind(n,3071)),"@site/developing/building-a-cwtch-app/core-concepts.md",3071],c2081115:[()=>n.e(8194).then(n.bind(n,7047)),"@site/security/components/ecosystem-overview.md",7047],c33e2c0d:[()=>n.e(9936).then(n.t.bind(n,6629,19)),"~docs/docs-security/category-security-tutorialsidebar-category-cwtch-ui-ecd.json",6629],c42e2be1:[()=>n.e(4842).then(n.bind(n,7771)),"@site/docs/profiles/create-a-profile.md",7771],c4773fe1:[()=>n.e(2612).then(n.bind(n,4457)),"@site/docs/contribute/translate.md",4457],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,3261)),"@site/src/pages/index.js",3261],c747432f:[()=>n.e(8835).then(n.bind(n,2090)),"@site/blog/2023-03-03-autobindings-optional-experiments.md?truncated=true",2090],c94c4dfb:[()=>n.e(9146).then(n.t.bind(n,4469,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],c96c5262:[()=>n.e(3761).then(n.bind(n,5426)),"@site/blog/2023-03-29-cwtch-1.11.md",5426],c9a691cf:[()=>n.e(2221).then(n.t.bind(n,2426,19)),"~docs/default/category-docs-tutorialsidebar-category-behaviour-e0d.json",2426],cc8d20ec:[()=>n.e(5035).then(n.bind(n,7672)),"@site/docs/profiles/profile-info.md",7672],ccc49370:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],cda43b61:[()=>n.e(6539).then(n.bind(n,7206)),"@site/docs/chat/accept-deny-new-conversation.md",7206],ce314f92:[()=>n.e(6965).then(n.bind(n,6672)),"@site/docs/platforms/tails.md",6672],ce4b3243:[()=>n.e(1179).then(n.t.bind(n,1250,19)),"~blog/default/blog-tags-autobindings-56d-list.json",1250],d39fd6c2:[()=>n.e(5230).then(n.bind(n,1007)),"@site/security/intro.md",1007],d5f314f9:[()=>n.e(5869).then(n.t.bind(n,9317,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-developer/plugin-route-context-module-100.json",9317],d66d73fd:[()=>n.e(8858).then(n.bind(n,6089)),"@site/security/development.md",6089],d6a44406:[()=>n.e(3213).then(n.t.bind(n,3260,19)),"~blog/default/blog-tags-cwtch-stable-page-2-9bf.json",3260],dc098020:[()=>n.e(6682).then(n.bind(n,258)),"@site/security/deployment.md",258],dc3c323e:[()=>n.e(564).then(n.bind(n,2909)),"@site/docs/groups/create-group.md",2909],df814c0d:[()=>n.e(6494).then(n.t.bind(n,2637,19)),"~blog/default/blog-tags-developer-documentation-72f-list.json",2637],e4fed92d:[()=>n.e(4995).then(n.bind(n,6142)),"@site/docs/chat/reply-to-message.md",6142],e62fac9c:[()=>n.e(8292).then(n.t.bind(n,4572,19)),"~blog/default/blog-tags-reproducible-builds-973.json",4572],e88d32a9:[()=>n.e(6585).then(n.t.bind(n,5745,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],e92b958d:[()=>n.e(7011).then(n.t.bind(n,1954,19)),"~blog/default/blog-tags-planning-ec4.json",1954],eb09219a:[()=>n.e(5327).then(n.t.bind(n,2242,19)),"~blog/default/blog-tags-security-handbook-f46-list.json",2242],eb183be6:[()=>n.e(1596).then(n.bind(n,5940)),"@site/docs/profiles/importing-a-profile.md",5940],ebdffa2e:[()=>n.e(4710).then(n.t.bind(n,5797,19)),"~blog/default/blog-tags-libcwtch-b3a.json",5797],ed85aa58:[()=>n.e(1987).then(n.bind(n,274)),"@site/docs/servers/share-key.md",274],ed9713f0:[()=>n.e(7820).then(n.bind(n,7887)),"@site/docs/settings/appearance/light-dark-mode.md",7887],ef243df7:[()=>n.e(7667).then(n.t.bind(n,4354,19)),"~blog/default/blog-tags-planning-ec4-list.json",4354],ef78badf:[()=>n.e(5532).then(n.bind(n,5481)),"@site/blog/2023-01-27-platform-support.md?truncated=true",5481],efb69e30:[()=>n.e(4003).then(n.bind(n,2676)),"@site/docs/chat/conversation-settings.md",2676],f041e880:[()=>n.e(5226).then(n.bind(n,3291)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md?truncated=true",3291],f146017a:[()=>n.e(6241).then(n.bind(n,1354)),"@site/docs/contribute/documentation.md",1354],f47fcb38:[()=>n.e(4325).then(n.t.bind(n,1837,19)),"~docs/default/category-docs-tutorialsidebar-category-groups-c04.json",1837],f4bfc819:[()=>n.e(8430).then(n.bind(n,5096)),"@site/docs/groups/send-invite.md",5096],f76a3b8e:[()=>n.e(2184).then(n.bind(n,3103)),"@site/blog/2023-02-17-cwtch-testing-ii.md?truncated=true",3103],f928e8d9:[()=>n.e(8786).then(n.t.bind(n,7160,19)),"~docs/docs-developer/version-current-metadata-prop-751.json",7160],f92b996b:[()=>n.e(4059).then(n.bind(n,1763)),"@site/security/components/cwtch/message_formats.md",1763],f96ae61b:[()=>n.e(2700).then(n.bind(n,4802)),"@site/docs/profiles/unlock-profile.md",4802],fb3c1916:[()=>n.e(276).then(n.bind(n,8886)),"@site/developing/intro.md",8886],fc0ce2b3:[()=>n.e(6363).then(n.bind(n,7266)),"@site/docs/contribute/testing.md",7266],fd27e325:[()=>n.e(1199).then(n.bind(n,9327)),"@site/developing/building-a-cwtch-app/building-an-echobot.md",9327],fe1dd7ae:[()=>n.e(1979).then(n.bind(n,1501)),"@site/blog/2023-06-07-new-nightly.md?truncated=true",1501]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],p={},f=[],m=[],g=(0,u.Z)(o);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=s[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const f=[{path:"/blog",component:p("/blog","f58"),exact:!0},{path:"/blog/archive",component:p("/blog/archive","2da"),exact:!0},{path:"/blog/autobindings",component:p("/blog/autobindings","1f5"),exact:!0},{path:"/blog/autobindings-ii",component:p("/blog/autobindings-ii","231"),exact:!0},{path:"/blog/availability-status-profile-attributes",component:p("/blog/availability-status-profile-attributes","a8c"),exact:!0},{path:"/blog/cwtch-android-reproducibility",component:p("/blog/cwtch-android-reproducibility","677"),exact:!0},{path:"/blog/cwtch-bindings-reproducible",component:p("/blog/cwtch-bindings-reproducible","279"),exact:!0},{path:"/blog/cwtch-developer-documentation",component:p("/blog/cwtch-developer-documentation","44c"),exact:!0},{path:"/blog/cwtch-documentation",component:p("/blog/cwtch-documentation","968"),exact:!0},{path:"/blog/cwtch-nightly-1-11",component:p("/blog/cwtch-nightly-1-11","a07"),exact:!0},{path:"/blog/cwtch-nightly-1-12",component:p("/blog/cwtch-nightly-1-12","312"),exact:!0},{path:"/blog/cwtch-nightly-v.11-74",component:p("/blog/cwtch-nightly-v.11-74","497"),exact:!0},{path:"/blog/cwtch-platform-support",component:p("/blog/cwtch-platform-support","6f7"),exact:!0},{path:"/blog/cwtch-stable-api-design",component:p("/blog/cwtch-stable-api-design","88b"),exact:!0},{path:"/blog/cwtch-stable-roadmap-update",component:p("/blog/cwtch-stable-roadmap-update","d8b"),exact:!0},{path:"/blog/cwtch-stable-roadmap-update-june",component:p("/blog/cwtch-stable-roadmap-update-june","87b"),exact:!0},{path:"/blog/cwtch-testing-i",component:p("/blog/cwtch-testing-i","346"),exact:!0},{path:"/blog/cwtch-testing-ii",component:p("/blog/cwtch-testing-ii","281"),exact:!0},{path:"/blog/page/2",component:p("/blog/page/2","f98"),exact:!0},{path:"/blog/path-to-cwtch-stable",component:p("/blog/path-to-cwtch-stable","451"),exact:!0},{path:"/blog/tags",component:p("/blog/tags","0a7"),exact:!0},{path:"/blog/tags/api",component:p("/blog/tags/api","ab1"),exact:!0},{path:"/blog/tags/autobindings",component:p("/blog/tags/autobindings","625"),exact:!0},{path:"/blog/tags/bindings",component:p("/blog/tags/bindings","111"),exact:!0},{path:"/blog/tags/cwtch",component:p("/blog/tags/cwtch","251"),exact:!0},{path:"/blog/tags/cwtch-stable",component:p("/blog/tags/cwtch-stable","808"),exact:!0},{path:"/blog/tags/cwtch-stable/page/2",component:p("/blog/tags/cwtch-stable/page/2","b5b"),exact:!0},{path:"/blog/tags/cwtch/page/2",component:p("/blog/tags/cwtch/page/2","01c"),exact:!0},{path:"/blog/tags/developer-documentation",component:p("/blog/tags/developer-documentation","773"),exact:!0},{path:"/blog/tags/documentation",component:p("/blog/tags/documentation","0da"),exact:!0},{path:"/blog/tags/libcwtch",component:p("/blog/tags/libcwtch","b5e"),exact:!0},{path:"/blog/tags/nightly",component:p("/blog/tags/nightly","aea"),exact:!0},{path:"/blog/tags/planning",component:p("/blog/tags/planning","7d1"),exact:!0},{path:"/blog/tags/release",component:p("/blog/tags/release","60a"),exact:!0},{path:"/blog/tags/repliqate",component:p("/blog/tags/repliqate","d17"),exact:!0},{path:"/blog/tags/reproducible-builds",component:p("/blog/tags/reproducible-builds","7bf"),exact:!0},{path:"/blog/tags/security-handbook",component:p("/blog/tags/security-handbook","606"),exact:!0},{path:"/blog/tags/support",component:p("/blog/tags/support","132"),exact:!0},{path:"/blog/tags/testing",component:p("/blog/tags/testing","bc9"),exact:!0},{path:"/developing",component:p("/developing","f07"),routes:[{path:"/developing/building-a-cwtch-app/building-an-echobot",component:p("/developing/building-a-cwtch-app/building-an-echobot","416"),exact:!0,sidebar:"tutorialSidebar"},{path:"/developing/building-a-cwtch-app/core-concepts",component:p("/developing/building-a-cwtch-app/core-concepts","804"),exact:!0,sidebar:"tutorialSidebar"},{path:"/developing/building-a-cwtch-app/intro",component:p("/developing/building-a-cwtch-app/intro","2e9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/developing/category/building-a-cwtch-app",component:p("/developing/category/building-a-cwtch-app","46a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/developing/intro",component:p("/developing/intro","967"),exact:!0,sidebar:"tutorialSidebar"},{path:"/developing/release",component:p("/developing/release","b76"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/docs",component:p("/docs","59e"),routes:[{path:"/docs/category/appearance",component:p("/docs/category/appearance","7b4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/behaviour",component:p("/docs/category/behaviour","e4f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/contribute",component:p("/docs/category/contribute","702"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/conversations",component:p("/docs/category/conversations","d82"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/experiments",component:p("/docs/category/experiments","151"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/getting-started",component:p("/docs/category/getting-started","01f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/groups",component:p("/docs/category/groups","5c5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/platforms",component:p("/docs/category/platforms","3c7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/profiles",component:p("/docs/category/profiles","387"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/servers",component:p("/docs/category/servers","7e8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/category/settings",component:p("/docs/category/settings","a03"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/accept-deny-new-conversation",component:p("/docs/chat/accept-deny-new-conversation","530"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/add-contact",component:p("/docs/chat/add-contact","ff4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/block-contact",component:p("/docs/chat/block-contact","f86"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/conversation-settings",component:p("/docs/chat/conversation-settings","8fa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/delete-contact",component:p("/docs/chat/delete-contact","377"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/introduction",component:p("/docs/chat/introduction","413"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/message-formatting",component:p("/docs/chat/message-formatting","af9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/reply-to-message",component:p("/docs/chat/reply-to-message","cd5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/save-conversation-history",component:p("/docs/chat/save-conversation-history","496"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/share-address-with-friends",component:p("/docs/chat/share-address-with-friends","280"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/share-file",component:p("/docs/chat/share-file","d13"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/chat/unblock-contact",component:p("/docs/chat/unblock-contact","0c8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contribute/developing",component:p("/docs/contribute/developing","9ea"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contribute/documentation",component:p("/docs/contribute/documentation","102"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contribute/stickers",component:p("/docs/contribute/stickers","113"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contribute/testing",component:p("/docs/contribute/testing","1b4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/contribute/translate",component:p("/docs/contribute/translate","4c7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/getting-started/supported_platforms",component:p("/docs/getting-started/supported_platforms","744"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/accept-group-invite",component:p("/docs/groups/accept-group-invite","8be"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/create-group",component:p("/docs/groups/create-group","f6d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/edit-group-name",component:p("/docs/groups/edit-group-name","4f1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/introduction",component:p("/docs/groups/introduction","869"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/leave-group",component:p("/docs/groups/leave-group","d38"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/manage-known-servers",component:p("/docs/groups/manage-known-servers","3b7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/groups/send-invite",component:p("/docs/groups/send-invite","aa7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/intro",component:p("/docs/intro","aed"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/platforms/tails",component:p("/docs/platforms/tails","db5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/availability-status",component:p("/docs/profiles/availability-status","23c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/change-name",component:p("/docs/profiles/change-name","4b7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/change-password",component:p("/docs/profiles/change-password","f4a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/change-profile-image",component:p("/docs/profiles/change-profile-image","d00"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/create-a-profile",component:p("/docs/profiles/create-a-profile","0dd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/delete-profile",component:p("/docs/profiles/delete-profile","f16"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/exporting-profile",component:p("/docs/profiles/exporting-profile","290"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/importing-a-profile",component:p("/docs/profiles/importing-a-profile","bca"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/introduction",component:p("/docs/profiles/introduction","740"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/profile-info",component:p("/docs/profiles/profile-info","87a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/profiles/unlock-profile",component:p("/docs/profiles/unlock-profile","867"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/servers/create-server",component:p("/docs/servers/create-server","ebf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/servers/delete-server",component:p("/docs/servers/delete-server","6dd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/servers/edit-server",component:p("/docs/servers/edit-server","e03"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/servers/introduction",component:p("/docs/servers/introduction","073"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/servers/share-key",component:p("/docs/servers/share-key","6c7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/servers/unlock-server",component:p("/docs/servers/unlock-server","425"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/appearance/change-language",component:p("/docs/settings/appearance/change-language","fc7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/appearance/light-dark-mode",component:p("/docs/settings/appearance/light-dark-mode","790"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/appearance/streamer-mode",component:p("/docs/settings/appearance/streamer-mode","d70"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/appearance/ui-columns",component:p("/docs/settings/appearance/ui-columns","99f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/behaviour/block-unknown-connections",component:p("/docs/settings/behaviour/block-unknown-connections","436"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/behaviour/notification-content",component:p("/docs/settings/behaviour/notification-content","ce9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/behaviour/notification-policy",component:p("/docs/settings/behaviour/notification-policy","34e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/clickable-links",component:p("/docs/settings/experiments/clickable-links","e62"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/file-sharing",component:p("/docs/settings/experiments/file-sharing","763"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/group-experiment",component:p("/docs/settings/experiments/group-experiment","223"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/image-previews-and-profile-pictures",component:p("/docs/settings/experiments/image-previews-and-profile-pictures","bd9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/message-formatting",component:p("/docs/settings/experiments/message-formatting","314"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/qrcodes",component:p("/docs/settings/experiments/qrcodes","095"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/experiments/server-hosting",component:p("/docs/settings/experiments/server-hosting","8a2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/settings/introduction",component:p("/docs/settings/introduction","e3a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/tor",component:p("/docs/tor","94b"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/security",component:p("/security","12c"),routes:[{path:"/security/category/connectivity--tor",component:p("/security/category/connectivity--tor","c9a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/category/cwtch",component:p("/security/category/cwtch","db2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/category/cwtch-components",component:p("/security/category/cwtch-components","b00"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/category/cwtch-ui",component:p("/security/category/cwtch-ui","53f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/category/tapir",component:p("/security/category/tapir","f6e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/connectivity/intro",component:p("/security/components/connectivity/intro","818"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/cwtch/groups",component:p("/security/components/cwtch/groups","843"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/cwtch/key_bundles",component:p("/security/components/cwtch/key_bundles","cbb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/cwtch/message_formats",component:p("/security/components/cwtch/message_formats","609"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/cwtch/server",component:p("/security/components/cwtch/server","92a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/ecosystem-overview",component:p("/security/components/ecosystem-overview","b67"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/intro",component:p("/security/components/intro","74e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/tapir/authentication_protocol",component:p("/security/components/tapir/authentication_protocol","ab3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/tapir/packet_format",component:p("/security/components/tapir/packet_format","4cb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/ui/android",component:p("/security/components/ui/android","f66"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/ui/image_previews",component:p("/security/components/ui/image_previews","976"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/ui/input",component:p("/security/components/ui/input","30b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/components/ui/overlays",component:p("/security/components/ui/overlays","676"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/deployment",component:p("/security/deployment","ef2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/development",component:p("/security/development","5ad"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/intro",component:p("/security/intro","be1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/references",component:p("/security/references","b21"),exact:!0,sidebar:"tutorialSidebar"},{path:"/security/risk",component:p("/security/risk","dc7"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/",component:p("/","057"),exact:!0},{path:"*",component:p("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),g=n(2263),h=n(4996),b=n(6668),v=n(1944),y=n(4711),w=n(9727),k=n(3320),S=n(197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),a=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,u.TH)();return e+(0,h.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function x(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(_,null),r.createElement(E,null),r.createElement(S.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),A=n(8940);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const a=s.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const R=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),P("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function N(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),N(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(R,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const I=O,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",j="__docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${j}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n var suggestionContainer = document.getElementById('${j}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function z(){const{siteConfig:{baseUrl:e}}=(0,g.Z)();return(0,r.useLayoutEffect)((()=>{window[F]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:D}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(z,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,g.Z)(),i=(0,h.Z)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var G=n(4763);function q(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(G.Z,null,r.createElement(A.M,null,r.createElement(L.t,null,r.createElement(p,null,r.createElement($,null),r.createElement(x,null),r.createElement(U,null),r.createElement(I,{location:T(t)},e)))))}var H=n(6887);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var V=n(9670);const W=new Set,Y=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!K()&&!Y.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(H).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!Y.has(e))(e)&&(Y.add(e),N(e))},X=Object.freeze(Q);if(l.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;N(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(q,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"intro","docs":[{"id":"chat/accept-deny-new-conversation","path":"/docs/chat/accept-deny-new-conversation","sidebar":"tutorialSidebar"},{"id":"chat/add-contact","path":"/docs/chat/add-contact","sidebar":"tutorialSidebar"},{"id":"chat/block-contact","path":"/docs/chat/block-contact","sidebar":"tutorialSidebar"},{"id":"chat/conversation-settings","path":"/docs/chat/conversation-settings","sidebar":"tutorialSidebar"},{"id":"chat/delete-contact","path":"/docs/chat/delete-contact","sidebar":"tutorialSidebar"},{"id":"chat/introduction","path":"/docs/chat/introduction","sidebar":"tutorialSidebar"},{"id":"chat/message-formatting","path":"/docs/chat/message-formatting","sidebar":"tutorialSidebar"},{"id":"chat/reply-to-message","path":"/docs/chat/reply-to-message","sidebar":"tutorialSidebar"},{"id":"chat/save-conversation-history","path":"/docs/chat/save-conversation-history","sidebar":"tutorialSidebar"},{"id":"chat/share-address-with-friends","path":"/docs/chat/share-address-with-friends","sidebar":"tutorialSidebar"},{"id":"chat/share-file","path":"/docs/chat/share-file","sidebar":"tutorialSidebar"},{"id":"chat/unblock-contact","path":"/docs/chat/unblock-contact","sidebar":"tutorialSidebar"},{"id":"contribute/developing","path":"/docs/contribute/developing","sidebar":"tutorialSidebar"},{"id":"contribute/documentation","path":"/docs/contribute/documentation","sidebar":"tutorialSidebar"},{"id":"contribute/stickers","path":"/docs/contribute/stickers","sidebar":"tutorialSidebar"},{"id":"contribute/testing","path":"/docs/contribute/testing","sidebar":"tutorialSidebar"},{"id":"contribute/translate","path":"/docs/contribute/translate","sidebar":"tutorialSidebar"},{"id":"getting-started/supported_platforms","path":"/docs/getting-started/supported_platforms","sidebar":"tutorialSidebar"},{"id":"groups/accept-group-invite","path":"/docs/groups/accept-group-invite","sidebar":"tutorialSidebar"},{"id":"groups/create-group","path":"/docs/groups/create-group","sidebar":"tutorialSidebar"},{"id":"groups/edit-group-name","path":"/docs/groups/edit-group-name","sidebar":"tutorialSidebar"},{"id":"groups/introduction","path":"/docs/groups/introduction","sidebar":"tutorialSidebar"},{"id":"groups/leave-group","path":"/docs/groups/leave-group","sidebar":"tutorialSidebar"},{"id":"groups/manage-known-servers","path":"/docs/groups/manage-known-servers","sidebar":"tutorialSidebar"},{"id":"groups/send-invite","path":"/docs/groups/send-invite","sidebar":"tutorialSidebar"},{"id":"intro","path":"/docs/intro","sidebar":"tutorialSidebar"},{"id":"platforms/tails","path":"/docs/platforms/tails","sidebar":"tutorialSidebar"},{"id":"profiles/availability-status","path":"/docs/profiles/availability-status","sidebar":"tutorialSidebar"},{"id":"profiles/change-name","path":"/docs/profiles/change-name","sidebar":"tutorialSidebar"},{"id":"profiles/change-password","path":"/docs/profiles/change-password","sidebar":"tutorialSidebar"},{"id":"profiles/change-profile-image","path":"/docs/profiles/change-profile-image","sidebar":"tutorialSidebar"},{"id":"profiles/create-a-profile","path":"/docs/profiles/create-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/delete-profile","path":"/docs/profiles/delete-profile","sidebar":"tutorialSidebar"},{"id":"profiles/exporting-profile","path":"/docs/profiles/exporting-profile","sidebar":"tutorialSidebar"},{"id":"profiles/importing-a-profile","path":"/docs/profiles/importing-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/introduction","path":"/docs/profiles/introduction","sidebar":"tutorialSidebar"},{"id":"profiles/profile-info","path":"/docs/profiles/profile-info","sidebar":"tutorialSidebar"},{"id":"profiles/unlock-profile","path":"/docs/profiles/unlock-profile","sidebar":"tutorialSidebar"},{"id":"servers/create-server","path":"/docs/servers/create-server","sidebar":"tutorialSidebar"},{"id":"servers/delete-server","path":"/docs/servers/delete-server","sidebar":"tutorialSidebar"},{"id":"servers/edit-server","path":"/docs/servers/edit-server","sidebar":"tutorialSidebar"},{"id":"servers/introduction","path":"/docs/servers/introduction","sidebar":"tutorialSidebar"},{"id":"servers/share-key","path":"/docs/servers/share-key","sidebar":"tutorialSidebar"},{"id":"servers/unlock-server","path":"/docs/servers/unlock-server","sidebar":"tutorialSidebar"},{"id":"settings/appearance/change-language","path":"/docs/settings/appearance/change-language","sidebar":"tutorialSidebar"},{"id":"settings/appearance/light-dark-mode","path":"/docs/settings/appearance/light-dark-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/streamer-mode","path":"/docs/settings/appearance/streamer-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/ui-columns","path":"/docs/settings/appearance/ui-columns","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/block-unknown-connections","path":"/docs/settings/behaviour/block-unknown-connections","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-content","path":"/docs/settings/behaviour/notification-content","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-policy","path":"/docs/settings/behaviour/notification-policy","sidebar":"tutorialSidebar"},{"id":"settings/experiments/clickable-links","path":"/docs/settings/experiments/clickable-links","sidebar":"tutorialSidebar"},{"id":"settings/experiments/file-sharing","path":"/docs/settings/experiments/file-sharing","sidebar":"tutorialSidebar"},{"id":"settings/experiments/group-experiment","path":"/docs/settings/experiments/group-experiment","sidebar":"tutorialSidebar"},{"id":"settings/experiments/image-previews-and-profile-pictures","path":"/docs/settings/experiments/image-previews-and-profile-pictures","sidebar":"tutorialSidebar"},{"id":"settings/experiments/message-formatting","path":"/docs/settings/experiments/message-formatting","sidebar":"tutorialSidebar"},{"id":"settings/experiments/qrcodes","path":"/docs/settings/experiments/qrcodes","sidebar":"tutorialSidebar"},{"id":"settings/experiments/server-hosting","path":"/docs/settings/experiments/server-hosting","sidebar":"tutorialSidebar"},{"id":"settings/introduction","path":"/docs/settings/introduction","sidebar":"tutorialSidebar"},{"id":"tor","path":"/docs/tor","sidebar":"tutorialSidebar"},{"id":"/category/getting-started","path":"/docs/category/getting-started","sidebar":"tutorialSidebar"},{"id":"/category/profiles","path":"/docs/category/profiles","sidebar":"tutorialSidebar"},{"id":"/category/conversations","path":"/docs/category/conversations","sidebar":"tutorialSidebar"},{"id":"/category/groups","path":"/docs/category/groups","sidebar":"tutorialSidebar"},{"id":"/category/servers","path":"/docs/category/servers","sidebar":"tutorialSidebar"},{"id":"/category/settings","path":"/docs/category/settings","sidebar":"tutorialSidebar"},{"id":"/category/appearance","path":"/docs/category/appearance","sidebar":"tutorialSidebar"},{"id":"/category/behaviour","path":"/docs/category/behaviour","sidebar":"tutorialSidebar"},{"id":"/category/experiments","path":"/docs/category/experiments","sidebar":"tutorialSidebar"},{"id":"/category/contribute","path":"/docs/category/contribute","sidebar":"tutorialSidebar"},{"id":"/category/platforms","path":"/docs/category/platforms","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/intro","label":"intro"}}}}],"breadcrumbs":true},"docs-developer":{"path":"/developing","versions":[{"name":"current","label":"Next","isLast":true,"path":"/developing","mainDocId":"intro","docs":[{"id":"building-a-cwtch-app/building-an-echobot","path":"/developing/building-a-cwtch-app/building-an-echobot","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/core-concepts","path":"/developing/building-a-cwtch-app/core-concepts","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/intro","path":"/developing/building-a-cwtch-app/intro","sidebar":"tutorialSidebar"},{"id":"intro","path":"/developing/intro","sidebar":"tutorialSidebar"},{"id":"release","path":"/developing/release","sidebar":"tutorialSidebar"},{"id":"/category/building-a-cwtch-app","path":"/developing/category/building-a-cwtch-app","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/developing/intro","label":"intro"}}}}],"breadcrumbs":true},"docs-security":{"path":"/security","versions":[{"name":"current","label":"Next","isLast":true,"path":"/security","mainDocId":"intro","docs":[{"id":"components/connectivity/intro","path":"/security/components/connectivity/intro","sidebar":"tutorialSidebar"},{"id":"components/cwtch/groups","path":"/security/components/cwtch/groups","sidebar":"tutorialSidebar"},{"id":"components/cwtch/key_bundles","path":"/security/components/cwtch/key_bundles","sidebar":"tutorialSidebar"},{"id":"components/cwtch/message_formats","path":"/security/components/cwtch/message_formats","sidebar":"tutorialSidebar"},{"id":"components/cwtch/server","path":"/security/components/cwtch/server","sidebar":"tutorialSidebar"},{"id":"components/ecosystem-overview","path":"/security/components/ecosystem-overview","sidebar":"tutorialSidebar"},{"id":"components/intro","path":"/security/components/intro","sidebar":"tutorialSidebar"},{"id":"components/tapir/authentication_protocol","path":"/security/components/tapir/authentication_protocol","sidebar":"tutorialSidebar"},{"id":"components/tapir/packet_format","path":"/security/components/tapir/packet_format","sidebar":"tutorialSidebar"},{"id":"components/ui/android","path":"/security/components/ui/android","sidebar":"tutorialSidebar"},{"id":"components/ui/image_previews","path":"/security/components/ui/image_previews","sidebar":"tutorialSidebar"},{"id":"components/ui/input","path":"/security/components/ui/input","sidebar":"tutorialSidebar"},{"id":"components/ui/overlays","path":"/security/components/ui/overlays","sidebar":"tutorialSidebar"},{"id":"deployment","path":"/security/deployment","sidebar":"tutorialSidebar"},{"id":"development","path":"/security/development","sidebar":"tutorialSidebar"},{"id":"intro","path":"/security/intro","sidebar":"tutorialSidebar"},{"id":"references","path":"/security/references","sidebar":"tutorialSidebar"},{"id":"risk","path":"/security/risk","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-components","path":"/security/category/cwtch-components","sidebar":"tutorialSidebar"},{"id":"/category/connectivity--tor","path":"/security/category/connectivity--tor","sidebar":"tutorialSidebar"},{"id":"/category/tapir","path":"/security/category/tapir","sidebar":"tutorialSidebar"},{"id":"/category/cwtch","path":"/security/category/cwtch","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-ui","path":"/security/category/cwtch-ui","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/security/intro","label":"intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en","es","de","it"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"},"es":{"label":"Espa\xf1ol","direction":"ltr","htmlLang":"es","calendar":"gregory","path":"es"},"de":{"label":"Deutsch","direction":"ltr","htmlLang":"de","calendar":"gregory","path":"de"},"it":{"label":"Italiano","direction":"ltr","htmlLang":"it","calendar":"gregory","path":"it"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"}}}'),c={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(412),o=n(5742),i=n(8780),l=n(7961);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(p,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),l=n(2263),s=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,l.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,a.useContext)(u),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const _=p||f;const x=(0,s.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(L=C,b&&(e=>e.startsWith("/"))(L)?k(L):L):void 0;var L;T&&x&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const A=(0,a.useRef)(!1),P=n?o.OL:o.rU,R=c.Z.canUseIntersectionObserver,N=(0,a.useRef)(),O=()=>{A.current||null==T||(window.docusaurus.preload(T),A.current=!0)};(0,a.useEffect)((()=>(!R&&x&&null!=T&&window.docusaurus.prefetch(T),()=>{R&&N.current&&N.current.disconnect()})),[N,T,R,x]);const I=T?.startsWith("#")??!1,D=!T||!x||I;return D||h||S.collectLink(T),D?a.createElement("a",(0,r.Z)({ref:E,href:T},_&&!x&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(P,(0,r.Z)({},v,{onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,R&&e&&x&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T},n&&{isActive:g,activeClassName:m}))}const f=a.forwardRef(p)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>g,gA:()=>p,_r:()=>u,Jo:()=>h,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7961:(e,t,n)=>{"use strict";n.d(t,{Z:()=>dt});var r=n(7294),a=n(6010),o=n(4763),i=n(1944),l=n(7462),s=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??m,{containerRef:n,onClick:a}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:`#${d}`,onClick:a}),t))}var h=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(g,{className:v.skipToContent})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...s}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},s),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E={closeButton:"closeButton_CVFx"};function _(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",E.closeButton,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const x={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(x.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(_,{onClick:n,className:T.announcementBarClose}))}var A=n(2961),P=n(2466);var R=n(902),N=n(3102);const O=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,N.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,R.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(O.Provider,{value:n},t)}function D(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(O);if(!e)throw new R.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:D(o)})),[a,o,t])}function j(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var F=n(2949),B=n(2389);function z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function G(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const l=(0,B.Z)(),s=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!l&&$.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const q=r.memo(G),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,F.I)();return a?null:r.createElement(q,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return r.createElement(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,A.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(Y,null))}var Q=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:s,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,X.Z)(a),f=(0,X.Z)(t),m=(0,X.Z)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,J.Z)(o),h=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,g&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(Q.Z,(0,l.Z)({href:u?m:o},d,h)):r.createElement(Q.Z,(0,l.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},d,h))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),le=n(8596),se=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,l.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},s,{onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),s.children??s.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(_e,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(ne,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(_e,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var fe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ge="iconLanguage_nlXk";var he=n(1875);const be={searchBox:"searchBox_ZlJk"};function ve(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,be.searchBox)},t)}var ye=n(143),we=n(2802);var ke=n(373);const Se=e=>e.docs.find((t=>t.id===e.mainDocId));const Ee={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,se.Z)(),p=(0,fe.l)(),{search:f,hash:m}=(0,s.TH)(),g=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(pe,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:ge}),h),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(ve,{className:n},r.createElement(he.Z,null))},dropdown:pe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.vY)(t,a);return null===s?null:r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===s.path||!!i?.sidebar&&i.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,we.lO)(a)[0],s=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,l.Z)({},o,{label:s,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:p}=(0,s.TH)(),f=(0,ye.Iw)(n),m=(0,ye.gB)(n),{savePreferredVersionName:g}=(0,ke.J)(n),h=[...o,...m.map((e=>{const t=f.alternateDocVersions[e.name]??Se(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>g(e.name)}})),...i],b=(0,we.lO)(n)[0],v=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:Se(b).path;return h.length<=1?r.createElement(oe,(0,l.Z)({},u,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(pe,(0,l.Z)({},u,{mobile:t,label:v,to:y,items:h,isActive:a?()=>!1:void 0}))}};function _e(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function xe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(_e,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ce(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Te(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ce,{onClick:()=>t.hide()}),t.content)}function Le(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(j,{header:r.createElement(K,null),primaryMenu:r.createElement(xe,null),secondaryMenu:r.createElement(Te,null)}):null}const Ae={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Re(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(a.current)return void(a.current=!1);const l=r?.scrollY,s=document.documentElement.scrollHeight-o.current,c=window.innerHeight;l&&i>=l?n(!1):i+c<s&&n(!0)})),(0,u.S)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ae.navbarHideable,!s&&Ae.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Pe,{onClick:i.toggle}),r.createElement(Le,null))}var Ne=n(8780);const Oe={errorBoundaryError:"errorBoundaryError_a6uf"};function Ie(e){return r.createElement("button",(0,l.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function De(e){let{error:t}=e;const n=(0,Ne.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:Oe.errorBoundaryError},n)}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const je="right";function Fe(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Be(){const{toggle:e,shown:t}=(0,A.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Fe,null))}const ze={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Me,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(_e,e)))))}function $e(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function Ge(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??je)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement($e,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Be,null),r.createElement(W,null),r.createElement(Ue,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ue,{items:a}),r.createElement(Z,{className:ze.colorModeToggle}),!o&&r.createElement(ve,null,r.createElement(he.Z,null)))})}function qe(){return r.createElement(Re,null,r.createElement(Ge,null))}function He(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...s}=t,c=(0,X.Z)(n),u=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Q.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},s),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function Ze(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(He,{item:t}))}function Ve(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Ze,{key:t,item:e})))))}function We(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Ve,{key:t,column:e}))))}function Ye(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Ke(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(He,{item:t})}function Qe(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Ke,{item:e}),t.length!==n+1&&r.createElement(Ye,null))))))}function Xe(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(We,{columns:t}):r.createElement(Qe,{links:t})}var Je=n(941);const et={footerLogoLink:"footerLogoLink_BH7S"};function tt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Je.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function nt(e){let{logo:t}=e;return t.href?r.createElement(Q.Z,{href:t.href,className:et.footerLogoLink,target:t.target},r.createElement(tt,{logo:t})):r.createElement(tt,{logo:t})}function rt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function ot(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(at,{style:o,links:n&&n.length>0&&r.createElement(Xe,{links:n}),logo:a&&r.createElement(nt,{logo:a}),copyright:t&&r.createElement(rt,{copyright:t})})}const it=r.memo(ot),lt=(0,R.Qc)([F.S,k.pl,P.OC,ke.L5,i.VC,function(e){let{children:t}=e;return r.createElement(N.n2,null,r.createElement(A.M,null,r.createElement(I,null,t)))}]);function st(e){let{children:t}=e;return r.createElement(lt,null,t)}function ct(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Ie,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(De,{error:t})))))}const ut={mainWrapper:"mainWrapper_z2l0"};function dt(e){const{children:t,noFooter:n,wrapperClassName:l,title:s,description:c}=e;return(0,b.t)(),r.createElement(st,null,r.createElement(i.d,{title:s,description:c}),r.createElement(y,null),r.createElement(L,null),r.createElement(qe,null),r.createElement("div",{id:d,className:(0,a.Z)(h.k.wrapper.main,ut.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(ct,e)},t)),!n&&r.createElement(it,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),l=n(2263),s=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},l=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.Z)(),{navbar:{title:n,logo:c}}=(0,s.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(c?.href||"/"),g=n?"":t,h=c?.alt??g;return a.createElement(o.Z,(0,r.Z)({to:m},f,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:h,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),l=n(2949);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,l.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(s.themedImage,s[`themedImage--${e}`],u)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>h});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const l="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?c:u}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const c=(0,a.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:s?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:l},r)}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:l})):null}function h(e){let{lazy:t,...n}=e;const r=t?g:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),a=n(2389),o=n(12),i=n(902),l=n(6668);const s=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===s.get(),d=e=>s.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),l=n(6668);const s=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>h});var r=n(7294),a=n(143),o=n(9935),i=n(6668),l=n(2802),s=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function h(e){let{children:t}=e;return l.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(f);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(null===e)throw new a.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),l=(n(1688),n(902));function s(e){!function(e){const t=(0,i.k6)(),n=(0,l.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function c(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>x,Wl:()=>m,_F:()=>v,cE:()=>p,jA:()=>g,xz:()=>f,hI:()=>_,lO:()=>k,vY:()=>E,oz:()=>S,s1:()=>w});var r=n(7294),a=n(6550),o=n(8790),i=n(143),l=n(373),s=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!i._r;function f(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,a.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>v(e,t)));function v(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||b(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function w(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function S(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,l=i.find((e=>(0,a.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.H)(i),sidebarName:s,sidebarItems:c}}function x(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),c=n(2263);function u(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),l)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function f(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>s,i6:()=>l,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>s,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&a<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(a-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>s});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function s(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),l=o===n?e:e.replace(`/${o}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(a&&(a+=" "),a+=n);else for(t in e)e[t]&&(a&&(a+=" "),a+=t);return a}n.d(t,{Z:()=>a});const a=function(){for(var e,t,n=0,a="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(a&&(a+=" "),a+=t);return a}},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>L,Ep:()=>p});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r<a;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&a(e),s=t&&a(t),c=l||s;if(e&&a(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=i.length;p>=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(2177);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var g=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",v="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),g||(0,l.Z)(!1);var t,n=window.history,a=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,c=i.forceRefresh,w=void 0!==c&&c,k=i.getUserConfirmation,S=void 0===k?h:k,E=i.keyLength,_=void 0===E?6:E,x=e.basename?d(s(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,a=window.location,o=a.pathname+a.search+a.hash;return x&&(o=u(o,x)),f(o,r,n)}function T(){return Math.random().toString(36).substr(2,_)}var L=m();function A(e){(0,r.Z)(U,e),U.length=n.length,L.notifyListeners(U.location,U.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||O(C(e.state))}function R(){O(C(y()))}var N=!1;function O(e){if(N)N=!1,A();else{L.confirmTransitionTo(e,"POP",S,(function(t){t?A({action:"POP",location:e}):function(e){var t=U.location,n=D.indexOf(t.key);-1===n&&(n=0);var r=D.indexOf(e.key);-1===r&&(r=0);var a=n-r;a&&(N=!0,j(a))}(e)}))}}var I=C(y()),D=[I.key];function M(e){return x+p(e)}function j(e){n.go(e)}var F=0;function B(e){1===(F+=e)&&1===e?(window.addEventListener(b,P),o&&window.addEventListener(v,R)):0===F&&(window.removeEventListener(b,P),o&&window.removeEventListener(v,R))}var z=!1;var U={length:n.length,action:"POP",location:I,createHref:M,push:function(e,t){var r="PUSH",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,l=o.state;if(a)if(n.pushState({key:i,state:l},null,t),w)window.location.href=t;else{var s=D.indexOf(U.location.key),c=D.slice(0,s+1);c.push(o.key),D=c,A({action:r,location:o})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,l=o.state;if(a)if(n.replaceState({key:i,state:l},null,t),w)window.location.replace(t);else{var s=D.indexOf(U.location.key);-1!==s&&(D[s]=o.key),A({action:r,location:o})}else window.location.replace(t)}}))},go:j,goBack:function(){j(-1)},goForward:function(){j(1)},block:function(e){void 0===e&&(e=!1);var t=L.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=L.appendListener(e);return B(1),function(){B(-1),t()}}};return U}var k="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+c(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:c,decodePath:s},slash:{encodePath:s,decodePath:s}};function E(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function _(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function x(e){window.location.replace(E(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),g||(0,l.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),a=n.getUserConfirmation,o=void 0===a?h:a,i=n.hashType,c=void 0===i?"slash":i,b=e.basename?d(s(e.basename)):"",v=S[c],y=v.encodePath,w=v.decodePath;function C(){var e=w(_());return b&&(e=u(e,b)),f(e)}var T=m();function L(e){(0,r.Z)(z,e),z.length=t.length,T.notifyListeners(z.location,z.action)}var A=!1,P=null;function R(){var e,t,n=_(),r=y(n);if(n!==r)x(r);else{var a=C(),i=z.location;if(!A&&(t=a,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===p(a))return;P=null,function(e){if(A)A=!1,L();else{var t="POP";T.confirmTransitionTo(e,t,o,(function(n){n?L({action:t,location:e}):function(e){var t=z.location,n=D.lastIndexOf(p(t));-1===n&&(n=0);var r=D.lastIndexOf(p(e));-1===r&&(r=0);var a=n-r;a&&(A=!0,M(a))}(e)}))}}(a)}}var N=_(),O=y(N);N!==O&&x(O);var I=C(),D=[p(I)];function M(e){t.go(e)}var j=0;function F(e){1===(j+=e)&&1===e?window.addEventListener(k,R):0===j&&window.removeEventListener(k,R)}var B=!1;var z={length:t.length,action:"POP",location:I,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=E(window.location.href)),n+"#"+y(b+p(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);if(_()!==a){P=t,function(e){window.location.hash=e}(a);var o=D.lastIndexOf(p(z.location)),i=D.slice(0,o+1);i.push(t),D=i,L({action:n,location:r})}else L()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);_()!==a&&(P=t,x(a));var o=D.indexOf(p(z.location));-1!==o&&(D[o]=t),L({action:n,location:r})}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return B||(F(1),B=!0),function(){return B&&(B=!1,F(-1)),t()}},listen:function(e){var t=T.appendListener(e);return F(1),function(){F(-1),t()}}};return z}function T(e,t,n){return Math.min(Math.max(e,t),n)}function L(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,a=t.initialEntries,o=void 0===a?["/"]:a,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,c=void 0===s?6:s,u=m();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function g(){return Math.random().toString(36).substr(2,c)}var h=T(l,0,o.length-1),b=o.map((function(e){return f(e,void 0,"string"==typeof e?g():e.key||g())})),v=p;function y(e){var t=T(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:v,push:function(e,t){var r="PUSH",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),g=s(n),h=0;h<i.length;++h){var b=i[h];if(!(o[b]||r&&r[b]||g&&g[b]||l&&l[b])){var v=p(n,b);try{c(t,b,v)}catch(y){}}}}return t}},1143:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function a(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s<arguments.length;s++){for(var c in o=Object(arguments[s]))n.call(o,c)&&(l[c]=o[c]);if(t){i=t(o);for(var u=0;u<i.length;u++)r.call(o,i[u])&&(l[i[u]]=o[i[u]])}}return l}},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(l+=e.slice(i,f),i=f+d.length,p)l+=p[1];else{var m=e[i],g=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=g&&null!=m&&m!==g,S="+"===y||"*"===y,E="?"===y||"*"===y,_=n[2]||u,x=b||v;r.push({name:h||o++,prefix:g||"",delimiter:_,optional:E,repeat:S,partial:k,asterisk:!!w,pattern:x?c(x):w?".*":"[^"+s(_)+"]+?"})}}return i<e.length&&(l+=e.substr(i)),l&&r.push(l),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function l(e,t){for(var n=new Array(e.length),a=0;a<e.length;a++)"object"==typeof e[a]&&(n[a]=new RegExp("^(?:"+e[a].pattern+")$",d(t)));return function(t,a){for(var o="",l=t||{},s=(a||{}).pretty?i:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=l[u.name];if(null==p){if(u.optional){u.partial&&(o+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(r(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=s(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):s(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');o+=u.prefix+d}}else o+=u}return o}}function s(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var a=(n=n||{}).strict,o=!1!==n.end,i="",l=0;l<e.length;l++){var c=e[l];if("string"==typeof c)i+=s(c);else{var p=s(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),i+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var m=s(n.delimiter||"/"),g=i.slice(-m.length)===m;return a||(i=(g?i.slice(0,-m.length):i)+"(?:"+m+"(?=$))?"),i+=o?"$":a&&g?"":"(?="+m+"|$)",u(new RegExp("^"+i,d(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],a=0;a<e.length;a++)r.push(f(e[a],t,n).source);return u(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},7410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var a,o;switch(n=n||{},r.util.type(t)){case"Object":if(o=r.util.objId(t),n[o])return n[o];for(var i in a={},n[o]=a,t)t.hasOwnProperty(i)&&(a[i]=e(t[i],n));return a;case"Array":return o=r.util.objId(t),n[o]?n[o]:(a=[],n[o]=a,t.forEach((function(t,r){a[r]=e(t,n)})),a);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var a in t)n[a]=t[a];return n},insertBefore:function(e,t,n,a){var o=(a=a||r.languages)[e],i={};for(var l in o)if(o.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=o[l])}var c=a[e];return a[e]=i,r.languages.DFS(r.languages,(function(t,n){n===c&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,a,o){o=o||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],a||l);var s=t[l],c=r.util.type(s);"Object"!==c||o[i(s)]?"Array"!==c||o[i(s)]||(o[i(s)]=!0,e(s,n,l,o)):(o[i(s)]=!0,e(s,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};return r.hooks.run("before-tokenize",o),o.tokens=r.tokenize(o.code,o.grammar),r.hooks.run("after-tokenize",o),a.stringify(r.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var a=new l;return s(a,a.head,e),i(e,a,t,a.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(a)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var a,o=0;a=n[o++];)a(t)}},Token:a};function a(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function o(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var o=a[1].length;a.index+=o,a[0]=a[0].slice(o)}return a}function i(e,t,n,l,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(d&&d.cause==p+","+m)return;var g=f[m],h=g.inside,b=!!g.lookbehind,v=!!g.greedy,y=g.alias;if(v&&!g.pattern.global){var w=g.pattern.toString().match(/[imsuy]*$/)[0];g.pattern=RegExp(g.pattern.source,w+"g")}for(var k=g.pattern||g,S=l.next,E=u;S!==t.tail&&!(d&&E>=d.reach);E+=S.value.length,S=S.next){var _=S.value;if(t.length>e.length)return;if(!(_ instanceof a)){var x,C=1;if(v){if(!(x=o(k,E,e,b))||x.index>=e.length)break;var T=x.index,L=x.index+x[0].length,A=E;for(A+=S.value.length;T>=A;)A+=(S=S.next).value.length;if(E=A-=S.value.length,S.value instanceof a)continue;for(var P=S;P!==t.tail&&(A<L||"string"==typeof P.value);P=P.next)C++,A+=P.value.length;C--,_=e.slice(E,A),x.index-=E}else if(!(x=o(k,0,_,b)))continue;T=x.index;var R=x[0],N=_.slice(0,T),O=_.slice(T+R.length),I=E+_.length;d&&I>d.reach&&(d.reach=I);var D=S.prev;if(N&&(D=s(t,D,N),E+=N.length),c(t,D,C),S=s(t,D,new a(p,h?r.tokenize(R,h):R,y,R)),O&&s(t,S,O),C>1){var M={cause:p+","+m,reach:I};i(e,t,n,S.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}return a.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var a="";return t.forEach((function(t){a+=e(t,n)})),a}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),r.hooks.run("wrap",o);var l="";for(var s in o.attributes)l+=" "+s+'="'+(o.attributes[s]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+l+">"+o.content+"</"+o.tag+">"},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i<a.length;i++)o[a[i]]=e.languages.bash[a[i]];e.languages.shell=e.languages.bash}(a),a.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var a=t[n];if("code"===a.type){var o=a.content[1],i=a.content[3];if(o&&i&&"code-language"===o.type&&"code-block"===i.type&&"string"==typeof o.content){var l=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),s="language-"+(l=(/[a-z][\w-]*/i.exec(l)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,s]:i.alias.push(s):i.alias=[s]}}else e(a.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,a=t.classes.length;r<a;r++){var o=t.classes[r],c=/language-(.+)/.exec(o);if(c){n=c[1];break}}var u,d=e.languages[n];if(d)t.content=e.highlight((u=t.content,u.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n);var r=l[t];return r||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var p="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=p,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(p);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var a=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=p(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),a.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),a.length>0)){var l=p(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s<l;s++){var c=t[s];"variable"===c.type&&a.indexOf(c.content)>=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return!1}return!0}function p(e,r){for(var a=1,o=n;o<t.length;o++){var i=t[o],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))a++;else if(r.test(l)&&0===--a)return o}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),a.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return u[n]=a,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=c(u[a]),f=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),f){var g=[f];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r<a;r++){var o=n[r];if("string"!=typeof o){var i=o.content;if(Array.isArray(i))if("template-string"===o.type){var l=i[1];if(3===i.length&&"string"!=typeof l&&"embedded-code"===l.type){var s=p(l),c=l.alias,d=Array.isArray(c)?c[0]:c,f=e.languages[d];if(!f)continue;i[1]=u(s,f,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(a),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var a=n[r],o=e.languages.javascript[a];"RegExp"===e.util.type(o)&&(o=e.languages.javascript[a]={pattern:o});var i=o.inside||{};o.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(a),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=!1;if("string"!=typeof a&&("tag"===a.type&&a.content[0]&&"tag"===a.content[0].type?"</"===a.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),r>0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(a>=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++a;var g=p.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),v=[];g&&v.push.apply(v,i([g])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function a(r,o){if(!(r in n)){o.push(r);var i=o.indexOf(r);if(i<o.length-1)throw new Error("Circular dependency: "+o.slice(i).join(" -> "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;a(m);){for(var g in p={},m){var h=s[g];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in f(b))if(v in u){p[b]=!0;break}for(var y in m=p)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return l[e]=a}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));var l=new Set,s={};function c(e,t){u(e,t),u(e+"Capture",t)}function u(e,t){for(s[e]=t,e=0;e<t.length;e++)l.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f=Object.prototype.hasOwnProperty,m={},g={};function h(e,t,n,r,a,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=a,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){b[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];b[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){b[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){b[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){b[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){b[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){b[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){b[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){b[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,r){var a=b.hasOwnProperty(t)?b[t]:null;(null!==a?0===a.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,a,r)&&(n=null),r||null===a?function(e){return!!f.call(g,e)||!f.call(m,e)&&(p.test(e)?g[e]=!0:(m[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):a.mustUseProperty?e[a.propertyName]=null===n?3!==a.type&&"":n:(t=a.attributeName,r=a.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(a=a.type)||4===a&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),b.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,S=60103,E=60106,_=60107,x=60108,C=60114,T=60109,L=60110,A=60112,P=60113,R=60120,N=60115,O=60116,I=60121,D=60128,M=60129,j=60130,F=60131;if("function"==typeof Symbol&&Symbol.for){var B=Symbol.for;S=B("react.element"),E=B("react.portal"),_=B("react.fragment"),x=B("react.strict_mode"),C=B("react.profiler"),T=B("react.provider"),L=B("react.context"),A=B("react.forward_ref"),P=B("react.suspense"),R=B("react.suspense_list"),N=B("react.memo"),O=B("react.lazy"),I=B("react.block"),B("react.scope"),D=B("react.opaque.id"),M=B("react.debug_trace_mode"),j=B("react.offscreen"),F=B("react.legacy_hidden")}var z,U="function"==typeof Symbol&&Symbol.iterator;function $(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=U&&e[U]||e["@@iterator"])?e:null}function G(e){if(void 0===z)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);z=t&&t[1]||""}return"\n"+z+e}var q=!1;function H(e,t){if(!e||q)return"";q=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(s){var r=s}Reflect.construct(e,[],t)}else{try{t.call()}catch(s){r=s}e.call(t.prototype)}else{try{throw Error()}catch(s){r=s}e()}}catch(s){if(s&&r&&"string"==typeof s.stack){for(var a=s.stack.split("\n"),o=r.stack.split("\n"),i=a.length-1,l=o.length-1;1<=i&&0<=l&&a[i]!==o[l];)l--;for(;1<=i&&0<=l;i--,l--)if(a[i]!==o[l]){if(1!==i||1!==l)do{if(i--,0>--l||a[i]!==o[l])return"\n"+a[i].replace(" at new "," at ")}while(1<=i&&0<=l);break}}}finally{q=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?G(e):""}function Z(e){switch(e.tag){case 5:return G(e.type);case 16:return G("Lazy");case 13:return G("Suspense");case 19:return G("SuspenseList");case 0:case 2:case 15:return e=H(e.type,!1);case 11:return e=H(e.type.render,!1);case 22:return e=H(e.type._render,!1);case 1:return e=H(e.type,!0);default:return""}}function V(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case E:return"Portal";case C:return"Profiler";case x:return"StrictMode";case P:return"Suspense";case R:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case L:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case A:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case N:return V(e.type);case I:return V(e._render);case O:t=e._payload,e=e._init;try{return V(e(t))}catch(n){}}return null}function W(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function Y(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function K(e){e._valueTracker||(e._valueTracker=function(e){var t=Y(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var a=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Y(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function X(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return a({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=W(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=W(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ae(e,t.type,n):t.hasOwnProperty("defaultValue")&&ae(e,t.type,W(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function re(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ae(e,t,n){"number"===t&&X(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function oe(e,t){return e=a({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a<n.length;a++)t["$"+n[a]]=!0;for(n=0;n<e.length;n++)a=t.hasOwnProperty("$"+e[n].value),e[n].selected!==a&&(e[n].selected=a),a&&r&&(e[n].defaultSelected=!0)}else{for(n=""+W(n),t=null,a=0;a<e.length;a++){if(e[a].value===n)return e[a].selected=!0,void(r&&(e[a].defaultSelected=!0));null!==t||e[a].disabled||(t=e[a])}null!==t&&(t.selected=!0)}}function le(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return a({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function se(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:W(n)}}function ce(e,t){var n=W(t.value),r=W(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ue(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function pe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function fe(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?pe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,ge,he=(ge=function(e,t){if(e.namespaceURI!==de.svg||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ge(e,t)}))}:ge);function be(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ve={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ye=["Webkit","ms","Moz","O"];function we(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ve.hasOwnProperty(e)&&ve[e]?(""+t).trim():t+"px"}function ke(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),a=we(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,a):e[n]=a}}Object.keys(ve).forEach((function(e){ye.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ve[t]=ve[e]}))}));var Se=a({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(Se[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function _e(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Ce=null,Te=null,Le=null;function Ae(e){if(e=na(e)){if("function"!=typeof Ce)throw Error(i(280));var t=e.stateNode;t&&(t=aa(t),Ce(e.stateNode,e.type,t))}}function Pe(e){Te?Le?Le.push(e):Le=[e]:Te=e}function Re(){if(Te){var e=Te,t=Le;if(Le=Te=null,Ae(e),t)for(e=0;e<t.length;e++)Ae(t[e])}}function Ne(e,t){return e(t)}function Oe(e,t,n,r,a){return e(t,n,r,a)}function Ie(){}var De=Ne,Me=!1,je=!1;function Fe(){null===Te&&null===Le||(Ie(),Re())}function Be(e,t){var n=e.stateNode;if(null===n)return null;var r=aa(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var ze=!1;if(d)try{var Ue={};Object.defineProperty(Ue,"passive",{get:function(){ze=!0}}),window.addEventListener("test",Ue,Ue),window.removeEventListener("test",Ue,Ue)}catch(ge){ze=!1}function $e(e,t,n,r,a,o,i,l,s){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var Ge=!1,qe=null,He=!1,Ze=null,Ve={onError:function(e){Ge=!0,qe=e}};function We(e,t,n,r,a,o,i,l,s){Ge=!1,qe=null,$e.apply(Ve,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ke(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Qe(e){if(Ye(e)!==e)throw Error(i(188))}function Xe(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var a=n.return;if(null===a)break;var o=a.alternate;if(null===o){if(null!==(r=a.return)){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return Qe(a),e;if(o===r)return Qe(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var l=!1,s=a.child;s;){if(s===n){l=!0,n=a,r=o;break}if(s===r){l=!0,r=a,n=o;break}s=s.sibling}if(!l){for(s=o.child;s;){if(s===n){l=!0,n=o,r=a;break}if(s===r){l=!0,r=o,n=a;break}s=s.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function Je(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var et,tt,nt,rt,at=!1,ot=[],it=null,lt=null,st=null,ct=new Map,ut=new Map,dt=[],pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ft(e,t,n,r,a){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:a,targetContainers:[r]}}function mt(e,t){switch(e){case"focusin":case"focusout":it=null;break;case"dragenter":case"dragleave":lt=null;break;case"mouseover":case"mouseout":st=null;break;case"pointerover":case"pointerout":ct.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":ut.delete(t.pointerId)}}function gt(e,t,n,r,a,o){return null===e||e.nativeEvent!==o?(e=ft(t,n,r,a,o),null!==t&&(null!==(t=na(t))&&tt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==a&&-1===t.indexOf(a)&&t.push(a),e)}function ht(e){var t=ta(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ke(n)))return e.blockedOn=t,void rt(e.lanePriority,(function(){o.unstable_runWithPriority(e.priority,(function(){nt(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function bt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=na(n))&&tt(t),e.blockedOn=n,!1;t.shift()}return!0}function vt(e,t,n){bt(e)&&n.delete(t)}function yt(){for(at=!1;0<ot.length;){var e=ot[0];if(null!==e.blockedOn){null!==(e=na(e.blockedOn))&&et(e);break}for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&ot.shift()}null!==it&&bt(it)&&(it=null),null!==lt&&bt(lt)&&(lt=null),null!==st&&bt(st)&&(st=null),ct.forEach(vt),ut.forEach(vt)}function wt(e,t){e.blockedOn===t&&(e.blockedOn=null,at||(at=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,yt)))}function kt(e){function t(t){return wt(t,e)}if(0<ot.length){wt(ot[0],e);for(var n=1;n<ot.length;n++){var r=ot[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==it&&wt(it,e),null!==lt&&wt(lt,e),null!==st&&wt(st,e),ct.forEach(t),ut.forEach(t),n=0;n<dt.length;n++)(r=dt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<dt.length&&null===(n=dt[0]).blockedOn;)ht(n),null===n.blockedOn&&dt.shift()}function St(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:St("Animation","AnimationEnd"),animationiteration:St("Animation","AnimationIteration"),animationstart:St("Animation","AnimationStart"),transitionend:St("Transition","TransitionEnd")},_t={},xt={};function Ct(e){if(_t[e])return _t[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in xt)return _t[e]=n[t];return e}d&&(xt=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var Tt=Ct("animationend"),Lt=Ct("animationiteration"),At=Ct("animationstart"),Pt=Ct("transitionend"),Rt=new Map,Nt=new Map,Ot=["abort","abort",Tt,"animationEnd",Lt,"animationIteration",At,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Pt,"transitionEnd","waiting","waiting"];function It(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],a=e[n+1];a="on"+(a[0].toUpperCase()+a.slice(1)),Nt.set(r,t),Rt.set(r,a),c(a,[r])}}(0,o.unstable_now)();var Dt=8;function Mt(e){if(0!=(1&e))return Dt=15,1;if(0!=(2&e))return Dt=14,2;if(0!=(4&e))return Dt=13,4;var t=24&e;return 0!==t?(Dt=12,t):0!=(32&e)?(Dt=11,32):0!==(t=192&e)?(Dt=10,t):0!=(256&e)?(Dt=9,256):0!==(t=3584&e)?(Dt=8,t):0!=(4096&e)?(Dt=7,4096):0!==(t=4186112&e)?(Dt=6,t):0!==(t=62914560&e)?(Dt=5,t):67108864&e?(Dt=4,67108864):0!=(134217728&e)?(Dt=3,134217728):0!==(t=805306368&e)?(Dt=2,t):0!=(1073741824&e)?(Dt=1,1073741824):(Dt=8,e)}function jt(e,t){var n=e.pendingLanes;if(0===n)return Dt=0;var r=0,a=0,o=e.expiredLanes,i=e.suspendedLanes,l=e.pingedLanes;if(0!==o)r=o,a=Dt=15;else if(0!==(o=134217727&n)){var s=o&~i;0!==s?(r=Mt(s),a=Dt):0!==(l&=o)&&(r=Mt(l),a=Dt)}else 0!==(o=n&~i)?(r=Mt(o),a=Dt):0!==l&&(r=Mt(l),a=Dt);if(0===r)return 0;if(r=n&((0>(r=31-Gt(r))?0:1<<r)<<1)-1,0!==t&&t!==r&&0==(t&i)){if(Mt(t),a<=Dt)return t;Dt=a}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)a=1<<(n=31-Gt(t)),r|=e[n],t&=~a;return r}function Ft(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function Bt(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=zt(24&~t))?Bt(10,t):e;case 10:return 0===(e=zt(192&~t))?Bt(8,t):e;case 8:return 0===(e=zt(3584&~t))&&(0===(e=zt(4186112&~t))&&(e=512)),e;case 2:return 0===(t=zt(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function zt(e){return e&-e}function Ut(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function $t(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-Gt(t)]=n}var Gt=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(qt(e)/Ht|0)|0},qt=Math.log,Ht=Math.LN2;var Zt=o.unstable_UserBlockingPriority,Vt=o.unstable_runWithPriority,Wt=!0;function Yt(e,t,n,r){Me||Ie();var a=Qt,o=Me;Me=!0;try{Oe(a,e,t,n,r)}finally{(Me=o)||Fe()}}function Kt(e,t,n,r){Vt(Zt,Qt.bind(null,e,t,n,r))}function Qt(e,t,n,r){var a;if(Wt)if((a=0==(4&t))&&0<ot.length&&-1<pt.indexOf(e))e=ft(null,e,t,n,r),ot.push(e);else{var o=Xt(e,t,n,r);if(null===o)a&&mt(e,r);else{if(a){if(-1<pt.indexOf(e))return e=ft(o,e,t,n,r),void ot.push(e);if(function(e,t,n,r,a){switch(t){case"focusin":return it=gt(it,e,t,n,r,a),!0;case"dragenter":return lt=gt(lt,e,t,n,r,a),!0;case"mouseover":return st=gt(st,e,t,n,r,a),!0;case"pointerover":var o=a.pointerId;return ct.set(o,gt(ct.get(o)||null,e,t,n,r,a)),!0;case"gotpointercapture":return o=a.pointerId,ut.set(o,gt(ut.get(o)||null,e,t,n,r,a)),!0}return!1}(o,e,t,n,r))return;mt(e,r)}Ir(e,t,r,null,n)}}}function Xt(e,t,n,r){var a=xe(r);if(null!==(a=ta(a))){var o=Ye(a);if(null===o)a=null;else{var i=o.tag;if(13===i){if(null!==(a=Ke(o)))return a;a=null}else if(3===i){if(o.stateNode.hydrate)return 3===o.tag?o.stateNode.containerInfo:null;a=null}else o!==a&&(a=null)}}return Ir(e,t,r,a,n),null}var Jt=null,en=null,tn=null;function nn(){if(tn)return tn;var e,t,n=en,r=n.length,a="value"in Jt?Jt.value:Jt.textContent,o=a.length;for(e=0;e<r&&n[e]===a[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===a[o-t];t++);return tn=a.slice(e,1<t?1-t:void 0)}function rn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function an(){return!0}function on(){return!1}function ln(e){function t(t,n,r,a,o){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=a,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(a):a[i]);return this.isDefaultPrevented=(null!=a.defaultPrevented?a.defaultPrevented:!1===a.returnValue)?an:on,this.isPropagationStopped=on,this}return a(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=an)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=an)},persist:function(){},isPersistent:an}),t}var sn,cn,un,dn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},pn=ln(dn),fn=a({},dn,{view:0,detail:0}),mn=ln(fn),gn=a({},fn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Tn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==un&&(un&&"mousemove"===e.type?(sn=e.screenX-un.screenX,cn=e.screenY-un.screenY):cn=sn=0,un=e),sn)},movementY:function(e){return"movementY"in e?e.movementY:cn}}),hn=ln(gn),bn=ln(a({},gn,{dataTransfer:0})),vn=ln(a({},fn,{relatedTarget:0})),yn=ln(a({},dn,{animationName:0,elapsedTime:0,pseudoElement:0})),wn=a({},dn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),kn=ln(wn),Sn=ln(a({},dn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},_n={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},xn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Cn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=xn[e])&&!!t[e]}function Tn(){return Cn}var Ln=a({},fn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=rn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?_n[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Tn,charCode:function(e){return"keypress"===e.type?rn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?rn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),An=ln(Ln),Pn=ln(a({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Rn=ln(a({},fn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Tn})),Nn=ln(a({},dn,{propertyName:0,elapsedTime:0,pseudoElement:0})),On=a({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),In=ln(On),Dn=[9,13,27,32],Mn=d&&"CompositionEvent"in window,jn=null;d&&"documentMode"in document&&(jn=document.documentMode);var Fn=d&&"TextEvent"in window&&!jn,Bn=d&&(!Mn||jn&&8<jn&&11>=jn),zn=String.fromCharCode(32),Un=!1;function $n(e,t){switch(e){case"keyup":return-1!==Dn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Gn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var qn=!1;var Hn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Zn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Hn[e.type]:"textarea"===t}function Vn(e,t,n,r){Pe(r),0<(t=Mr(t,"onChange")).length&&(n=new pn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Wn=null,Yn=null;function Kn(e){Lr(e,0)}function Qn(e){if(Q(ra(e)))return e}function Xn(e,t){if("change"===e)return t}var Jn=!1;if(d){var er;if(d){var tr="oninput"in document;if(!tr){var nr=document.createElement("div");nr.setAttribute("oninput","return;"),tr="function"==typeof nr.oninput}er=tr}else er=!1;Jn=er&&(!document.documentMode||9<document.documentMode)}function rr(){Wn&&(Wn.detachEvent("onpropertychange",ar),Yn=Wn=null)}function ar(e){if("value"===e.propertyName&&Qn(Yn)){var t=[];if(Vn(t,Yn,e,xe(e)),e=Kn,Me)e(t);else{Me=!0;try{Ne(e,t)}finally{Me=!1,Fe()}}}}function or(e,t,n){"focusin"===e?(rr(),Yn=n,(Wn=t).attachEvent("onpropertychange",ar)):"focusout"===e&&rr()}function ir(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Qn(Yn)}function lr(e,t){if("click"===e)return Qn(t)}function sr(e,t){if("input"===e||"change"===e)return Qn(t)}var cr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},ur=Object.prototype.hasOwnProperty;function dr(e,t){if(cr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!ur.call(t,n[r])||!cr(e[n[r]],t[n[r]]))return!1;return!0}function pr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function fr(e,t){var n,r=pr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=pr(r)}}function mr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function gr(){for(var e=window,t=X();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=X((e=t.contentWindow).document)}return t}function hr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var br=d&&"documentMode"in document&&11>=document.documentMode,vr=null,yr=null,wr=null,kr=!1;function Sr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;kr||null==vr||vr!==X(r)||("selectionStart"in(r=vr)&&hr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},wr&&dr(wr,r)||(wr=r,0<(r=Mr(yr,"onSelect")).length&&(t=new pn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=vr)))}It("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),It("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),It(Ot,2);for(var Er="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),_r=0;_r<Er.length;_r++)Nt.set(Er[_r],0);u("onMouseEnter",["mouseout","mouseover"]),u("onMouseLeave",["mouseout","mouseover"]),u("onPointerEnter",["pointerout","pointerover"]),u("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var xr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Cr=new Set("cancel close invalid load scroll toggle".split(" ").concat(xr));function Tr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,a,o,l,s,c){if(We.apply(this,arguments),Ge){if(!Ge)throw Error(i(198));var u=qe;Ge=!1,qe=null,He||(He=!0,Ze=u)}}(r,t,void 0,e),e.currentTarget=null}function Lr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],a=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,c=l.currentTarget;if(l=l.listener,s!==o&&a.isPropagationStopped())break e;Tr(a,l,c),o=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,c=l.currentTarget,l=l.listener,s!==o&&a.isPropagationStopped())break e;Tr(a,l,c),o=s}}}if(He)throw e=Ze,He=!1,Ze=null,e}function Ar(e,t){var n=oa(t),r=e+"__bubble";n.has(r)||(Or(t,e,2,!1),n.add(r))}var Pr="_reactListening"+Math.random().toString(36).slice(2);function Rr(e){e[Pr]||(e[Pr]=!0,l.forEach((function(t){Cr.has(t)||Nr(t,!1,e,null),Nr(t,!0,e,null)})))}function Nr(e,t,n,r){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,o=n;if("selectionchange"===e&&9!==n.nodeType&&(o=n.ownerDocument),null!==r&&!t&&Cr.has(e)){if("scroll"!==e)return;a|=2,o=r}var i=oa(o),l=e+"__"+(t?"capture":"bubble");i.has(l)||(t&&(a|=4),Or(o,e,a,t),i.add(l))}function Or(e,t,n,r){var a=Nt.get(t);switch(void 0===a?2:a){case 0:a=Yt;break;case 1:a=Kt;break;default:a=Qt}n=a.bind(null,t,n,e),a=void 0,!ze||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(a=!0),r?void 0!==a?e.addEventListener(t,n,{capture:!0,passive:a}):e.addEventListener(t,n,!0):void 0!==a?e.addEventListener(t,n,{passive:a}):e.addEventListener(t,n,!1)}function Ir(e,t,n,r,a){var o=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===a||8===l.nodeType&&l.parentNode===a)break;if(4===i)for(i=r.return;null!==i;){var s=i.tag;if((3===s||4===s)&&((s=i.stateNode.containerInfo)===a||8===s.nodeType&&s.parentNode===a))return;i=i.return}for(;null!==l;){if(null===(i=ta(l)))return;if(5===(s=i.tag)||6===s){r=o=i;continue e}l=l.parentNode}}r=r.return}!function(e,t,n){if(je)return e(t,n);je=!0;try{return De(e,t,n)}finally{je=!1,Fe()}}((function(){var r=o,a=xe(n),i=[];e:{var l=Rt.get(e);if(void 0!==l){var s=pn,c=e;switch(e){case"keypress":if(0===rn(n))break e;case"keydown":case"keyup":s=An;break;case"focusin":c="focus",s=vn;break;case"focusout":c="blur",s=vn;break;case"beforeblur":case"afterblur":s=vn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":s=hn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":s=bn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":s=Rn;break;case Tt:case Lt:case At:s=yn;break;case Pt:s=Nn;break;case"scroll":s=mn;break;case"wheel":s=In;break;case"copy":case"cut":case"paste":s=kn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":s=Pn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==l?l+"Capture":null:l;u=[];for(var f,m=r;null!==m;){var g=(f=m).stateNode;if(5===f.tag&&null!==g&&(f=g,null!==p&&(null!=(g=Be(m,p))&&u.push(Dr(m,g,f)))),d)break;m=m.return}0<u.length&&(l=new s(l,c,null,n,a),i.push({event:l,listeners:u}))}}if(0==(7&t)){if(s="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(c=n.relatedTarget||n.fromElement)||!ta(c)&&!c[Jr])&&(s||l)&&(l=a.window===a?a:(l=a.ownerDocument)?l.defaultView||l.parentWindow:window,s?(s=r,null!==(c=(c=n.relatedTarget||n.toElement)?ta(c):null)&&(c!==(d=Ye(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(s=null,c=r),s!==c)){if(u=hn,g="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Pn,g="onPointerLeave",p="onPointerEnter",m="pointer"),d=null==s?l:ra(s),f=null==c?l:ra(c),(l=new u(g,m+"leave",s,n,a)).target=d,l.relatedTarget=f,g=null,ta(a)===r&&((u=new u(p,m+"enter",c,n,a)).target=f,u.relatedTarget=d,g=u),d=g,s&&c)e:{for(p=c,m=0,f=u=s;f;f=jr(f))m++;for(f=0,g=p;g;g=jr(g))f++;for(;0<m-f;)u=jr(u),m--;for(;0<f-m;)p=jr(p),f--;for(;m--;){if(u===p||null!==p&&u===p.alternate)break e;u=jr(u),p=jr(p)}u=null}else u=null;null!==s&&Fr(i,l,s,u,!1),null!==c&&null!==d&&Fr(i,d,c,u,!0)}if("select"===(s=(l=r?ra(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===s&&"file"===l.type)var h=Xn;else if(Zn(l))if(Jn)h=sr;else{h=ir;var b=or}else(s=l.nodeName)&&"input"===s.toLowerCase()&&("checkbox"===l.type||"radio"===l.type)&&(h=lr);switch(h&&(h=h(e,r))?Vn(i,h,n,a):(b&&b(e,l,r),"focusout"===e&&(b=l._wrapperState)&&b.controlled&&"number"===l.type&&ae(l,"number",l.value)),b=r?ra(r):window,e){case"focusin":(Zn(b)||"true"===b.contentEditable)&&(vr=b,yr=r,wr=null);break;case"focusout":wr=yr=vr=null;break;case"mousedown":kr=!0;break;case"contextmenu":case"mouseup":case"dragend":kr=!1,Sr(i,n,a);break;case"selectionchange":if(br)break;case"keydown":case"keyup":Sr(i,n,a)}var v;if(Mn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else qn?$n(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Bn&&"ko"!==n.locale&&(qn||"onCompositionStart"!==y?"onCompositionEnd"===y&&qn&&(v=nn()):(en="value"in(Jt=a)?Jt.value:Jt.textContent,qn=!0)),0<(b=Mr(r,y)).length&&(y=new Sn(y,e,null,n,a),i.push({event:y,listeners:b}),v?y.data=v:null!==(v=Gn(n))&&(y.data=v))),(v=Fn?function(e,t){switch(e){case"compositionend":return Gn(t);case"keypress":return 32!==t.which?null:(Un=!0,zn);case"textInput":return(e=t.data)===zn&&Un?null:e;default:return null}}(e,n):function(e,t){if(qn)return"compositionend"===e||!Mn&&$n(e,t)?(e=nn(),tn=en=Jt=null,qn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Bn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Mr(r,"onBeforeInput")).length&&(a=new Sn("onBeforeInput","beforeinput",null,n,a),i.push({event:a,listeners:r}),a.data=v))}Lr(i,t)}))}function Dr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Mr(e,t){for(var n=t+"Capture",r=[];null!==e;){var a=e,o=a.stateNode;5===a.tag&&null!==o&&(a=o,null!=(o=Be(e,n))&&r.unshift(Dr(e,o,a)),null!=(o=Be(e,t))&&r.push(Dr(e,o,a))),e=e.return}return r}function jr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Fr(e,t,n,r,a){for(var o=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,c=l.stateNode;if(null!==s&&s===r)break;5===l.tag&&null!==c&&(l=c,a?null!=(s=Be(n,o))&&i.unshift(Dr(n,s,l)):a||null!=(s=Be(n,o))&&i.push(Dr(n,s,l))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function Br(){}var zr=null,Ur=null;function $r(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function Gr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var qr="function"==typeof setTimeout?setTimeout:void 0,Hr="function"==typeof clearTimeout?clearTimeout:void 0;function Zr(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Vr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Wr(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Yr=0;var Kr=Math.random().toString(36).slice(2),Qr="__reactFiber$"+Kr,Xr="__reactProps$"+Kr,Jr="__reactContainer$"+Kr,ea="__reactEvents$"+Kr;function ta(e){var t=e[Qr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Jr]||n[Qr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Wr(e);null!==e;){if(n=e[Qr])return n;e=Wr(e)}return t}n=(e=n).parentNode}return null}function na(e){return!(e=e[Qr]||e[Jr])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function ra(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function aa(e){return e[Xr]||null}function oa(e){var t=e[ea];return void 0===t&&(t=e[ea]=new Set),t}var ia=[],la=-1;function sa(e){return{current:e}}function ca(e){0>la||(e.current=ia[la],ia[la]=null,la--)}function ua(e,t){la++,ia[la]=e.current,e.current=t}var da={},pa=sa(da),fa=sa(!1),ma=da;function ga(e,t){var n=e.type.contextTypes;if(!n)return da;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var a,o={};for(a in n)o[a]=t[a];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function ha(e){return null!=(e=e.childContextTypes)}function ba(){ca(fa),ca(pa)}function va(e,t,n){if(pa.current!==da)throw Error(i(168));ua(pa,t),ua(fa,n)}function ya(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(i(108,V(t)||"Unknown",o));return a({},n,r)}function wa(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||da,ma=pa.current,ua(pa,e),ua(fa,fa.current),!0}function ka(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=ya(e,t,ma),r.__reactInternalMemoizedMergedChildContext=e,ca(fa),ca(pa),ua(pa,e)):ca(fa),ua(fa,n)}var Sa=null,Ea=null,_a=o.unstable_runWithPriority,xa=o.unstable_scheduleCallback,Ca=o.unstable_cancelCallback,Ta=o.unstable_shouldYield,La=o.unstable_requestPaint,Aa=o.unstable_now,Pa=o.unstable_getCurrentPriorityLevel,Ra=o.unstable_ImmediatePriority,Na=o.unstable_UserBlockingPriority,Oa=o.unstable_NormalPriority,Ia=o.unstable_LowPriority,Da=o.unstable_IdlePriority,Ma={},ja=void 0!==La?La:function(){},Fa=null,Ba=null,za=!1,Ua=Aa(),$a=1e4>Ua?Aa:function(){return Aa()-Ua};function Ga(){switch(Pa()){case Ra:return 99;case Na:return 98;case Oa:return 97;case Ia:return 96;case Da:return 95;default:throw Error(i(332))}}function qa(e){switch(e){case 99:return Ra;case 98:return Na;case 97:return Oa;case 96:return Ia;case 95:return Da;default:throw Error(i(332))}}function Ha(e,t){return e=qa(e),_a(e,t)}function Za(e,t,n){return e=qa(e),xa(e,t,n)}function Va(){if(null!==Ba){var e=Ba;Ba=null,Ca(e)}Wa()}function Wa(){if(!za&&null!==Fa){za=!0;var e=0;try{var t=Fa;Ha(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),Fa=null}catch(n){throw null!==Fa&&(Fa=Fa.slice(e+1)),xa(Ra,Va),n}finally{za=!1}}}var Ya=k.ReactCurrentBatchConfig;function Ka(e,t){if(e&&e.defaultProps){for(var n in t=a({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Qa=sa(null),Xa=null,Ja=null,eo=null;function to(){eo=Ja=Xa=null}function no(e){var t=Qa.current;ca(Qa),e.type._context._currentValue=t}function ro(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function ao(e,t){Xa=e,eo=Ja=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Mi=!0),e.firstContext=null)}function oo(e,t){if(eo!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(eo=e,t=1073741823),t={context:e,observedBits:t,next:null},null===Ja){if(null===Xa)throw Error(i(308));Ja=t,Xa.dependencies={lanes:0,firstContext:t,responders:null}}else Ja=Ja.next=t;return e._currentValue}var io=!1;function lo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function so(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function co(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function uo(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function po(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var a=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===o?a=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?a=o=t:o=o.next=t}else a=o=t;return n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:o,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function fo(e,t,n,r){var o=e.updateQueue;io=!1;var i=o.firstBaseUpdate,l=o.lastBaseUpdate,s=o.shared.pending;if(null!==s){o.shared.pending=null;var c=s,u=c.next;c.next=null,null===l?i=u:l.next=u,l=c;var d=e.alternate;if(null!==d){var p=(d=d.updateQueue).lastBaseUpdate;p!==l&&(null===p?d.firstBaseUpdate=u:p.next=u,d.lastBaseUpdate=c)}}if(null!==i){for(p=o.baseState,l=0,d=u=c=null;;){s=i.lane;var f=i.eventTime;if((r&s)===s){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var m=e,g=i;switch(s=t,f=n,g.tag){case 1:if("function"==typeof(m=g.payload)){p=m.call(f,p,s);break e}p=m;break e;case 3:m.flags=-4097&m.flags|64;case 0:if(null==(s="function"==typeof(m=g.payload)?m.call(f,p,s):m))break e;p=a({},p,s);break e;case 2:io=!0}}null!==i.callback&&(e.flags|=32,null===(s=o.effects)?o.effects=[i]:s.push(i))}else f={eventTime:f,lane:s,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(u=d=f,c=p):d=d.next=f,l|=s;if(null===(i=i.next)){if(null===(s=o.shared.pending))break;i=s.next,s.next=null,o.lastBaseUpdate=s,o.shared.pending=null}}null===d&&(c=p),o.baseState=c,o.firstBaseUpdate=u,o.lastBaseUpdate=d,Ul|=l,e.lanes=l,e.memoizedState=p}}function mo(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],a=r.callback;if(null!==a){if(r.callback=null,r=n,"function"!=typeof a)throw Error(i(191,a));a.call(r)}}}var go=(new r.Component).refs;function ho(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:a({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var bo={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=ps(),a=fs(e),o=co(r,a);o.payload=t,null!=n&&(o.callback=n),uo(e,o),ms(e,a,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=ps(),a=fs(e),o=co(r,a);o.tag=1,o.payload=t,null!=n&&(o.callback=n),uo(e,o),ms(e,a,r)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=ps(),r=fs(e),a=co(n,r);a.tag=2,null!=t&&(a.callback=t),uo(e,a),ms(e,r,n)}};function vo(e,t,n,r,a,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!dr(n,r)||!dr(a,o))}function yo(e,t,n){var r=!1,a=da,o=t.contextType;return"object"==typeof o&&null!==o?o=oo(o):(a=ha(t)?ma:pa.current,o=(r=null!=(r=t.contextTypes))?ga(e,a):da),t=new t(n,o),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=bo,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=a,e.__reactInternalMemoizedMaskedChildContext=o),t}function wo(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&bo.enqueueReplaceState(t,t.state,null)}function ko(e,t,n,r){var a=e.stateNode;a.props=n,a.state=e.memoizedState,a.refs=go,lo(e);var o=t.contextType;"object"==typeof o&&null!==o?a.context=oo(o):(o=ha(t)?ma:pa.current,a.context=ga(e,o)),fo(e,n,a,r),a.state=e.memoizedState,"function"==typeof(o=t.getDerivedStateFromProps)&&(ho(e,t,o,n),a.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof a.getSnapshotBeforeUpdate||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||(t=a.state,"function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount(),t!==a.state&&bo.enqueueReplaceState(a,a.state,null),fo(e,n,a,r),a.state=e.memoizedState),"function"==typeof a.componentDidMount&&(e.flags|=4)}var So=Array.isArray;function Eo(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=r.refs;t===go&&(t=r.refs={}),null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function _o(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function xo(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function a(e,t){return(e=Zs(e,t)).index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags=2,n):r:(t.flags=2,n):n}function l(t){return e&&null===t.alternate&&(t.flags=2),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ks(n,e.mode,r)).return=e,t):((t=a(t,n)).return=e,t)}function c(e,t,n,r){return null!==t&&t.elementType===n.type?((r=a(t,n.props)).ref=Eo(e,t,n),r.return=e,r):((r=Vs(n.type,n.key,n.props,null,e.mode,r)).ref=Eo(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Qs(n,e.mode,r)).return=e,t):((t=a(t,n.children||[])).return=e,t)}function d(e,t,n,r,o){return null===t||7!==t.tag?((t=Ws(n,e.mode,r,o)).return=e,t):((t=a(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Ks(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case S:return(n=Vs(t.type,t.key,t.props,null,e.mode,n)).ref=Eo(e,null,t),n.return=e,n;case E:return(t=Qs(t,e.mode,n)).return=e,t}if(So(t)||$(t))return(t=Ws(t,e.mode,n,null)).return=e,t;_o(e,t)}return null}function f(e,t,n,r){var a=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==a?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case S:return n.key===a?n.type===_?d(e,t,n.props.children,r,a):c(e,t,n,r):null;case E:return n.key===a?u(e,t,n,r):null}if(So(n)||$(n))return null!==a?null:d(e,t,n,r,null);_o(e,n)}return null}function m(e,t,n,r,a){if("string"==typeof r||"number"==typeof r)return s(t,e=e.get(n)||null,""+r,a);if("object"==typeof r&&null!==r){switch(r.$$typeof){case S:return e=e.get(null===r.key?n:r.key)||null,r.type===_?d(t,e,r.props.children,a,r.key):c(t,e,r,a);case E:return u(t,e=e.get(null===r.key?n:r.key)||null,r,a)}if(So(r)||$(r))return d(t,e=e.get(n)||null,r,a,null);_o(t,r)}return null}function g(a,i,l,s){for(var c=null,u=null,d=i,g=i=0,h=null;null!==d&&g<l.length;g++){d.index>g?(h=d,d=null):h=d.sibling;var b=f(a,d,l[g],s);if(null===b){null===d&&(d=h);break}e&&d&&null===b.alternate&&t(a,d),i=o(b,i,g),null===u?c=b:u.sibling=b,u=b,d=h}if(g===l.length)return n(a,d),c;if(null===d){for(;g<l.length;g++)null!==(d=p(a,l[g],s))&&(i=o(d,i,g),null===u?c=d:u.sibling=d,u=d);return c}for(d=r(a,d);g<l.length;g++)null!==(h=m(d,a,g,l[g],s))&&(e&&null!==h.alternate&&d.delete(null===h.key?g:h.key),i=o(h,i,g),null===u?c=h:u.sibling=h,u=h);return e&&d.forEach((function(e){return t(a,e)})),c}function h(a,l,s,c){var u=$(s);if("function"!=typeof u)throw Error(i(150));if(null==(s=u.call(s)))throw Error(i(151));for(var d=u=null,g=l,h=l=0,b=null,v=s.next();null!==g&&!v.done;h++,v=s.next()){g.index>h?(b=g,g=null):b=g.sibling;var y=f(a,g,v.value,c);if(null===y){null===g&&(g=b);break}e&&g&&null===y.alternate&&t(a,g),l=o(y,l,h),null===d?u=y:d.sibling=y,d=y,g=b}if(v.done)return n(a,g),u;if(null===g){for(;!v.done;h++,v=s.next())null!==(v=p(a,v.value,c))&&(l=o(v,l,h),null===d?u=v:d.sibling=v,d=v);return u}for(g=r(a,g);!v.done;h++,v=s.next())null!==(v=m(g,a,h,v.value,c))&&(e&&null!==v.alternate&&g.delete(null===v.key?h:v.key),l=o(v,l,h),null===d?u=v:d.sibling=v,d=v);return e&&g.forEach((function(e){return t(a,e)})),u}return function(e,r,o,s){var c="object"==typeof o&&null!==o&&o.type===_&&null===o.key;c&&(o=o.props.children);var u="object"==typeof o&&null!==o;if(u)switch(o.$$typeof){case S:e:{for(u=o.key,c=r;null!==c;){if(c.key===u){if(7===c.tag){if(o.type===_){n(e,c.sibling),(r=a(c,o.props.children)).return=e,e=r;break e}}else if(c.elementType===o.type){n(e,c.sibling),(r=a(c,o.props)).ref=Eo(e,c,o),r.return=e,e=r;break e}n(e,c);break}t(e,c),c=c.sibling}o.type===_?((r=Ws(o.props.children,e.mode,s,o.key)).return=e,e=r):((s=Vs(o.type,o.key,o.props,null,e.mode,s)).ref=Eo(e,r,o),s.return=e,e=s)}return l(e);case E:e:{for(c=o.key;null!==r;){if(r.key===c){if(4===r.tag&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),(r=a(r,o.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Qs(o,e.mode,s)).return=e,e=r}return l(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==r&&6===r.tag?(n(e,r.sibling),(r=a(r,o)).return=e,e=r):(n(e,r),(r=Ks(o,e.mode,s)).return=e,e=r),l(e);if(So(o))return g(e,r,o,s);if($(o))return h(e,r,o,s);if(u&&_o(e,o),void 0===o&&!c)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,V(e.type)||"Component"))}return n(e,r)}}var Co=xo(!0),To=xo(!1),Lo={},Ao=sa(Lo),Po=sa(Lo),Ro=sa(Lo);function No(e){if(e===Lo)throw Error(i(174));return e}function Oo(e,t){switch(ua(Ro,t),ua(Po,e),ua(Ao,Lo),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:fe(null,"");break;default:t=fe(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}ca(Ao),ua(Ao,t)}function Io(){ca(Ao),ca(Po),ca(Ro)}function Do(e){No(Ro.current);var t=No(Ao.current),n=fe(t,e.type);t!==n&&(ua(Po,e),ua(Ao,n))}function Mo(e){Po.current===e&&(ca(Ao),ca(Po))}var jo=sa(0);function Fo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Bo=null,zo=null,Uo=!1;function $o(e,t){var n=qs(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function Go(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function qo(e){if(Uo){var t=zo;if(t){var n=t;if(!Go(e,t)){if(!(t=Vr(n.nextSibling))||!Go(e,t))return e.flags=-1025&e.flags|2,Uo=!1,void(Bo=e);$o(Bo,n)}Bo=e,zo=Vr(t.firstChild)}else e.flags=-1025&e.flags|2,Uo=!1,Bo=e}}function Ho(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;Bo=e}function Zo(e){if(e!==Bo)return!1;if(!Uo)return Ho(e),Uo=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!Gr(t,e.memoizedProps))for(t=zo;t;)$o(e,t),t=Vr(t.nextSibling);if(Ho(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){zo=Vr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}zo=null}}else zo=Bo?Vr(e.stateNode.nextSibling):null;return!0}function Vo(){zo=Bo=null,Uo=!1}var Wo=[];function Yo(){for(var e=0;e<Wo.length;e++)Wo[e]._workInProgressVersionPrimary=null;Wo.length=0}var Ko=k.ReactCurrentDispatcher,Qo=k.ReactCurrentBatchConfig,Xo=0,Jo=null,ei=null,ti=null,ni=!1,ri=!1;function ai(){throw Error(i(321))}function oi(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!cr(e[n],t[n]))return!1;return!0}function ii(e,t,n,r,a,o){if(Xo=o,Jo=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Ko.current=null===e||null===e.memoizedState?Ni:Oi,e=n(r,a),ri){o=0;do{if(ri=!1,!(25>o))throw Error(i(301));o+=1,ti=ei=null,t.updateQueue=null,Ko.current=Ii,e=n(r,a)}while(ri)}if(Ko.current=Ri,t=null!==ei&&null!==ei.next,Xo=0,ti=ei=Jo=null,ni=!1,t)throw Error(i(300));return e}function li(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ti?Jo.memoizedState=ti=e:ti=ti.next=e,ti}function si(){if(null===ei){var e=Jo.alternate;e=null!==e?e.memoizedState:null}else e=ei.next;var t=null===ti?Jo.memoizedState:ti.next;if(null!==t)ti=t,ei=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ei=e).memoizedState,baseState:ei.baseState,baseQueue:ei.baseQueue,queue:ei.queue,next:null},null===ti?Jo.memoizedState=ti=e:ti=ti.next=e}return ti}function ci(e,t){return"function"==typeof t?t(e):t}function ui(e){var t=si(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=ei,a=r.baseQueue,o=n.pending;if(null!==o){if(null!==a){var l=a.next;a.next=o.next,o.next=l}r.baseQueue=a=o,n.pending=null}if(null!==a){a=a.next,r=r.baseState;var s=l=o=null,c=a;do{var u=c.lane;if((Xo&u)===u)null!==s&&(s=s.next={lane:0,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null}),r=c.eagerReducer===e?c.eagerState:e(r,c.action);else{var d={lane:u,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null};null===s?(l=s=d,o=r):s=s.next=d,Jo.lanes|=u,Ul|=u}c=c.next}while(null!==c&&c!==a);null===s?o=r:s.next=l,cr(r,t.memoizedState)||(Mi=!0),t.memoizedState=r,t.baseState=o,t.baseQueue=s,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function di(e){var t=si(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(null!==a){n.pending=null;var l=a=a.next;do{o=e(o,l.action),l=l.next}while(l!==a);cr(o,t.memoizedState)||(Mi=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function pi(e,t,n){var r=t._getVersion;r=r(t._source);var a=t._workInProgressVersionPrimary;if(null!==a?e=a===r:(e=e.mutableReadLanes,(e=(Xo&e)===e)&&(t._workInProgressVersionPrimary=r,Wo.push(t))),e)return n(t._source);throw Wo.push(t),Error(i(350))}function fi(e,t,n,r){var a=Ol;if(null===a)throw Error(i(349));var o=t._getVersion,l=o(t._source),s=Ko.current,c=s.useState((function(){return pi(a,t,n)})),u=c[1],d=c[0];c=ti;var p=e.memoizedState,f=p.refs,m=f.getSnapshot,g=p.source;p=p.subscribe;var h=Jo;return e.memoizedState={refs:f,source:t,subscribe:r},s.useEffect((function(){f.getSnapshot=n,f.setSnapshot=u;var e=o(t._source);if(!cr(l,e)){e=n(t._source),cr(d,e)||(u(e),e=fs(h),a.mutableReadLanes|=e&a.pendingLanes),e=a.mutableReadLanes,a.entangledLanes|=e;for(var r=a.entanglements,i=e;0<i;){var s=31-Gt(i),c=1<<s;r[s]|=e,i&=~c}}}),[n,t,r]),s.useEffect((function(){return r(t._source,(function(){var e=f.getSnapshot,n=f.setSnapshot;try{n(e(t._source));var r=fs(h);a.mutableReadLanes|=r&a.pendingLanes}catch(o){n((function(){throw o}))}}))}),[t,r]),cr(m,n)&&cr(g,t)&&cr(p,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:d}).dispatch=u=Pi.bind(null,Jo,e),c.queue=e,c.baseQueue=null,d=pi(a,t,n),c.memoizedState=c.baseState=d),d}function mi(e,t,n){return fi(si(),e,t,n)}function gi(e){var t=li();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:e}).dispatch=Pi.bind(null,Jo,e),[t.memoizedState,e]}function hi(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=Jo.updateQueue)?(t={lastEffect:null},Jo.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function bi(e){return e={current:e},li().memoizedState=e}function vi(){return si().memoizedState}function yi(e,t,n,r){var a=li();Jo.flags|=e,a.memoizedState=hi(1|t,n,void 0,void 0===r?null:r)}function wi(e,t,n,r){var a=si();r=void 0===r?null:r;var o=void 0;if(null!==ei){var i=ei.memoizedState;if(o=i.destroy,null!==r&&oi(r,i.deps))return void hi(t,n,o,r)}Jo.flags|=e,a.memoizedState=hi(1|t,n,o,r)}function ki(e,t){return yi(516,4,e,t)}function Si(e,t){return wi(516,4,e,t)}function Ei(e,t){return wi(4,2,e,t)}function _i(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function xi(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,_i.bind(null,t,e),n)}function Ci(){}function Ti(e,t){var n=si();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Li(e,t){var n=si();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Ai(e,t){var n=Ga();Ha(98>n?98:n,(function(){e(!0)})),Ha(97<n?97:n,(function(){var n=Qo.transition;Qo.transition=1;try{e(!1),t()}finally{Qo.transition=n}}))}function Pi(e,t,n){var r=ps(),a=fs(e),o={lane:a,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?o.next=o:(o.next=i.next,i.next=o),t.pending=o,i=e.alternate,e===Jo||null!==i&&i===Jo)ri=ni=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var l=t.lastRenderedState,s=i(l,n);if(o.eagerReducer=i,o.eagerState=s,cr(s,l))return}catch(c){}ms(e,a,r)}}var Ri={readContext:oo,useCallback:ai,useContext:ai,useEffect:ai,useImperativeHandle:ai,useLayoutEffect:ai,useMemo:ai,useReducer:ai,useRef:ai,useState:ai,useDebugValue:ai,useDeferredValue:ai,useTransition:ai,useMutableSource:ai,useOpaqueIdentifier:ai,unstable_isNewReconciler:!1},Ni={readContext:oo,useCallback:function(e,t){return li().memoizedState=[e,void 0===t?null:t],e},useContext:oo,useEffect:ki,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,yi(4,2,_i.bind(null,t,e),n)},useLayoutEffect:function(e,t){return yi(4,2,e,t)},useMemo:function(e,t){var n=li();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=li();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Pi.bind(null,Jo,e),[r.memoizedState,e]},useRef:bi,useState:gi,useDebugValue:Ci,useDeferredValue:function(e){var t=gi(e),n=t[0],r=t[1];return ki((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=gi(!1),t=e[0];return bi(e=Ai.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var r=li();return r.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},fi(r,e,t,n)},useOpaqueIdentifier:function(){if(Uo){var e=!1,t=function(e){return{$$typeof:D,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Yr++).toString(36))),Error(i(355))})),n=gi(t)[1];return 0==(2&Jo.mode)&&(Jo.flags|=516,hi(5,(function(){n("r:"+(Yr++).toString(36))}),void 0,null)),t}return gi(t="r:"+(Yr++).toString(36)),t},unstable_isNewReconciler:!1},Oi={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:ui,useRef:vi,useState:function(){return ui(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=ui(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=ui(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return ui(ci)[0]},unstable_isNewReconciler:!1},Ii={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:di,useRef:vi,useState:function(){return di(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=di(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=di(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ci)[0]},unstable_isNewReconciler:!1},Di=k.ReactCurrentOwner,Mi=!1;function ji(e,t,n,r){t.child=null===e?To(t,null,n,r):Co(t,e.child,n,r)}function Fi(e,t,n,r,a){n=n.render;var o=t.ref;return ao(t,a),r=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,r,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,ol(e,t,a))}function Bi(e,t,n,r,a,o){if(null===e){var i=n.type;return"function"!=typeof i||Hs(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Vs(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,zi(e,t,i,r,a,o))}return i=e.child,0==(a&o)&&(a=i.memoizedProps,(n=null!==(n=n.compare)?n:dr)(a,r)&&e.ref===t.ref)?ol(e,t,o):(t.flags|=1,(e=Zs(i,r)).ref=t.ref,e.return=t,t.child=e)}function zi(e,t,n,r,a,o){if(null!==e&&dr(e.memoizedProps,r)&&e.ref===t.ref){if(Mi=!1,0==(o&a))return t.lanes=e.lanes,ol(e,t,o);0!=(16384&e.flags)&&(Mi=!0)}return Gi(e,t,n,r,o)}function Ui(e,t,n){var r=t.pendingProps,a=r.children,o=null!==e?e.memoizedState:null;if("hidden"===r.mode||"unstable-defer-without-hiding"===r.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},Ss(t,n);else{if(0==(1073741824&n))return e=null!==o?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},Ss(t,e),null;t.memoizedState={baseLanes:0},Ss(t,null!==o?o.baseLanes:n)}else null!==o?(r=o.baseLanes|n,t.memoizedState=null):r=n,Ss(t,r);return ji(e,t,a,n),t.child}function $i(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function Gi(e,t,n,r,a){var o=ha(n)?ma:pa.current;return o=ga(t,o),ao(t,a),n=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,n,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,ol(e,t,a))}function qi(e,t,n,r,a){if(ha(n)){var o=!0;wa(t)}else o=!1;if(ao(t,a),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),yo(t,n,r),ko(t,n,r,a),r=!0;else if(null===e){var i=t.stateNode,l=t.memoizedProps;i.props=l;var s=i.context,c=n.contextType;"object"==typeof c&&null!==c?c=oo(c):c=ga(t,c=ha(n)?ma:pa.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==r||s!==c)&&wo(t,i,r,c),io=!1;var p=t.memoizedState;i.state=p,fo(t,r,i,a),s=t.memoizedState,l!==r||p!==s||fa.current||io?("function"==typeof u&&(ho(t,n,u,r),s=t.memoizedState),(l=io||vo(t,n,l,r,p,s,c))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=r,t.memoizedState=s),i.props=r,i.state=s,i.context=c,r=l):("function"==typeof i.componentDidMount&&(t.flags|=4),r=!1)}else{i=t.stateNode,so(e,t),l=t.memoizedProps,c=t.type===t.elementType?l:Ka(t.type,l),i.props=c,d=t.pendingProps,p=i.context,"object"==typeof(s=n.contextType)&&null!==s?s=oo(s):s=ga(t,s=ha(n)?ma:pa.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==d||p!==s)&&wo(t,i,r,s),io=!1,p=t.memoizedState,i.state=p,fo(t,r,i,a);var m=t.memoizedState;l!==d||p!==m||fa.current||io?("function"==typeof f&&(ho(t,n,f,r),m=t.memoizedState),(c=io||vo(t,n,c,r,p,m,s))?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,m,s),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,m,s)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),t.memoizedProps=r,t.memoizedState=m),i.props=r,i.state=m,i.context=s,r=c):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),r=!1)}return Hi(e,t,n,r,o,a)}function Hi(e,t,n,r,a,o){$i(e,t);var i=0!=(64&t.flags);if(!r&&!i)return a&&ka(t,n,!1),ol(e,t,o);r=t.stateNode,Di.current=t;var l=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=Co(t,e.child,null,o),t.child=Co(t,null,l,o)):ji(e,t,l,o),t.memoizedState=r.state,a&&ka(t,n,!0),t.child}function Zi(e){var t=e.stateNode;t.pendingContext?va(0,t.pendingContext,t.pendingContext!==t.context):t.context&&va(0,t.context,!1),Oo(e,t.containerInfo)}var Vi,Wi,Yi,Ki,Qi={dehydrated:null,retryLane:0};function Xi(e,t,n){var r,a=t.pendingProps,o=jo.current,i=!1;return(r=0!=(64&t.flags))||(r=(null===e||null!==e.memoizedState)&&0!=(2&o)),r?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===a.fallback||!0===a.unstable_avoidThisFallback||(o|=1),ua(jo,1&o),null===e?(void 0!==a.fallback&&qo(t),e=a.children,o=a.fallback,i?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,e):"number"==typeof a.unstable_expectedLoadTime?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,t.lanes=33554432,e):((n=Ys({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(a=tl(e,t,a.children,a.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=null===o?{baseLanes:n}:{baseLanes:o.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Qi,a):(n=el(e,t,a.children,n),t.memoizedState=null,n))}function Ji(e,t,n,r){var a=e.mode,o=e.child;return t={mode:"hidden",children:t},0==(2&a)&&null!==o?(o.childLanes=0,o.pendingProps=t):o=Ys(t,a,0,null),n=Ws(n,a,r,null),o.return=e,n.return=e,o.sibling=n,e.child=o,n}function el(e,t,n,r){var a=e.child;return e=a.sibling,n=Zs(a,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=r),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function tl(e,t,n,r,a){var o=t.mode,i=e.child;e=i.sibling;var l={mode:"hidden",children:n};return 0==(2&o)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=l,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=Zs(i,l),null!==e?r=Zs(e,r):(r=Ws(r,o,a,null)).flags|=2,r.return=t,n.return=t,n.sibling=r,t.child=n,r}function nl(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),ro(e.return,t)}function rl(e,t,n,r,a,o){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:a,lastEffect:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=a,i.lastEffect=o)}function al(e,t,n){var r=t.pendingProps,a=r.revealOrder,o=r.tail;if(ji(e,t,r.children,n),0!=(2&(r=jo.current)))r=1&r|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&nl(e,n);else if(19===e.tag)nl(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(ua(jo,r),0==(2&t.mode))t.memoizedState=null;else switch(a){case"forwards":for(n=t.child,a=null;null!==n;)null!==(e=n.alternate)&&null===Fo(e)&&(a=n),n=n.sibling;null===(n=a)?(a=t.child,t.child=null):(a=n.sibling,n.sibling=null),rl(t,!1,a,n,o,t.lastEffect);break;case"backwards":for(n=null,a=t.child,t.child=null;null!==a;){if(null!==(e=a.alternate)&&null===Fo(e)){t.child=a;break}e=a.sibling,a.sibling=n,n=a,a=e}rl(t,!0,n,null,o,t.lastEffect);break;case"together":rl(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function ol(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Ul|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Zs(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Zs(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function il(e,t){if(!Uo)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ll(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return ha(t.type)&&ba(),null;case 3:return Io(),ca(fa),ca(pa),Yo(),(r=t.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Zo(t)?t.flags|=4:r.hydrate||(t.flags|=256)),Wi(t),null;case 5:Mo(t);var o=No(Ro.current);if(n=t.type,null!==e&&null!=t.stateNode)Yi(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=128);else{if(!r){if(null===t.stateNode)throw Error(i(166));return null}if(e=No(Ao.current),Zo(t)){r=t.stateNode,n=t.type;var l=t.memoizedProps;switch(r[Qr]=t,r[Xr]=l,n){case"dialog":Ar("cancel",r),Ar("close",r);break;case"iframe":case"object":case"embed":Ar("load",r);break;case"video":case"audio":for(e=0;e<xr.length;e++)Ar(xr[e],r);break;case"source":Ar("error",r);break;case"img":case"image":case"link":Ar("error",r),Ar("load",r);break;case"details":Ar("toggle",r);break;case"input":ee(r,l),Ar("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!l.multiple},Ar("invalid",r);break;case"textarea":se(r,l),Ar("invalid",r)}for(var c in Ee(n,l),e=null,l)l.hasOwnProperty(c)&&(o=l[c],"children"===c?"string"==typeof o?r.textContent!==o&&(e=["children",o]):"number"==typeof o&&r.textContent!==""+o&&(e=["children",""+o]):s.hasOwnProperty(c)&&null!=o&&"onScroll"===c&&Ar("scroll",r));switch(n){case"input":K(r),re(r,l,!0);break;case"textarea":K(r),ue(r);break;case"select":case"option":break;default:"function"==typeof l.onClick&&(r.onclick=Br)}r=e,t.updateQueue=r,null!==r&&(t.flags|=4)}else{switch(c=9===o.nodeType?o:o.ownerDocument,e===de.html&&(e=pe(n)),e===de.html?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[Qr]=t,e[Xr]=r,Vi(e,t,!1,!1),t.stateNode=e,c=_e(n,r),n){case"dialog":Ar("cancel",e),Ar("close",e),o=r;break;case"iframe":case"object":case"embed":Ar("load",e),o=r;break;case"video":case"audio":for(o=0;o<xr.length;o++)Ar(xr[o],e);o=r;break;case"source":Ar("error",e),o=r;break;case"img":case"image":case"link":Ar("error",e),Ar("load",e),o=r;break;case"details":Ar("toggle",e),o=r;break;case"input":ee(e,r),o=J(e,r),Ar("invalid",e);break;case"option":o=oe(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=a({},r,{value:void 0}),Ar("invalid",e);break;case"textarea":se(e,r),o=le(e,r),Ar("invalid",e);break;default:o=r}Ee(n,o);var u=o;for(l in u)if(u.hasOwnProperty(l)){var d=u[l];"style"===l?ke(e,d):"dangerouslySetInnerHTML"===l?null!=(d=d?d.__html:void 0)&&he(e,d):"children"===l?"string"==typeof d?("textarea"!==n||""!==d)&&be(e,d):"number"==typeof d&&be(e,""+d):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(s.hasOwnProperty(l)?null!=d&&"onScroll"===l&&Ar("scroll",e):null!=d&&w(e,l,d,c))}switch(n){case"input":K(e),re(e,r,!1);break;case"textarea":K(e),ue(e);break;case"option":null!=r.value&&e.setAttribute("value",""+W(r.value));break;case"select":e.multiple=!!r.multiple,null!=(l=r.value)?ie(e,!!r.multiple,l,!1):null!=r.defaultValue&&ie(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Br)}$r(n,r)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Ki(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));n=No(Ro.current),No(Ao.current),Zo(t)?(r=t.stateNode,n=t.memoizedProps,r[Qr]=t,r.nodeValue!==n&&(t.flags|=4)):((r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[Qr]=t,t.stateNode=r)}return null;case 13:return ca(jo),r=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(r=null!==r,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Zo(t):n=null!==e.memoizedState,r&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&jo.current)?0===Fl&&(Fl=3):(0!==Fl&&3!==Fl||(Fl=4),null===Ol||0==(134217727&Ul)&&0==(134217727&$l)||vs(Ol,Dl))),(r||n)&&(t.flags|=4),null);case 4:return Io(),Wi(t),null===e&&Rr(t.stateNode.containerInfo),null;case 10:return no(t),null;case 19:if(ca(jo),null===(r=t.memoizedState))return null;if(l=0!=(64&t.flags),null===(c=r.rendering))if(l)il(r,!1);else{if(0!==Fl||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(c=Fo(e))){for(t.flags|=64,il(r,!1),null!==(l=c.updateQueue)&&(t.updateQueue=l,t.flags|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=n,n=t.child;null!==n;)e=r,(l=n).flags&=2,l.nextEffect=null,l.firstEffect=null,l.lastEffect=null,null===(c=l.alternate)?(l.childLanes=0,l.lanes=e,l.child=null,l.memoizedProps=null,l.memoizedState=null,l.updateQueue=null,l.dependencies=null,l.stateNode=null):(l.childLanes=c.childLanes,l.lanes=c.lanes,l.child=c.child,l.memoizedProps=c.memoizedProps,l.memoizedState=c.memoizedState,l.updateQueue=c.updateQueue,l.type=c.type,e=c.dependencies,l.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return ua(jo,1&jo.current|2),t.child}e=e.sibling}null!==r.tail&&$a()>Zl&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432)}else{if(!l)if(null!==(e=Fo(c))){if(t.flags|=64,l=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),il(r,!0),null===r.tail&&"hidden"===r.tailMode&&!c.alternate&&!Uo)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*$a()-r.renderingStartTime>Zl&&1073741824!==n&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432);r.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=r.last)?n.sibling=c:t.child=c,r.last=c)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=$a(),n.sibling=null,t=jo.current,ua(jo,l?1&t|2:1&t),n):null;case 23:case 24:return Es(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function sl(e){switch(e.tag){case 1:ha(e.type)&&ba();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Io(),ca(fa),ca(pa),Yo(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Mo(e),null;case 13:return ca(jo),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return ca(jo),null;case 4:return Io(),null;case 10:return no(e),null;case 23:case 24:return Es(),null;default:return null}}function cl(e,t){try{var n="",r=t;do{n+=Z(r),r=r.return}while(r);var a=n}catch(o){a="\nError generating stack: "+o.message+"\n"+o.stack}return{value:e,source:t,stack:a}}function ul(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Vi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Wi=function(){},Yi=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,No(Ao.current);var i,l=null;switch(n){case"input":o=J(e,o),r=J(e,r),l=[];break;case"option":o=oe(e,o),r=oe(e,r),l=[];break;case"select":o=a({},o,{value:void 0}),r=a({},r,{value:void 0}),l=[];break;case"textarea":o=le(e,o),r=le(e,r),l=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Br)}for(d in Ee(n,r),n=null,o)if(!r.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(i in c)c.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(s.hasOwnProperty(d)?l||(l=[]):(l=l||[]).push(d,null));for(d in r){var u=r[d];if(c=null!=o?o[d]:void 0,r.hasOwnProperty(d)&&u!==c&&(null!=u||null!=c))if("style"===d)if(c){for(i in c)!c.hasOwnProperty(i)||u&&u.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in u)u.hasOwnProperty(i)&&c[i]!==u[i]&&(n||(n={}),n[i]=u[i])}else n||(l||(l=[]),l.push(d,n)),n=u;else"dangerouslySetInnerHTML"===d?(u=u?u.__html:void 0,c=c?c.__html:void 0,null!=u&&c!==u&&(l=l||[]).push(d,u)):"children"===d?"string"!=typeof u&&"number"!=typeof u||(l=l||[]).push(d,""+u):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(s.hasOwnProperty(d)?(null!=u&&"onScroll"===d&&Ar("scroll",e),l||c===u||(l=[])):"object"==typeof u&&null!==u&&u.$$typeof===D?u.toString():(l=l||[]).push(d,u))}n&&(l=l||[]).push("style",n);var d=l;(t.updateQueue=d)&&(t.flags|=4)}},Ki=function(e,t,n,r){n!==r&&(t.flags|=4)};var dl="function"==typeof WeakMap?WeakMap:Map;function pl(e,t,n){(n=co(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Kl||(Kl=!0,Ql=r),ul(0,t)},n}function fl(e,t,n){(n=co(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var a=t.value;n.payload=function(){return ul(0,t),r(a)}}var o=e.stateNode;return null!==o&&"function"==typeof o.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Xl?Xl=new Set([this]):Xl.add(this),ul(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var ml="function"==typeof WeakSet?WeakSet:Set;function gl(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){zs(e,n)}else t.current=null}function hl(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ka(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Zr(t.stateNode.containerInfo))}throw Error(i(163))}function bl(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var a=e;r=a.next,0!=(4&(a=a.tag))&&0!=(1&a)&&(js(n,e),Ms(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ka(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&mo(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}mo(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&$r(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&kt(n)))))}throw Error(i(163))}function vl(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var a=n.memoizedProps.style;a=null!=a&&a.hasOwnProperty("display")?a.display:null,r.style.display=we("display",a)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function yl(e,t){if(Ea&&"function"==typeof Ea.onCommitFiberUnmount)try{Ea.onCommitFiberUnmount(Sa,t)}catch(o){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,a=r.destroy;if(r=r.tag,void 0!==a)if(0!=(4&r))js(t,n);else{r=t;try{a()}catch(o){zs(r,o)}}n=n.next}while(n!==e)}break;case 1:if(gl(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(o){zs(t,o)}break;case 5:gl(t);break;case 4:xl(e,t)}}function wl(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function kl(e){return 5===e.tag||3===e.tag||4===e.tag}function Sl(e){e:{for(var t=e.return;null!==t;){if(kl(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(i(161))}16&n.flags&&(be(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||kl(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?El(e,n,t):_l(e,n,t)}function El(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Br));else if(4!==r&&null!==(e=e.child))for(El(e,t,n),e=e.sibling;null!==e;)El(e,t,n),e=e.sibling}function _l(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(_l(e,t,n),e=e.sibling;null!==e;)_l(e,t,n),e=e.sibling}function xl(e,t){for(var n,r,a=t,o=!1;;){if(!o){o=a.return;e:for(;;){if(null===o)throw Error(i(160));switch(n=o.stateNode,o.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}o=o.return}o=!0}if(5===a.tag||6===a.tag){e:for(var l=e,s=a,c=s;;)if(yl(l,c),null!==c.child&&4!==c.tag)c.child.return=c,c=c.child;else{if(c===s)break e;for(;null===c.sibling;){if(null===c.return||c.return===s)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}r?(l=n,s=a.stateNode,8===l.nodeType?l.parentNode.removeChild(s):l.removeChild(s)):n.removeChild(a.stateNode)}else if(4===a.tag){if(null!==a.child){n=a.stateNode.containerInfo,r=!0,a.child.return=a,a=a.child;continue}}else if(yl(e,a),null!==a.child){a.child.return=a,a=a.child;continue}if(a===t)break;for(;null===a.sibling;){if(null===a.return||a.return===t)return;4===(a=a.return).tag&&(o=!1)}a.sibling.return=a.return,a=a.sibling}}function Cl(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var a=null!==e?e.memoizedProps:r;e=t.type;var o=t.updateQueue;if(t.updateQueue=null,null!==o){for(n[Xr]=r,"input"===e&&"radio"===r.type&&null!=r.name&&te(n,r),_e(e,a),t=_e(e,r),a=0;a<o.length;a+=2){var l=o[a],s=o[a+1];"style"===l?ke(n,s):"dangerouslySetInnerHTML"===l?he(n,s):"children"===l?be(n,s):w(n,l,s,t)}switch(e){case"input":ne(n,r);break;case"textarea":ce(n,r);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(o=r.value)?ie(n,!!r.multiple,o,!1):e!==!!r.multiple&&(null!=r.defaultValue?ie(n,!!r.multiple,r.defaultValue,!0):ie(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,kt(n.containerInfo)));case 13:return null!==t.memoizedState&&(Hl=$a(),vl(t.child,!0)),void Tl(t);case 19:return void Tl(t);case 23:case 24:return void vl(t,null!==t.memoizedState)}throw Error(i(163))}function Tl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new ml),t.forEach((function(t){var r=$s.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function Ll(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var Al=Math.ceil,Pl=k.ReactCurrentDispatcher,Rl=k.ReactCurrentOwner,Nl=0,Ol=null,Il=null,Dl=0,Ml=0,jl=sa(0),Fl=0,Bl=null,zl=0,Ul=0,$l=0,Gl=0,ql=null,Hl=0,Zl=1/0;function Vl(){Zl=$a()+500}var Wl,Yl=null,Kl=!1,Ql=null,Xl=null,Jl=!1,es=null,ts=90,ns=[],rs=[],as=null,os=0,is=null,ls=-1,ss=0,cs=0,us=null,ds=!1;function ps(){return 0!=(48&Nl)?$a():-1!==ls?ls:ls=$a()}function fs(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===Ga()?1:2;if(0===ss&&(ss=zl),0!==Ya.transition){0!==cs&&(cs=null!==ql?ql.pendingLanes:0),e=ss;var t=4186112&~cs;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=Ga(),0!=(4&Nl)&&98===e?e=Bt(12,ss):e=Bt(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ss),e}function ms(e,t,n){if(50<os)throw os=0,is=null,Error(i(185));if(null===(e=gs(e,t)))return null;$t(e,t,n),e===Ol&&($l|=t,4===Fl&&vs(e,Dl));var r=Ga();1===t?0!=(8&Nl)&&0==(48&Nl)?ys(e):(hs(e,n),0===Nl&&(Vl(),Va())):(0==(4&Nl)||98!==r&&99!==r||(null===as?as=new Set([e]):as.add(e)),hs(e,n)),ql=e}function gs(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function hs(e,t){for(var n=e.callbackNode,r=e.suspendedLanes,a=e.pingedLanes,o=e.expirationTimes,l=e.pendingLanes;0<l;){var s=31-Gt(l),c=1<<s,u=o[s];if(-1===u){if(0==(c&r)||0!=(c&a)){u=t,Mt(c);var d=Dt;o[s]=10<=d?u+250:6<=d?u+5e3:-1}}else u<=t&&(e.expiredLanes|=c);l&=~c}if(r=jt(e,e===Ol?Dl:0),t=Dt,0===r)null!==n&&(n!==Ma&&Ca(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Ma&&Ca(n)}15===t?(n=ys.bind(null,e),null===Fa?(Fa=[n],Ba=xa(Ra,Wa)):Fa.push(n),n=Ma):14===t?n=Za(99,ys.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Za(n,bs.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function bs(e){if(ls=-1,cs=ss=0,0!=(48&Nl))throw Error(i(327));var t=e.callbackNode;if(Ds()&&e.callbackNode!==t)return null;var n=jt(e,e===Ol?Dl:0);if(0===n)return null;var r=n,a=Nl;Nl|=16;var o=Cs();for(Ol===e&&Dl===r||(Vl(),_s(e,r));;)try{As();break}catch(s){xs(e,s)}if(to(),Pl.current=o,Nl=a,null!==Il?r=0:(Ol=null,Dl=0,r=Fl),0!=(zl&$l))_s(e,0);else if(0!==r){if(2===r&&(Nl|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(n=Ft(e))&&(r=Ts(e,n))),1===r)throw t=Bl,_s(e,0),vs(e,n),hs(e,$a()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,r){case 0:case 1:throw Error(i(345));case 2:case 5:Ns(e);break;case 3:if(vs(e,n),(62914560&n)===n&&10<(r=Hl+500-$a())){if(0!==jt(e,0))break;if(((a=e.suspendedLanes)&n)!==n){ps(),e.pingedLanes|=e.suspendedLanes&a;break}e.timeoutHandle=qr(Ns.bind(null,e),r);break}Ns(e);break;case 4:if(vs(e,n),(4186112&n)===n)break;for(r=e.eventTimes,a=-1;0<n;){var l=31-Gt(n);o=1<<l,(l=r[l])>a&&(a=l),n&=~o}if(n=a,10<(n=(120>(n=$a()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Al(n/1960))-n)){e.timeoutHandle=qr(Ns.bind(null,e),n);break}Ns(e);break;default:throw Error(i(329))}}return hs(e,$a()),e.callbackNode===t?bs.bind(null,e):null}function vs(e,t){for(t&=~Gl,t&=~$l,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-Gt(t),r=1<<n;e[n]=-1,t&=~r}}function ys(e){if(0!=(48&Nl))throw Error(i(327));if(Ds(),e===Ol&&0!=(e.expiredLanes&Dl)){var t=Dl,n=Ts(e,t);0!=(zl&$l)&&(n=Ts(e,t=jt(e,t)))}else n=Ts(e,t=jt(e,0));if(0!==e.tag&&2===n&&(Nl|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(t=Ft(e))&&(n=Ts(e,t))),1===n)throw n=Bl,_s(e,0),vs(e,t),hs(e,$a()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,Ns(e),hs(e,$a()),null}function ws(e,t){var n=Nl;Nl|=1;try{return e(t)}finally{0===(Nl=n)&&(Vl(),Va())}}function ks(e,t){var n=Nl;Nl&=-2,Nl|=8;try{return e(t)}finally{0===(Nl=n)&&(Vl(),Va())}}function Ss(e,t){ua(jl,Ml),Ml|=t,zl|=t}function Es(){Ml=jl.current,ca(jl)}function _s(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,Hr(n)),null!==Il)for(n=Il.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&ba();break;case 3:Io(),ca(fa),ca(pa),Yo();break;case 5:Mo(r);break;case 4:Io();break;case 13:case 19:ca(jo);break;case 10:no(r);break;case 23:case 24:Es()}n=n.return}Ol=e,Il=Zs(e.current,null),Dl=Ml=zl=t,Fl=0,Bl=null,Gl=$l=Ul=0}function xs(e,t){for(;;){var n=Il;try{if(to(),Ko.current=Ri,ni){for(var r=Jo.memoizedState;null!==r;){var a=r.queue;null!==a&&(a.pending=null),r=r.next}ni=!1}if(Xo=0,ti=ei=Jo=null,ri=!1,Rl.current=null,null===n||null===n.return){Fl=1,Bl=t,Il=null;break}e:{var o=e,i=n.return,l=n,s=t;if(t=Dl,l.flags|=2048,l.firstEffect=l.lastEffect=null,null!==s&&"object"==typeof s&&"function"==typeof s.then){var c=s;if(0==(2&l.mode)){var u=l.alternate;u?(l.updateQueue=u.updateQueue,l.memoizedState=u.memoizedState,l.lanes=u.lanes):(l.updateQueue=null,l.memoizedState=null)}var d=0!=(1&jo.current),p=i;do{var f;if(f=13===p.tag){var m=p.memoizedState;if(null!==m)f=null!==m.dehydrated;else{var g=p.memoizedProps;f=void 0!==g.fallback&&(!0!==g.unstable_avoidThisFallback||!d)}}if(f){var h=p.updateQueue;if(null===h){var b=new Set;b.add(c),p.updateQueue=b}else h.add(c);if(0==(2&p.mode)){if(p.flags|=64,l.flags|=16384,l.flags&=-2981,1===l.tag)if(null===l.alternate)l.tag=17;else{var v=co(-1,1);v.tag=2,uo(l,v)}l.lanes|=1;break e}s=void 0,l=t;var y=o.pingCache;if(null===y?(y=o.pingCache=new dl,s=new Set,y.set(c,s)):void 0===(s=y.get(c))&&(s=new Set,y.set(c,s)),!s.has(l)){s.add(l);var w=Us.bind(null,o,c,l);c.then(w,w)}p.flags|=4096,p.lanes=t;break e}p=p.return}while(null!==p);s=Error((V(l.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Fl&&(Fl=2),s=cl(s,l),p=i;do{switch(p.tag){case 3:o=s,p.flags|=4096,t&=-t,p.lanes|=t,po(p,pl(0,o,t));break e;case 1:o=s;var k=p.type,S=p.stateNode;if(0==(64&p.flags)&&("function"==typeof k.getDerivedStateFromError||null!==S&&"function"==typeof S.componentDidCatch&&(null===Xl||!Xl.has(S)))){p.flags|=4096,t&=-t,p.lanes|=t,po(p,fl(p,o,t));break e}}p=p.return}while(null!==p)}Rs(n)}catch(E){t=E,Il===n&&null!==n&&(Il=n=n.return);continue}break}}function Cs(){var e=Pl.current;return Pl.current=Ri,null===e?Ri:e}function Ts(e,t){var n=Nl;Nl|=16;var r=Cs();for(Ol===e&&Dl===t||_s(e,t);;)try{Ls();break}catch(a){xs(e,a)}if(to(),Nl=n,Pl.current=r,null!==Il)throw Error(i(261));return Ol=null,Dl=0,Fl}function Ls(){for(;null!==Il;)Ps(Il)}function As(){for(;null!==Il&&!Ta();)Ps(Il)}function Ps(e){var t=Wl(e.alternate,e,Ml);e.memoizedProps=e.pendingProps,null===t?Rs(e):Il=t,Rl.current=null}function Rs(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ll(n,t,Ml)))return void(Il=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&Ml)||0==(4&n.mode)){for(var r=0,a=n.child;null!==a;)r|=a.lanes|a.childLanes,a=a.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=sl(t)))return n.flags&=2047,void(Il=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Il=t);Il=t=e}while(null!==t);0===Fl&&(Fl=5)}function Ns(e){var t=Ga();return Ha(99,Os.bind(null,e,t)),null}function Os(e,t){do{Ds()}while(null!==es);if(0!=(48&Nl))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var r=n.lanes|n.childLanes,a=r,o=e.pendingLanes&~a;e.pendingLanes=a,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=a,e.mutableReadLanes&=a,e.entangledLanes&=a,a=e.entanglements;for(var l=e.eventTimes,s=e.expirationTimes;0<o;){var c=31-Gt(o),u=1<<c;a[c]=0,l[c]=-1,s[c]=-1,o&=~u}if(null!==as&&0==(24&r)&&as.has(e)&&as.delete(e),e===Ol&&(Il=Ol=null,Dl=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,r=n.firstEffect):r=n:r=n.firstEffect,null!==r){if(a=Nl,Nl|=32,Rl.current=null,zr=Wt,hr(l=gr())){if("selectionStart"in l)s={start:l.selectionStart,end:l.selectionEnd};else e:if(s=(s=l.ownerDocument)&&s.defaultView||window,(u=s.getSelection&&s.getSelection())&&0!==u.rangeCount){s=u.anchorNode,o=u.anchorOffset,c=u.focusNode,u=u.focusOffset;try{s.nodeType,c.nodeType}catch(C){s=null;break e}var d=0,p=-1,f=-1,m=0,g=0,h=l,b=null;t:for(;;){for(var v;h!==s||0!==o&&3!==h.nodeType||(p=d+o),h!==c||0!==u&&3!==h.nodeType||(f=d+u),3===h.nodeType&&(d+=h.nodeValue.length),null!==(v=h.firstChild);)b=h,h=v;for(;;){if(h===l)break t;if(b===s&&++m===o&&(p=d),b===c&&++g===u&&(f=d),null!==(v=h.nextSibling))break;b=(h=b).parentNode}h=v}s=-1===p||-1===f?null:{start:p,end:f}}else s=null;s=s||{start:0,end:0}}else s=null;Ur={focusedElem:l,selectionRange:s},Wt=!1,us=null,ds=!1,Yl=r;do{try{Is()}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);us=null,Yl=r;do{try{for(l=e;null!==Yl;){var y=Yl.flags;if(16&y&&be(Yl.stateNode,""),128&y){var w=Yl.alternate;if(null!==w){var k=w.ref;null!==k&&("function"==typeof k?k(null):k.current=null)}}switch(1038&y){case 2:Sl(Yl),Yl.flags&=-3;break;case 6:Sl(Yl),Yl.flags&=-3,Cl(Yl.alternate,Yl);break;case 1024:Yl.flags&=-1025;break;case 1028:Yl.flags&=-1025,Cl(Yl.alternate,Yl);break;case 4:Cl(Yl.alternate,Yl);break;case 8:xl(l,s=Yl);var S=s.alternate;wl(s),null!==S&&wl(S)}Yl=Yl.nextEffect}}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);if(k=Ur,w=gr(),y=k.focusedElem,l=k.selectionRange,w!==y&&y&&y.ownerDocument&&mr(y.ownerDocument.documentElement,y)){null!==l&&hr(y)&&(w=l.start,void 0===(k=l.end)&&(k=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(k,y.value.length)):(k=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(k=k.getSelection(),s=y.textContent.length,S=Math.min(l.start,s),l=void 0===l.end?S:Math.min(l.end,s),!k.extend&&S>l&&(s=l,l=S,S=s),s=fr(y,S),o=fr(y,l),s&&o&&(1!==k.rangeCount||k.anchorNode!==s.node||k.anchorOffset!==s.offset||k.focusNode!==o.node||k.focusOffset!==o.offset)&&((w=w.createRange()).setStart(s.node,s.offset),k.removeAllRanges(),S>l?(k.addRange(w),k.extend(o.node,o.offset)):(w.setEnd(o.node,o.offset),k.addRange(w))))),w=[];for(k=y;k=k.parentNode;)1===k.nodeType&&w.push({element:k,left:k.scrollLeft,top:k.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(k=w[y]).element.scrollLeft=k.left,k.element.scrollTop=k.top}Wt=!!zr,Ur=zr=null,e.current=n,Yl=r;do{try{for(y=e;null!==Yl;){var E=Yl.flags;if(36&E&&bl(y,Yl.alternate,Yl),128&E){w=void 0;var _=Yl.ref;if(null!==_){var x=Yl.stateNode;Yl.tag,w=x,"function"==typeof _?_(w):_.current=w}}Yl=Yl.nextEffect}}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);Yl=null,ja(),Nl=a}else e.current=n;if(Jl)Jl=!1,es=e,ts=t;else for(Yl=r;null!==Yl;)t=Yl.nextEffect,Yl.nextEffect=null,8&Yl.flags&&((E=Yl).sibling=null,E.stateNode=null),Yl=t;if(0===(r=e.pendingLanes)&&(Xl=null),1===r?e===is?os++:(os=0,is=e):os=0,n=n.stateNode,Ea&&"function"==typeof Ea.onCommitFiberRoot)try{Ea.onCommitFiberRoot(Sa,n,void 0,64==(64&n.current.flags))}catch(C){}if(hs(e,$a()),Kl)throw Kl=!1,e=Ql,Ql=null,e;return 0!=(8&Nl)||Va(),null}function Is(){for(;null!==Yl;){var e=Yl.alternate;ds||null===us||(0!=(8&Yl.flags)?Je(Yl,us)&&(ds=!0):13===Yl.tag&&Ll(e,Yl)&&Je(Yl,us)&&(ds=!0));var t=Yl.flags;0!=(256&t)&&hl(e,Yl),0==(512&t)||Jl||(Jl=!0,Za(97,(function(){return Ds(),null}))),Yl=Yl.nextEffect}}function Ds(){if(90!==ts){var e=97<ts?97:ts;return ts=90,Ha(e,Fs)}return!1}function Ms(e,t){ns.push(t,e),Jl||(Jl=!0,Za(97,(function(){return Ds(),null})))}function js(e,t){rs.push(t,e),Jl||(Jl=!0,Za(97,(function(){return Ds(),null})))}function Fs(){if(null===es)return!1;var e=es;if(es=null,0!=(48&Nl))throw Error(i(331));var t=Nl;Nl|=32;var n=rs;rs=[];for(var r=0;r<n.length;r+=2){var a=n[r],o=n[r+1],l=a.destroy;if(a.destroy=void 0,"function"==typeof l)try{l()}catch(c){if(null===o)throw Error(i(330));zs(o,c)}}for(n=ns,ns=[],r=0;r<n.length;r+=2){a=n[r],o=n[r+1];try{var s=a.create;a.destroy=s()}catch(c){if(null===o)throw Error(i(330));zs(o,c)}}for(s=e.current.firstEffect;null!==s;)e=s.nextEffect,s.nextEffect=null,8&s.flags&&(s.sibling=null,s.stateNode=null),s=e;return Nl=t,Va(),!0}function Bs(e,t,n){uo(e,t=pl(0,t=cl(n,t),1)),t=ps(),null!==(e=gs(e,1))&&($t(e,1,t),hs(e,t))}function zs(e,t){if(3===e.tag)Bs(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Bs(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Xl||!Xl.has(r))){var a=fl(n,e=cl(t,e),1);if(uo(n,a),a=ps(),null!==(n=gs(n,1)))$t(n,1,a),hs(n,a);else if("function"==typeof r.componentDidCatch&&(null===Xl||!Xl.has(r)))try{r.componentDidCatch(t,e)}catch(o){}break}}n=n.return}}function Us(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=ps(),e.pingedLanes|=e.suspendedLanes&n,Ol===e&&(Dl&n)===n&&(4===Fl||3===Fl&&(62914560&Dl)===Dl&&500>$a()-Hl?_s(e,0):Gl|=n),hs(e,t)}function $s(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===Ga()?1:2:(0===ss&&(ss=zl),0===(t=zt(62914560&~ss))&&(t=4194304))),n=ps(),null!==(e=gs(e,t))&&($t(e,t,n),hs(e,n))}function Gs(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function qs(e,t,n,r){return new Gs(e,t,n,r)}function Hs(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Zs(e,t){var n=e.alternate;return null===n?((n=qs(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Vs(e,t,n,r,a,o){var l=2;if(r=e,"function"==typeof e)Hs(e)&&(l=1);else if("string"==typeof e)l=5;else e:switch(e){case _:return Ws(n.children,a,o,t);case M:l=8,a|=16;break;case x:l=8,a|=1;break;case C:return(e=qs(12,n,t,8|a)).elementType=C,e.type=C,e.lanes=o,e;case P:return(e=qs(13,n,t,a)).type=P,e.elementType=P,e.lanes=o,e;case R:return(e=qs(19,n,t,a)).elementType=R,e.lanes=o,e;case j:return Ys(n,a,o,t);case F:return(e=qs(24,n,t,a)).elementType=F,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:l=10;break e;case L:l=9;break e;case A:l=11;break e;case N:l=14;break e;case O:l=16,r=null;break e;case I:l=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=qs(l,n,t,a)).elementType=e,t.type=r,t.lanes=o,t}function Ws(e,t,n,r){return(e=qs(7,e,r,t)).lanes=n,e}function Ys(e,t,n,r){return(e=qs(23,e,r,t)).elementType=j,e.lanes=n,e}function Ks(e,t,n){return(e=qs(6,e,null,t)).lanes=n,e}function Qs(e,t,n){return(t=qs(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Xs(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Ut(0),this.expirationTimes=Ut(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ut(0),this.mutableSourceEagerHydrationData=null}function Js(e,t,n,r){var a=t.current,o=ps(),l=fs(a);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var s=n;do{switch(s.tag){case 3:s=s.stateNode.context;break t;case 1:if(ha(s.type)){s=s.stateNode.__reactInternalMemoizedMergedChildContext;break t}}s=s.return}while(null!==s);throw Error(i(171))}if(1===n.tag){var c=n.type;if(ha(c)){n=ya(n,c,s);break e}}n=s}else n=da;return null===t.context?t.context=n:t.pendingContext=n,(t=co(o,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),uo(a,t),ms(a,l,o),l}function ec(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function tc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function nc(e,t){tc(e,t),(e=e.alternate)&&tc(e,t)}function rc(e,t,n){var r=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Xs(e,t,null!=n&&!0===n.hydrate),t=qs(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,lo(t),e[Jr]=n.current,Rr(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var a=(t=r[e])._getVersion;a=a(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,a]:n.mutableSourceEagerHydrationData.push(t,a)}this._internalRoot=n}function ac(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function oc(e,t,n,r,a){var o=n._reactRootContainer;if(o){var i=o._internalRoot;if("function"==typeof a){var l=a;a=function(){var e=ec(i);l.call(e)}}Js(t,i,e,a)}else{if(o=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new rc(e,0,t?{hydrate:!0}:void 0)}(n,r),i=o._internalRoot,"function"==typeof a){var s=a;a=function(){var e=ec(i);s.call(e)}}ks((function(){Js(t,i,e,a)}))}return ec(i)}function ic(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!ac(t))throw Error(i(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:E,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)}Wl=function(e,t,n){var r=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||fa.current)Mi=!0;else{if(0==(n&r)){switch(Mi=!1,t.tag){case 3:Zi(t),Vo();break;case 5:Do(t);break;case 1:ha(t.type)&&wa(t);break;case 4:Oo(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value;var a=t.type._context;ua(Qa,a._currentValue),a._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Xi(e,t,n):(ua(jo,1&jo.current),null!==(t=ol(e,t,n))?t.sibling:null);ua(jo,1&jo.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(64&e.flags)){if(r)return al(e,t,n);t.flags|=64}if(null!==(a=t.memoizedState)&&(a.rendering=null,a.tail=null,a.lastEffect=null),ua(jo,jo.current),r)break;return null;case 23:case 24:return t.lanes=0,Ui(e,t,n)}return ol(e,t,n)}Mi=0!=(16384&e.flags)}else Mi=!1;switch(t.lanes=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=ga(t,pa.current),ao(t,n),a=ii(null,t,r,e,a,n),t.flags|=1,"object"==typeof a&&null!==a&&"function"==typeof a.render&&void 0===a.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,ha(r)){var o=!0;wa(t)}else o=!1;t.memoizedState=null!==a.state&&void 0!==a.state?a.state:null,lo(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&ho(t,r,l,e),a.updater=bo,t.stateNode=a,a._reactInternals=t,ko(t,r,e,n),t=Hi(null,t,r,!0,o,n)}else t.tag=0,ji(null,t,a,n),t=t.child;return t;case 16:a=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=(o=a._init)(a._payload),t.type=a,o=t.tag=function(e){if("function"==typeof e)return Hs(e)?1:0;if(null!=e){if((e=e.$$typeof)===A)return 11;if(e===N)return 14}return 2}(a),e=Ka(a,e),o){case 0:t=Gi(null,t,a,e,n);break e;case 1:t=qi(null,t,a,e,n);break e;case 11:t=Fi(null,t,a,e,n);break e;case 14:t=Bi(null,t,a,Ka(a.type,e),r,n);break e}throw Error(i(306,a,""))}return t;case 0:return r=t.type,a=t.pendingProps,Gi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 1:return r=t.type,a=t.pendingProps,qi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 3:if(Zi(t),r=t.updateQueue,null===e||null===r)throw Error(i(282));if(r=t.pendingProps,a=null!==(a=t.memoizedState)?a.element:null,so(e,t),fo(t,r,null,n),(r=t.memoizedState.element)===a)Vo(),t=ol(e,t,n);else{if((o=(a=t.stateNode).hydrate)&&(zo=Vr(t.stateNode.containerInfo.firstChild),Bo=t,o=Uo=!0),o){if(null!=(e=a.mutableSourceEagerHydrationData))for(a=0;a<e.length;a+=2)(o=e[a])._workInProgressVersionPrimary=e[a+1],Wo.push(o);for(n=To(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else ji(e,t,r,n),Vo();t=t.child}return t;case 5:return Do(t),null===e&&qo(t),r=t.type,a=t.pendingProps,o=null!==e?e.memoizedProps:null,l=a.children,Gr(r,a)?l=null:null!==o&&Gr(r,o)&&(t.flags|=16),$i(e,t),ji(e,t,l,n),t.child;case 6:return null===e&&qo(t),null;case 13:return Xi(e,t,n);case 4:return Oo(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Co(t,null,r,n):ji(e,t,r,n),t.child;case 11:return r=t.type,a=t.pendingProps,Fi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 7:return ji(e,t,t.pendingProps,n),t.child;case 8:case 12:return ji(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,a=t.pendingProps,l=t.memoizedProps,o=a.value;var s=t.type._context;if(ua(Qa,s._currentValue),s._currentValue=o,null!==l)if(s=l.value,0===(o=cr(s,o)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(s,o):1073741823))){if(l.children===a.children&&!fa.current){t=ol(e,t,n);break e}}else for(null!==(s=t.child)&&(s.return=t);null!==s;){var c=s.dependencies;if(null!==c){l=s.child;for(var u=c.firstContext;null!==u;){if(u.context===r&&0!=(u.observedBits&o)){1===s.tag&&((u=co(-1,n&-n)).tag=2,uo(s,u)),s.lanes|=n,null!==(u=s.alternate)&&(u.lanes|=n),ro(s.return,n),c.lanes|=n;break}u=u.next}}else l=10===s.tag&&s.type===t.type?null:s.child;if(null!==l)l.return=s;else for(l=s;null!==l;){if(l===t){l=null;break}if(null!==(s=l.sibling)){s.return=l.return,l=s;break}l=l.return}s=l}ji(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,r=(o=t.pendingProps).children,ao(t,n),r=r(a=oo(a,o.unstable_observedBits)),t.flags|=1,ji(e,t,r,n),t.child;case 14:return o=Ka(a=t.type,t.pendingProps),Bi(e,t,a,o=Ka(a.type,o),r,n);case 15:return zi(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,a=t.pendingProps,a=t.elementType===r?a:Ka(r,a),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,ha(r)?(e=!0,wa(t)):e=!1,ao(t,n),yo(t,r,a),ko(t,r,a,n),Hi(null,t,r,!0,e,n);case 19:return al(e,t,n);case 23:case 24:return Ui(e,t,n)}throw Error(i(156,t.tag))},rc.prototype.render=function(e){Js(e,this._internalRoot,null,null)},rc.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;Js(null,e,null,(function(){t[Jr]=null}))},et=function(e){13===e.tag&&(ms(e,4,ps()),nc(e,4))},tt=function(e){13===e.tag&&(ms(e,67108864,ps()),nc(e,67108864))},nt=function(e){if(13===e.tag){var t=ps(),n=fs(e);ms(e,n,t),nc(e,n)}},rt=function(e,t){return t()},Ce=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=aa(r);if(!a)throw Error(i(90));Q(r),ne(r,a)}}}break;case"textarea":ce(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Ne=ws,Oe=function(e,t,n,r,a){var o=Nl;Nl|=4;try{return Ha(98,e.bind(null,t,n,r,a))}finally{0===(Nl=o)&&(Vl(),Va())}},Ie=function(){0==(49&Nl)&&(function(){if(null!==as){var e=as;as=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,hs(e,$a())}))}Va()}(),Ds())},De=function(e,t){var n=Nl;Nl|=2;try{return e(t)}finally{0===(Nl=n)&&(Vl(),Va())}};var lc={Events:[na,ra,aa,Pe,Re,Ds,{current:!1}]},sc={findFiberByHostInstance:ta,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},cc={bundleType:sc.bundleType,version:sc.version,rendererPackageName:sc.rendererPackageName,rendererConfig:sc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Xe(e))?null:e.stateNode},findFiberByHostInstance:sc.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var uc=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!uc.isDisabled&&uc.supportsFiber)try{Sa=uc.inject(cc),Ea=uc}catch(ge){}}t.hydrate=function(e,t,n){if(!ac(t))throw Error(i(200));return oc(null,e,t,!0,n)}},3935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(4448)},9590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,c,u;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(!o(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;for(u=e.entries();!(s=u.next()).done;)if(!o(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((l=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!=s--;)if(!Object.prototype.hasOwnProperty.call(i,c[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!=s--;)if(("_owner"!==c[s]&&"__v"!==c[s]&&"__o"!==c[s]||!e.$$typeof)&&!o(e[c[s]],i[c[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>H,ql:()=>J});var r=n(7294),a=n(5697),o=n.n(a),i=n(9590),l=n.n(i),s=n(1143),c=n.n(s),u=n(6774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function g(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(h).map((function(e){return h[e]})),k={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},S=Object.keys(k).reduce((function(e,t){return e[k[t]]=t,e}),{}),E=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=E(e,h.TITLE),n=E(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=E(e,"defaultTitle");return t||r||void 0},x=function(e){return E(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a<r.length;a+=1){var o=r[a].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},L=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var a={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var l=o[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),a[n]||(a[n]={}),!r[n][c]&&(a[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(a),i=0;i<o.length;i+=1){var l=o[i],s=p({},r[l],a[l]);r[l]=s}return e}),[]).reverse()},A=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},R=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},O=[h.NOSCRIPT,h.SCRIPT,h.STYLE],I=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},D=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},M=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[k[n]||n]=e[n],t}),t)},j=function(e,t){return t.map((function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach((function(e){var n=k[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),r.createElement(e,o)}))},F=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=M(n,a),[r.createElement(h.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=D(n),o=P(t);return a?"<"+e+' data-rh="true" '+a+">"+I(o,r)+"</"+e+">":"<"+e+' data-rh="true">'+I(o,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return M(t)},toString:function(){return D(t)}};default:return{toComponent:function(){return j(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+I(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===O.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=R(e.metaTags,y),o=R(t,b),i=R(n,v);return{priorityMethods:{toComponent:function(){return[].concat(j(h.META,a.priority),j(h.LINK,o.priority),j(h.SCRIPT,i.priority))},toString:function(){return F(h.META,a.priority,r)+" "+F(h.LINK,o.priority,r)+" "+F(h.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);f=m.priorityMethods,u=m.linkTags,d=m.metaTags,p=m.scriptTags}return{priority:f,base:F(h.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",a,r),link:F(h.LINK,u,r),meta:F(h.META,d,r),noscript:F(h.NOSCRIPT,o,r),script:F(h.SCRIPT,p,r),style:F(h.STYLE,i,r),title:F(h.TITLE,{title:s,titleAttributes:c},r)}},z=[],U=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},$=r.createContext({}),G=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),q="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new U(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement($.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=q,H.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var Z=function(e,t){var n,r=document.head||document.querySelector(h.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,r.isEqualNode(e)}))?o.splice(n,1):i.push(r)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:o,newTags:i}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],c=t[s]||"";n.getAttribute(s)!==c&&n.setAttribute(s,c),-1===a.indexOf(s)&&a.push(s);var u=o.indexOf(s);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},W=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;V(h.BODY,e.bodyAttributes),V(h.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),V(h.TITLE,t)}(u,d);var p={baseTag:Z(h.BASE,n),linkTags:Z(h.LINK,a),metaTags:Z(h.META,o),noscriptTags:Z(h.NOSCRIPT,i),scriptTags:Z(h.SCRIPT,s),styleTags:Z(h.STYLE,c)},f={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),l(e,f,m)},Y=null,K=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,a=null,o=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:E(e,"defer"),encode:E(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:L(h.LINK,["rel","href"],e),metaTags:L(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:L(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:x(e),scriptTags:L(h.SCRIPT,["src","innerHTML"],e),styleTags:L(h.STYLE,["cssText"],e),title:_(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:A(e,"prioritizeSeoTags")});H.canUseDOM?(t=o,Y&&cancelAnimationFrame(Y),t.defer?Y=requestAnimationFrame((function(){W(t,(function(){Y=null}))})):(W(t),Y=null)):B&&(a=B(o)),r(a)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);K.propTypes={context:G.isRequired},K.displayName="HelmetDispatcher";var Q=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case h.TITLE:return p({},a,((t={})[r.type]=i,t.titleAttributes=p({},o),t));case h.BODY:return p({},a,{bodyAttributes:p({},o)});case h.HTML:return p({},a,{htmlAttributes:p({},o)});default:return p({},a,((n={})[r.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,o=r.children,i=g(r,Q),l=Object.keys(i).reduce((function(e,t){return e[S[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,o),s){case h.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:l,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=g(e,X),a=p({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof U||(o=new U(o.context,o.instances)),o?r.createElement(K,p({},a,{context:o.value,helmetData:void 0})):r.createElement($.Consumer,null,(function(e){return r.createElement(K,p({},a,{context:e}))}))},t}(r.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},9921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,g=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case o:case l:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case h:case g:case s:return e;default:return t}}case a:return t}}}function S(e){return k(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=p,t.Fragment=o,t.Lazy=h,t.Memo=g,t.Portal=a,t.Profiler=l,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return S(e)||k(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===c},t.isContextProvider=function(e){return k(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===p},t.isFragment=function(e){return k(e)===o},t.isLazy=function(e){return k(e)===h},t.isMemo=function(e){return k(e)===g},t.isPortal=function(e){return k(e)===a},t.isProfiler=function(e){return k(e)===l},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===l||e===i||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===g||e.$$typeof===s||e.$$typeof===c||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=k},9864:(e,t,n)=>{"use strict";e.exports=n(9921)},8356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(7294),s=n(5697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var a=d(e[r]);a.loading?t.loading=!0:(t.loaded[r]=a.loaded,t.error=a.error),n.push(a.promise),a.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),g=null;function h(){return g||(g=e(m.loader)),g.promise}return c.push(h),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=d=function(t){function n(n){var r;return o(a(a(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),g=e(m.loader),r._loadModule()})),h(),r.state={error:g.error,pastDelay:!1,timedOut:!1,loading:g.loading,loaded:g.loaded},r}r(n,t),n.preload=function(){return h()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.loadable.report(t)})),g.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:g.error,loaded:g.loaded,loading:g.loading}),e._clearTimeouts()};g.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(l.Component),o(d,"contextTypes",{loadable:s.shape({report:s.func.isRequired})}),p}function g(e){return m(d,e)}g.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return l.Children.only(this.props.children)},t}(l.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}o(h,"propTypes",{report:s.func.isRequired}),o(h,"childContextTypes",{loadable:s.shape({report:s.func.isRequired}).isRequired}),g.Capture=h,g.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},g.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=g},8790:(e,t,n)=>{"use strict";n.d(t,{H:()=>l,f:()=>i});var r=n(6550),a=n(7462),o=n(7294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var a=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return a&&(n.push({route:e,match:a}),e.routes&&i(e.routes,t,n)),a})),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(r.rs,n,e.map((function(e,n){return o.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,a.Z)({},n,{},t,{route:e})):o.createElement(e.component,(0,a.Z)({},n,t,{route:e}))}})}))):null}},3727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>u,rU:()=>h});var r=n(6550),a=n(5068),o=n(7294),i=n(9318),l=n(7462),s=n(3366),c=n(2177),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.lX)(t.props),t}return(0,a.Z)(t,e),t.prototype.render=function(){return o.createElement(r.F0,{history:this.history,children:this.props.children})},t}(o.Component);o.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},f=function(e){return e},m=o.forwardRef;void 0===m&&(m=f);var g=m((function(e,t){var n=e.innerRef,r=e.navigate,a=e.onClick,i=(0,s.Z)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,l.Z)({},i,{onClick:function(e){try{a&&a(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=f!==m&&t||n,o.createElement("a",u)}));var h=m((function(e,t){var n=e.component,a=void 0===n?g:n,u=e.replace,h=e.to,b=e.innerRef,v=(0,s.Z)(e,["component","replace","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,r=p(d(h,e.location),e.location),s=r?n.createHref(r):"",g=(0,l.Z)({},v,{href:s,navigate:function(){var t=d(h,e.location),r=(0,i.Ep)(e.location)===(0,i.Ep)(p(t));(u||r?n.replace:n.push)(t)}});return f!==m?g.ref=t||b:g.innerRef=b,o.createElement(a,g)}))})),b=function(e){return e},v=o.forwardRef;void 0===v&&(v=b);var y=v((function(e,t){var n=e["aria-current"],a=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,f=e.activeStyle,m=e.className,g=e.exact,y=e.isActive,w=e.location,k=e.sensitive,S=e.strict,E=e.style,_=e.to,x=e.innerRef,C=(0,s.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=w||e.location,i=p(d(_,n),n),s=i.pathname,T=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),L=T?(0,r.LX)(n.pathname,{path:T,exact:g,sensitive:k,strict:S}):null,A=!!(y?y(L,n):L),P="function"==typeof m?m(A):m,R="function"==typeof E?E(A):E;A&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,u),R=(0,l.Z)({},R,f));var N=(0,l.Z)({"aria-current":A&&a||null,className:P,style:R,to:i},C);return b!==v?N.ref=t||x:N.innerRef=x,o.createElement(h,N)}))}))},6550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>_,F0:()=>y,LX:()=>E,TH:()=>O,k6:()=>N,rs:()=>P,s6:()=>v});var r=n(5068),a=n(7294),o=n(5697),i=n.n(o),l=n(9318),s=n(2177),c=n(7462),u=n(4779),d=n.n(u),p=(n(9864),n(3366)),f=(n(8679),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var g=a.createContext||function(e,t){var n,o,l="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n,r,a=arguments.length,o=new Array(a),i=0;i<a;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.Z)(n,e);var a=n.prototype;return a.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},a.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(i=a)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(r,a):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},a.render=function(){return this.props.children},n}(a.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var a=n.prototype;return a.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},a.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},a.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},a.getValue=function(){return this.context[l]?this.context[l].get():e},a.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(a.Component);return c.contextTypes=((o={})[l]=i().object,o),{Provider:s,Consumer:c}},h=function(e){var t=g();return t.displayName=e,t},b=h("Router-History"),v=h("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return a.createElement(v.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},a.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(a.Component);a.Component;a.Component;var w={},k=1e4,S=0;function E(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,i=n.strict,l=void 0!==i&&i,s=n.sensitive,c=void 0!==s&&s;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var a=[],o={regexp:d()(e,a,t),keys:a};return S<k&&(r[e]=o,S++),o}(n,{end:o,strict:l,sensitive:c}),a=r.regexp,i=r.keys,s=a.exec(e);if(!s)return null;var u=s[0],p=s.slice(1),f=e===u;return o&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var _=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,s.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?E(n.pathname,e.props):t.match,o=(0,c.Z)({},t,{location:n,match:r}),i=e.props,l=i.children,u=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===a.Children.count(e)}(l)&&(l=null),a.createElement(v.Provider,{value:o},o.match?l?"function"==typeof l?l(o):l:u?a.createElement(u,o):d?d(o):null:"function"==typeof l?l(o):null)}))},t}(a.Component);function x(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=x(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,l.Ep)(e)}function L(e){return function(){(0,s.Z)(!1)}}function A(){}a.Component;var P=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,s.Z)(!1);var n,r,o=e.props.location||t.location;return a.Children.forEach(e.props.children,(function(e){if(null==r&&a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?E(o.pathname,(0,c.Z)({},e.props,{path:i})):t.match}})),r?a.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(a.Component);var R=a.useContext;function N(){return R(b)}function O(){return R(v).location}},2408:(e,t,n)=>{"use strict";var r=n(7418),a=60103,o=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,l=60110,s=60112;t.Suspense=60113;var c=60115,u=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;a=d("react.element"),o=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),l=d("react.context"),s=d("react.forward_ref"),t.Suspense=d("react.suspense"),c=d("react.memo"),u=d("react.lazy")}var p="function"==typeof Symbol&&Symbol.iterator;function f(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g={};function h(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}function b(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}h.prototype.isReactComponent={},h.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(f(85));this.updater.enqueueSetState(this,e,t,"setState")},h.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=h.prototype;var y=v.prototype=new b;y.constructor=v,r(y,h.prototype),y.isPureReactComponent=!0;var w={current:null},k=Object.prototype.hasOwnProperty,S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,n){var r,o={},i=null,l=null;if(null!=t)for(r in void 0!==t.ref&&(l=t.ref),void 0!==t.key&&(i=""+t.key),t)k.call(t,r)&&!S.hasOwnProperty(r)&&(o[r]=t[r]);var s=arguments.length-2;if(1===s)o.children=n;else if(1<s){for(var c=Array(s),u=0;u<s;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(r in s=e.defaultProps)void 0===o[r]&&(o[r]=s[r]);return{$$typeof:a,type:e,key:i,ref:l,props:o,_owner:w.current}}function _(e){return"object"==typeof e&&null!==e&&e.$$typeof===a}var x=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,n,r,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s=!1;if(null===e)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case a:case o:s=!0}}if(s)return i=i(s=e),e=""===r?"."+C(s,0):r,Array.isArray(i)?(n="",null!=e&&(n=e.replace(x,"$&/")+"/"),T(i,t,n,"",(function(e){return e}))):null!=i&&(_(i)&&(i=function(e,t){return{$$typeof:a,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||s&&s.key===i.key?"":(""+i.key).replace(x,"$&/")+"/")+e)),t.push(i)),1;if(s=0,r=""===r?".":r+":",Array.isArray(e))for(var c=0;c<e.length;c++){var u=r+C(l=e[c],c);s+=T(l,t,n,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=p&&e[p]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(l=e.next()).done;)s+=T(l=l.value,t,n,u=r+C(l,c++),i);else if("object"===l)throw t=""+e,Error(f(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return s}function L(e,t,n){if(null==e)return e;var r=[],a=0;return T(e,r,"","",(function(e){return t.call(n,e,a++)})),r}function A(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function R(){var e=P.current;if(null===e)throw Error(f(321));return e}var N={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:L,forEach:function(e,t,n){L(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return L(e,(function(){t++})),t},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!_(e))throw Error(f(143));return e}},t.Component=h,t.PureComponent=v,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=N,t.cloneElement=function(e,t,n){if(null==e)throw Error(f(267,e));var o=r({},e.props),i=e.key,l=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(l=t.ref,s=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(u in t)k.call(t,u)&&!S.hasOwnProperty(u)&&(o[u]=void 0===t[u]&&void 0!==c?c[u]:t[u])}var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){c=Array(u);for(var d=0;d<u;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:a,type:e.type,key:i,ref:l,props:o,_owner:s}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:l,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:s,render:e}},t.isValidElement=_,t.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:A}},t.memo=function(e,t){return{$$typeof:c,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return R().useCallback(e,t)},t.useContext=function(e,t){return R().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return R().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return R().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return R().useLayoutEffect(e,t)},t.useMemo=function(e,t){return R().useMemo(e,t)},t.useReducer=function(e,t,n){return R().useReducer(e,t,n)},t.useRef=function(e){return R().useRef(e)},t.useState=function(e){return R().useState(e)},t.version="17.0.2"},7294:(e,t,n)=>{"use strict";e.exports=n(2408)},53:(e,t)=>{"use strict";var n,r,a,o;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var c=null,u=null,d=function(){if(null!==c)try{var e=t.unstable_now();c(!0,e),c=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==c?setTimeout(n,0,e):(c=e,setTimeout(d,0))},r=function(e,t){u=setTimeout(e,t)},a=function(){clearTimeout(u)},t.unstable_shouldYield=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var p=window.setTimeout,f=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var g=!1,h=null,b=-1,v=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):v=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,k=w.port2;w.port1.onmessage=function(){if(null!==h){var e=t.unstable_now();y=e+v;try{h(!0,e)?k.postMessage(null):(g=!1,h=null)}catch(n){throw k.postMessage(null),n}}else g=!1},n=function(e){h=e,g||(g=!0,k.postMessage(null))},r=function(e,n){b=p((function(){e(t.unstable_now())}),n)},a=function(){f(b),b=-1}}function S(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<x(a,t)))break e;e[r]=t,e[n]=a,n=r}}function E(e){return void 0===(e=e[0])?null:e}function _(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var o=2*(r+1)-1,i=e[o],l=o+1,s=e[l];if(void 0!==i&&0>x(i,n))void 0!==s&&0>x(s,i)?(e[r]=s,e[l]=n,r=l):(e[r]=i,e[o]=n,r=o);else{if(!(void 0!==s&&0>x(s,n)))break e;e[r]=s,e[l]=n,r=l}}}return t}return null}function x(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],T=[],L=1,A=null,P=3,R=!1,N=!1,O=!1;function I(e){for(var t=E(T);null!==t;){if(null===t.callback)_(T);else{if(!(t.startTime<=e))break;_(T),t.sortIndex=t.expirationTime,S(C,t)}t=E(T)}}function D(e){if(O=!1,I(e),!N)if(null!==E(C))N=!0,n(M);else{var t=E(T);null!==t&&r(D,t.startTime-e)}}function M(e,n){N=!1,O&&(O=!1,a()),R=!0;var o=P;try{for(I(n),A=E(C);null!==A&&(!(A.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=A.callback;if("function"==typeof i){A.callback=null,P=A.priorityLevel;var l=i(A.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?A.callback=l:A===E(C)&&_(C),I(n)}else _(C);A=E(C)}if(null!==A)var s=!0;else{var c=E(T);null!==c&&r(D,c.startTime-n),s=!1}return s}finally{A=null,P=o,R=!1}}var j=o;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){N||R||(N=!0,n(M))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return E(C)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=j,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,o,i){var l=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?l+i:l:i=l,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:L++,callback:o,priorityLevel:e,startTime:i,expirationTime:s=i+s,sortIndex:-1},i>l?(e.sortIndex=i,S(T,e),null===E(C)&&e===E(T)&&(O?a():O=!0,r(D,i-l))):(e.sortIndex=s,S(C,e),N||R||(N=!0,n(M))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},3840:(e,t,n)=>{"use strict";e.exports=n(53)},6774:e=>{e.exports=function(e,t,n,r){var a=n?n.call(r,e,t):void 0;if(void 0!==a)return!!a;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<o.length;s++){var c=o[s];if(!l(c))return!1;var u=e[c],d=t[c];if(!1===(a=n?n.call(r,u,d,c):void 0)||void 0===a&&u!==d)return!1}return!0}},2177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t;throw new Error(n?a+": "+n:a)}}},3250:(e,t,n)=>{"use strict";var r=n(7294);var a="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=r.useState,i=r.useEffect,l=r.useLayoutEffect,s=r.useDebugValue;function c(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!a(e,n)}catch(r){return!0}}var u="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=o({inst:{value:n,getSnapshot:t}}),a=r[0].inst,u=r[1];return l((function(){a.value=n,a.getSnapshot=t,c(a)&&u({inst:a})}),[e,n,t]),i((function(){return c(a)&&u({inst:a}),e((function(){c(a)&&u({inst:a})}))}),[e]),s(n),n};void 0!==r.useSyncExternalStore&&r.useSyncExternalStore},1688:(e,t,n)=>{"use strict";n(3250)},6809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"The Cwtch Handbook",tagline:"Your Guide to setting up, and using, Surveillance Resistant Infrastructure",url:"https://docs.cwtch.im",baseUrl:"/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/favicon.png",organizationName:"Open Privacy Research Society",projectName:"cwtch.im",i18n:{defaultLocale:"en",locales:["en","es","de","it"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/",remarkPlugins:[null],rehypePlugins:[null]},blog:{feedOptions:{type:"all",copyright:"Copyright \xa9 ${new Date().getFullYear()} Open Privacy Research Society",title:"Cwtch Development Log",description:"The latest insight into Cwtch Development and what the Cwtch team are working on"},blogSidebarCount:20},theme:{customCss:"/home/sarah/PARA/projects/docs.cwtch.im/src/css/custom.css"}}]],themeConfig:{image:"img/cwtch_handbook_header.jpg",colorMode:{defaultMode:"dark",disableSwitch:!1,respectPrefersColorScheme:!1},navbar:{title:"Cwtch Handbook",logo:{alt:"Cwtch Logo",src:"img/knott.png"},items:[{type:"doc",docId:"intro",position:"left",label:"Cwtch Intro"},{to:"/security/intro",position:"left",label:"Security Handbook"},{to:"/developing/intro",position:"left",label:"Developers Handbook"},{to:"blog",position:"left",label:"Development Log"},{href:"https://openprivacy.ca/donate",label:"Donate",position:"right"},{href:"https://patreon.com/openprivacy",label:"Patreon",position:"right"},{href:"https://cwtch.im/download",label:"Download",position:"right"},{type:"localeDropdown",position:"right",dropdownItemsBefore:[],dropdownItemsAfter:[]}],hideOnScroll:!1},footer:{links:[{title:"Docs",items:[{label:"Introduction",to:"/docs/intro"},{to:"/security/intro",label:"Security Handbook"},{to:"/developing/intro",label:"Developer Guide"}]},{title:"Community",items:[{label:"Mastodon",href:"https://fosstodon.org/@cwtch"},{label:"Twitter",href:"https://twitter.com/cwtch_im"}]},{title:"Contribute",items:[{label:"Donate",href:"https://openprivacy.ca/donate"},{label:"Patreon",href:"https://patreon.com/openprivacy"},{label:"Source Code",href:"https://git.openprivacy.ca/cwtch.im"},{label:"Download",href:"https://cwtch.im/download"}]}],copyright:"Copyright \xa9 Open Privacy Research Society",style:"light"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},plugins:[["@docusaurus/plugin-content-docs",{id:"docs-security",path:"security",routeBasePath:"security",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}],["@docusaurus/plugin-content-docs",{id:"docs-developer",path:"developing",routeBasePath:"developing",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}]],stylesheets:[{href:"/katex/katex.min.css",type:"text/css"}],baseUrlIssueBanner:!0,onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},themes:[],scripts:[],headTags:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{mermaid:!1}}},7462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},5068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>a})},3366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}n.d(t,{Z:()=>r})},7529:e=>{"use strict";e.exports=JSON.parse('{"theme.ErrorPageContent.title":"This page crashed.","theme.ErrorPageContent.tryAgain":"Try again","theme.NotFound.title":"Page Not Found","theme.NotFound.p1":"We could not find what you were looking for.","theme.NotFound.p2":"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.","theme.BackToTopButton.buttonAriaLabel":"Scroll back to top","theme.blog.archive.title":"Archive","theme.blog.archive.description":"Archive","theme.AnnouncementBar.closeButtonAriaLabel":"Close","theme.blog.paginator.navAriaLabel":"Blog list page navigation","theme.blog.paginator.newerEntries":"Newer Entries","theme.blog.paginator.olderEntries":"Older Entries","theme.blog.post.readingTime.plurals":"One min read|{readingTime} min read","theme.blog.post.readMoreLabel":"Read more about {title}","theme.blog.post.readMore":"Read More","theme.blog.post.paginator.navAriaLabel":"Blog post page navigation","theme.blog.post.paginator.newerPost":"Newer Post","theme.blog.post.paginator.olderPost":"Older Post","theme.blog.post.plurals":"One post|{count} posts","theme.blog.tagTitle":"{nPosts} tagged with \\"{tagName}\\"","theme.tags.tagsPageLink":"View All Tags","theme.colorToggle.ariaLabel":"Switch between dark and light mode (currently {mode})","theme.colorToggle.ariaLabel.mode.dark":"dark mode","theme.colorToggle.ariaLabel.mode.light":"light mode","theme.docs.breadcrumbs.home":"Home page","theme.docs.breadcrumbs.navAriaLabel":"Breadcrumbs","theme.docs.DocCard.categoryDescription":"{count} items","theme.docs.paginator.navAriaLabel":"Docs pages navigation","theme.docs.paginator.previous":"Previous","theme.docs.paginator.next":"Next","theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel":"Toggle the collapsible sidebar category \'{label}\'","theme.docs.tagDocListPageTitle.nDocsTagged":"One doc tagged|{count} docs tagged","theme.docs.tagDocListPageTitle":"{nDocsTagged} with \\"{tagName}\\"","theme.docs.versionBadge.label":"Version: {versionLabel}","theme.docs.versions.unreleasedVersionLabel":"This is unreleased documentation for {siteTitle} {versionLabel} version.","theme.docs.versions.unmaintainedVersionLabel":"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.","theme.docs.versions.latestVersionSuggestionLabel":"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).","theme.docs.versions.latestVersionLinkLabel":"latest version","theme.common.editThisPage":"Edit this page","theme.common.headingLinkTitle":"Direct link to heading","theme.lastUpdated.atDate":" on {date}","theme.lastUpdated.byUser":" by {user}","theme.lastUpdated.lastUpdatedAtBy":"Last updated{atDate}{byUser}","theme.navbar.mobileVersionsDropdown.label":"Versions","theme.common.skipToMainContent":"Skip to main content","theme.TOCCollapsible.toggleButtonLabel":"On this page","theme.tags.tagsListLabel":"Tags:","theme.blog.sidebar.navAriaLabel":"Blog recent posts navigation","theme.CodeBlock.copied":"Copied","theme.CodeBlock.copyButtonAriaLabel":"Copy code to clipboard","theme.CodeBlock.copy":"Copy","theme.CodeBlock.wordWrapToggle":"Toggle word wrap","theme.navbar.mobileLanguageDropdown.label":"Languages","theme.docs.sidebar.collapseButtonTitle":"Collapse sidebar","theme.docs.sidebar.collapseButtonAriaLabel":"Collapse sidebar","theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel":"\u2190 Back to main menu","theme.docs.sidebar.expandButtonTitle":"Expand sidebar","theme.docs.sidebar.expandButtonAriaLabel":"Expand sidebar","theme.admonition.note":"note","theme.admonition.tip":"tip","theme.admonition.danger":"danger","theme.admonition.info":"info","theme.admonition.caution":"caution","theme.NavBar.navAriaLabel":"Main","theme.docs.sidebar.navAriaLabel":"Docs sidebar","theme.docs.sidebar.closeSidebarButtonAriaLabel":"Close navigation bar","theme.docs.sidebar.toggleSidebarButtonAriaLabel":"Toggle navigation bar","theme.tags.tagsPageTitle":"Tags","The Cwtch Handbook":"The Cwtch Handbook","Your Guide to setting up, and using, Surveillance Resistant Infrastructure":"Your Guide to setting up, and using, Surveillance Resistant Infrastructure","Get Started With Cwtch":"Get Started With Cwtch"}')},6887:e=>{"use strict";e.exports=JSON.parse('{"/blog-f58":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"metadata":"b2b675dd"},"/blog/archive-2da":{"__comp":"9e4087bc","__context":{"plugin":"c94c4dfb"},"archive":"b2f554cd"},"/blog/autobindings-1f5":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9dd8190d"},"/blog/autobindings-ii-231":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"8fe7a387"},"/blog/availability-status-profile-attributes-a8c":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6a78f460"},"/blog/cwtch-android-reproducibility-677":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9b12a270"},"/blog/cwtch-bindings-reproducible-279":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"0d64c1d9"},"/blog/cwtch-developer-documentation-44c":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a65a3c47"},"/blog/cwtch-documentation-968":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6275ceb4"},"/blog/cwtch-nightly-1-11-a07":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"c96c5262"},"/blog/cwtch-nightly-1-12-312":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a02b4022"},"/blog/cwtch-nightly-v.11-74-497":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5beee875"},"/blog/cwtch-platform-support-6f7":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5e5faacc"},"/blog/cwtch-stable-api-design-88b":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9e2a7473"},"/blog/cwtch-stable-roadmap-update-d8b":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"af23c5f9"},"/blog/cwtch-stable-roadmap-update-june-87b":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"61794344"},"/blog/cwtch-testing-i-346":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"43b107c1"},"/blog/cwtch-testing-ii-281":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9f1c7621"},"/blog/page/2-f98":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"metadata":"8eb4e46b"},"/blog/path-to-cwtch-stable-451":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"b0404c31"},"/blog/tags-0a7":{"__comp":"01a85c17","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","tags":"a7023ddc"},"/blog/tags/api-ab1":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"a79c88c2"}],"tag":"6d453d64","listMetadata":"0be9de06"},"/blog/tags/autobindings-625":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"142f86d0","listMetadata":"ce4b3243"},"/blog/tags/bindings-111":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"},{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"06a743f0","listMetadata":"442b4cb8"},"/blog/tags/cwtch-251":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"16838ca5","listMetadata":"15d993af"},"/blog/tags/cwtch-stable-808":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"4912a2e0","listMetadata":"acb99df2"},"/blog/tags/cwtch-stable/page/2-b5b":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"d6a44406","listMetadata":"6015355d"},"/blog/tags/cwtch/page/2-01c":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"55d4c988","listMetadata":"39c54b43"},"/blog/tags/developer-documentation-773":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"fe1dd7ae"},{"content":"5cb298ca"}],"tag":"1252ef76","listMetadata":"df814c0d"},"/blog/tags/documentation-0da":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"38f00f86","listMetadata":"992a3bb7"},"/blog/tags/libcwtch-b5e":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"ebdffa2e","listMetadata":"3b599162"},"/blog/tags/nightly-aea":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"141cdfa9"}],"tag":"97a045eb","listMetadata":"41c638ee"},"/blog/tags/planning-7d1":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"f041e880"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"e92b958d","listMetadata":"ef243df7"},"/blog/tags/release-60a":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"4aa555c3"},{"content":"89f86a37"}],"tag":"83d480e9","listMetadata":"9c021584"},"/blog/tags/repliqate-d17":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"a430b379","listMetadata":"76913e45"},"/blog/tags/reproducible-builds-7bf":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"e62fac9c","listMetadata":"6b72ab5e"},"/blog/tags/security-handbook-606":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"1944a0c9","listMetadata":"eb09219a"},"/blog/tags/support-132":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"},{"content":"ef78badf"}],"tag":"ac6c2a1e","listMetadata":"a34f2ac7"},"/blog/tags/testing-bc9":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"}],"tag":"15b89b76","listMetadata":"4bb443f0"},"/developing-f07":{"__comp":"1be78505","__context":{"plugin":"d5f314f9"},"versionMetadata":"f928e8d9"},"/developing/building-a-cwtch-app/building-an-echobot-416":{"__comp":"17896441","content":"fd27e325"},"/developing/building-a-cwtch-app/core-concepts-804":{"__comp":"17896441","content":"c14f15fd"},"/developing/building-a-cwtch-app/intro-2e9":{"__comp":"17896441","content":"824a28c6"},"/developing/category/building-a-cwtch-app-46a":{"__comp":"14eb3368","categoryGeneratedIndex":"7dfbf03e"},"/developing/intro-967":{"__comp":"17896441","content":"fb3c1916"},"/developing/release-b76":{"__comp":"17896441","content":"5dc151e9"},"/docs-59e":{"__comp":"1be78505","__context":{"plugin":"3db42865"},"versionMetadata":"935f2afb"},"/docs/category/appearance-7b4":{"__comp":"14eb3368","categoryGeneratedIndex":"003ad223"},"/docs/category/behaviour-e4f":{"__comp":"14eb3368","categoryGeneratedIndex":"c9a691cf"},"/docs/category/contribute-702":{"__comp":"14eb3368","categoryGeneratedIndex":"628b3074"},"/docs/category/conversations-d82":{"__comp":"14eb3368","categoryGeneratedIndex":"b59bb8da"},"/docs/category/experiments-151":{"__comp":"14eb3368","categoryGeneratedIndex":"2c8522e6"},"/docs/category/getting-started-01f":{"__comp":"14eb3368","categoryGeneratedIndex":"3152febb"},"/docs/category/groups-5c5":{"__comp":"14eb3368","categoryGeneratedIndex":"f47fcb38"},"/docs/category/platforms-3c7":{"__comp":"14eb3368","categoryGeneratedIndex":"76493ef6"},"/docs/category/profiles-387":{"__comp":"14eb3368","categoryGeneratedIndex":"986bf1b5"},"/docs/category/servers-7e8":{"__comp":"14eb3368","categoryGeneratedIndex":"693f9c9e"},"/docs/category/settings-a03":{"__comp":"14eb3368","categoryGeneratedIndex":"98da7451"},"/docs/chat/accept-deny-new-conversation-530":{"__comp":"17896441","content":"cda43b61"},"/docs/chat/add-contact-ff4":{"__comp":"17896441","content":"7285d864"},"/docs/chat/block-contact-f86":{"__comp":"17896441","content":"4e96e24f"},"/docs/chat/conversation-settings-8fa":{"__comp":"17896441","content":"efb69e30"},"/docs/chat/delete-contact-377":{"__comp":"17896441","content":"0e3e2a9e"},"/docs/chat/introduction-413":{"__comp":"17896441","content":"975564ee"},"/docs/chat/message-formatting-af9":{"__comp":"17896441","content":"43521719"},"/docs/chat/reply-to-message-cd5":{"__comp":"17896441","content":"e4fed92d"},"/docs/chat/save-conversation-history-496":{"__comp":"17896441","content":"34cd4dc6"},"/docs/chat/share-address-with-friends-280":{"__comp":"17896441","content":"7650afbf"},"/docs/chat/share-file-d13":{"__comp":"17896441","content":"0a9e402c"},"/docs/chat/unblock-contact-0c8":{"__comp":"17896441","content":"a6882456"},"/docs/contribute/developing-9ea":{"__comp":"17896441","content":"7df3f7bb"},"/docs/contribute/documentation-102":{"__comp":"17896441","content":"f146017a"},"/docs/contribute/stickers-113":{"__comp":"17896441","content":"6575cef9"},"/docs/contribute/testing-1b4":{"__comp":"17896441","content":"fc0ce2b3"},"/docs/contribute/translate-4c7":{"__comp":"17896441","content":"c4773fe1"},"/docs/getting-started/supported_platforms-744":{"__comp":"17896441","content":"553b7761"},"/docs/groups/accept-group-invite-8be":{"__comp":"17896441","content":"414c86b4"},"/docs/groups/create-group-f6d":{"__comp":"17896441","content":"dc3c323e"},"/docs/groups/edit-group-name-4f1":{"__comp":"17896441","content":"67152af3"},"/docs/groups/introduction-869":{"__comp":"17896441","content":"081d7fe1"},"/docs/groups/leave-group-d38":{"__comp":"17896441","content":"2853a99a"},"/docs/groups/manage-known-servers-3b7":{"__comp":"17896441","content":"663d5f0b"},"/docs/groups/send-invite-aa7":{"__comp":"17896441","content":"f4bfc819"},"/docs/intro-aed":{"__comp":"17896441","content":"0e384e19"},"/docs/platforms/tails-db5":{"__comp":"17896441","content":"ce314f92"},"/docs/profiles/availability-status-23c":{"__comp":"17896441","content":"89c52e74"},"/docs/profiles/change-name-4b7":{"__comp":"17896441","content":"840bb092"},"/docs/profiles/change-password-f4a":{"__comp":"17896441","content":"5a5e3510"},"/docs/profiles/change-profile-image-d00":{"__comp":"17896441","content":"697a71fd"},"/docs/profiles/create-a-profile-0dd":{"__comp":"17896441","content":"c42e2be1"},"/docs/profiles/delete-profile-f16":{"__comp":"17896441","content":"bb772baa"},"/docs/profiles/exporting-profile-290":{"__comp":"17896441","content":"44fbbcc6"},"/docs/profiles/importing-a-profile-bca":{"__comp":"17896441","content":"eb183be6"},"/docs/profiles/introduction-740":{"__comp":"17896441","content":"4e8da046"},"/docs/profiles/profile-info-87a":{"__comp":"17896441","content":"cc8d20ec"},"/docs/profiles/unlock-profile-867":{"__comp":"17896441","content":"f96ae61b"},"/docs/servers/create-server-ebf":{"__comp":"17896441","content":"48119dbc"},"/docs/servers/delete-server-6dd":{"__comp":"17896441","content":"b273a073"},"/docs/servers/edit-server-e03":{"__comp":"17896441","content":"7daa3c80"},"/docs/servers/introduction-073":{"__comp":"17896441","content":"a19b8c23"},"/docs/servers/share-key-6c7":{"__comp":"17896441","content":"ed85aa58"},"/docs/servers/unlock-server-425":{"__comp":"17896441","content":"22069e6c"},"/docs/settings/appearance/change-language-fc7":{"__comp":"17896441","content":"a08943ae"},"/docs/settings/appearance/light-dark-mode-790":{"__comp":"17896441","content":"ed9713f0"},"/docs/settings/appearance/streamer-mode-d70":{"__comp":"17896441","content":"bfc2e843"},"/docs/settings/appearance/ui-columns-99f":{"__comp":"17896441","content":"1af46bd3"},"/docs/settings/behaviour/block-unknown-connections-436":{"__comp":"17896441","content":"5a3f34f2"},"/docs/settings/behaviour/notification-content-ce9":{"__comp":"17896441","content":"2ffd7dc7"},"/docs/settings/behaviour/notification-policy-34e":{"__comp":"17896441","content":"1b4ba274"},"/docs/settings/experiments/clickable-links-e62":{"__comp":"17896441","content":"238b6b00"},"/docs/settings/experiments/file-sharing-763":{"__comp":"17896441","content":"3ce57273"},"/docs/settings/experiments/group-experiment-223":{"__comp":"17896441","content":"a6fe627e"},"/docs/settings/experiments/image-previews-and-profile-pictures-bd9":{"__comp":"17896441","content":"9d21518d"},"/docs/settings/experiments/message-formatting-314":{"__comp":"17896441","content":"5420a7ba"},"/docs/settings/experiments/qrcodes-095":{"__comp":"17896441","content":"917e8196"},"/docs/settings/experiments/server-hosting-8a2":{"__comp":"17896441","content":"a9159543"},"/docs/settings/introduction-e3a":{"__comp":"17896441","content":"c11bf3c5"},"/docs/tor-94b":{"__comp":"17896441","content":"8ec965fd"},"/security-12c":{"__comp":"1be78505","__context":{"plugin":"4f68bcc6"},"versionMetadata":"a8c7fdc6"},"/security/category/connectivity--tor-c9a":{"__comp":"14eb3368","categoryGeneratedIndex":"5b4e4bee"},"/security/category/cwtch-db2":{"__comp":"14eb3368","categoryGeneratedIndex":"437de1b1"},"/security/category/cwtch-components-b00":{"__comp":"14eb3368","categoryGeneratedIndex":"49ced744"},"/security/category/cwtch-ui-53f":{"__comp":"14eb3368","categoryGeneratedIndex":"c33e2c0d"},"/security/category/tapir-f6e":{"__comp":"14eb3368","categoryGeneratedIndex":"5f6192c8"},"/security/components/connectivity/intro-818":{"__comp":"17896441","content":"947e3a34"},"/security/components/cwtch/groups-843":{"__comp":"17896441","content":"a9d2d00e"},"/security/components/cwtch/key_bundles-cbb":{"__comp":"17896441","content":"13bbad87"},"/security/components/cwtch/message_formats-609":{"__comp":"17896441","content":"f92b996b"},"/security/components/cwtch/server-92a":{"__comp":"17896441","content":"b5c61d38"},"/security/components/ecosystem-overview-b67":{"__comp":"17896441","content":"c2081115"},"/security/components/intro-74e":{"__comp":"17896441","content":"9bb37799"},"/security/components/tapir/authentication_protocol-ab3":{"__comp":"17896441","content":"1075f7cd"},"/security/components/tapir/packet_format-4cb":{"__comp":"17896441","content":"3e7ae638"},"/security/components/ui/android-f66":{"__comp":"17896441","content":"709d36d8"},"/security/components/ui/image_previews-976":{"__comp":"17896441","content":"017f0ba6"},"/security/components/ui/input-30b":{"__comp":"17896441","content":"c063e42f"},"/security/components/ui/overlays-676":{"__comp":"17896441","content":"09058439"},"/security/deployment-ef2":{"__comp":"17896441","content":"dc098020"},"/security/development-5ad":{"__comp":"17896441","content":"d66d73fd"},"/security/intro-be1":{"__comp":"17896441","content":"d39fd6c2"},"/security/references-b21":{"__comp":"17896441","content":"b1e57def"},"/security/risk-dc7":{"__comp":"17896441","content":"5b041459"},"/-057":{"__comp":"c4f5d8e4","__context":{"plugin":"e88d32a9"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[532],(()=>{return t=9383,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/build-staging/assets/js/main.d97936a9.js.LICENSE.txt b/build-staging/assets/js/main.d97936a9.js.LICENSE.txt new file mode 100644 index 00000000..eb75d691 --- /dev/null +++ b/build-staging/assets/js/main.d97936a9.js.LICENSE.txt @@ -0,0 +1,63 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/** + * @license React + * use-sync-external-store-shim.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + */ + +/** @license React v0.20.2 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/build-staging/assets/js/runtime~main.741c7f05.js b/build-staging/assets/js/runtime~main.741c7f05.js new file mode 100644 index 00000000..220fed7b --- /dev/null +++ b/build-staging/assets/js/runtime~main.741c7f05.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,c,a,f,b,d={},t={};function r(e){var c=t[e];if(void 0!==c)return c.exports;var a=t[e]={id:e,loaded:!1,exports:{}};return d[e].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}r.m=d,r.c=t,e=[],r.O=(c,a,f,b)=>{if(!a){var d=1/0;for(i=0;i<e.length;i++){a=e[i][0],f=e[i][1],b=e[i][2];for(var t=!0,o=0;o<a.length;o++)(!1&b||d>=b)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(t=!1,b<d&&(d=b));if(t){e.splice(i--,1);var n=f();void 0!==n&&(c=n)}}return c}b=b||0;for(var i=e.length;i>0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[a,f,b]},r.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return r.d(c,{a:c}),c},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var d={};c=c||[null,a({}),a([]),a(a)];for(var t=2&f&&e;"object"==typeof t&&!~c.indexOf(t);t=a(t))Object.getOwnPropertyNames(t).forEach((c=>d[c]=()=>e[c]));return d.default=()=>e,r.d(b,d),b},r.d=(e,c)=>{for(var a in c)r.o(c,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:c[a]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((c,a)=>(r.f[a](e,c),c)),[])),r.u=e=>"assets/js/"+({1:"8eb4e46b",10:"acb99df2",53:"935f2afb",129:"238b6b00",176:"709d36d8",198:"6015355d",205:"83d480e9",225:"3152febb",266:"b1e57def",276:"fb3c1916",439:"6a78f460",533:"b2b675dd",564:"dc3c323e",610:"bfc2e843",712:"697a71fd",730:"414c86b4",732:"553b7761",788:"4d27f429",815:"1252ef76",923:"5dc151e9",962:"1af46bd3",1088:"44fbbcc6",1174:"15d993af",1179:"ce4b3243",1199:"fd27e325",1234:"7dfbf03e",1258:"9e2a7473",1312:"9f1c7621",1315:"5a5e3510",1367:"a430b379",1415:"992a3bb7",1477:"b2f554cd",1586:"7650afbf",1596:"eb183be6",1598:"4912a2e0",1602:"a8c7fdc6",1713:"a7023ddc",1800:"a08943ae",1970:"7daa3c80",1979:"fe1dd7ae",1987:"ed85aa58",2073:"2ffd7dc7",2184:"f76a3b8e",2221:"c9a691cf",2322:"67152af3",2535:"814f3328",2562:"437de1b1",2612:"c4773fe1",2688:"9dd8190d",2700:"f96ae61b",2852:"22069e6c",2909:"5cb298ca",3080:"06a743f0",3089:"a6aa9e1f",3171:"5b4e4bee",3213:"d6a44406",3218:"af23c5f9",3429:"34cd4dc6",3478:"628b3074",3492:"a02b4022",3516:"4f68bcc6",3608:"9e4087bc",3625:"986bf1b5",3628:"9d21518d",3761:"c96c5262",3838:"97a045eb",3965:"7285d864",4003:"efb69e30",4013:"01a85c17",4052:"1b4ba274",4059:"f92b996b",4078:"4bb443f0",4186:"09058439",4195:"c4f5d8e4",4325:"f47fcb38",4415:"a6882456",4704:"16838ca5",4710:"ebdffa2e",4729:"b59bb8da",4788:"1ebd8798",4842:"c42e2be1",4995:"e4fed92d",4998:"48119dbc",5006:"49ced744",5035:"cc8d20ec",5226:"f041e880",5230:"d39fd6c2",5233:"8fe7a387",5273:"bf059cf9",5327:"eb09219a",5497:"917e8196",5532:"ef78badf",5586:"7df3f7bb",5696:"081d7fe1",5732:"1a25c548",5869:"d5f314f9",5905:"824a28c6",5940:"b273a073",5941:"a9159543",6033:"76493ef6",6103:"ccc49370",6126:"a9d2d00e",6232:"61794344",6241:"f146017a",6291:"a34f2ac7",6297:"2853a99a",6341:"bb772baa",6363:"fc0ce2b3",6368:"4e8da046",6435:"a19b8c23",6471:"8ec965fd",6494:"df814c0d",6515:"5420a7ba",6539:"cda43b61",6555:"6275ceb4",6562:"0a9e402c",6585:"e88d32a9",6682:"dc098020",6927:"693f9c9e",6946:"55d4c988",6965:"ce314f92",6971:"442b4cb8",6972:"3ce57273",7011:"e92b958d",7139:"3db42865",7143:"5a3f34f2",7222:"0be9de06",7293:"141cdfa9",7294:"3b599162",7322:"c11bf3c5",7438:"9c021584",7479:"5f6192c8",7499:"2c8522e6",7531:"13bbad87",7538:"142f86d0",7591:"a65a3c47",7594:"53cc4802",7649:"c14f15fd",7667:"ef243df7",7710:"5b041459",7782:"3a109bd3",7797:"4aa555c3",7820:"ed9713f0",7860:"b0404c31",7875:"947e3a34",7918:"17896441",7992:"663d5f0b",8017:"6b72ab5e",8073:"003ad223",8141:"98da7451",8192:"5e5faacc",8194:"c2081115",8266:"41c638ee",8292:"e62fac9c",8351:"840bb092",8389:"975564ee",8392:"15b89b76",8430:"f4bfc819",8588:"6575cef9",8589:"c063e42f",8610:"6875c492",8639:"ac6c2a1e",8655:"89c52e74",8710:"0d64c1d9",8786:"f928e8d9",8793:"39c54b43",8799:"b125d866",8835:"c747432f",8849:"b5c61d38",8858:"d66d73fd",9038:"0e3e2a9e",9072:"76913e45",9140:"1944a0c9",9146:"c94c4dfb",9200:"43b107c1",9239:"a6fe627e",9249:"9b12a270",9287:"6d453d64",9376:"43521719",9398:"017f0ba6",9444:"5beee875",9514:"1be78505",9595:"3e7ae638",9667:"38f00f86",9671:"0e384e19",9726:"4e96e24f",9759:"89f86a37",9767:"9bb37799",9817:"14eb3368",9899:"1075f7cd",9936:"c33e2c0d",9976:"a79c88c2"}[e]||e)+"."+{1:"31c74b65",10:"6a426454",53:"cdf3516a",129:"1d778162",176:"7ce37739",198:"bdad9d73",205:"493a1628",225:"21d88be4",266:"39caf8a6",276:"6ddb0beb",439:"b63275b7",533:"eb291241",564:"a0698420",610:"2c458193",712:"731c5d0b",730:"d09cba17",732:"097b3d41",788:"42bfc139",815:"288a11c6",923:"3afedfb7",962:"2c226ae2",1088:"1ad2a97d",1174:"c6cf4653",1179:"db7c61a0",1199:"8533fcdc",1234:"f0688a66",1258:"1020ed04",1312:"9c0d80ed",1315:"d3615000",1367:"8153e8a0",1415:"e91a6bcf",1477:"89cd4a2e",1586:"8584622c",1596:"523c05ca",1598:"20d5fd1e",1602:"649793e5",1713:"b24ccc70",1800:"a0db67c9",1970:"f196e6d6",1979:"81e23f94",1987:"fdf5814c",2073:"c74ecef6",2184:"18e5a4dd",2221:"bfed5992",2322:"b56258c2",2535:"7742819b",2562:"df91c06b",2612:"81d125b1",2688:"f34b30a9",2700:"6149bc06",2852:"c353e095",2909:"ec2236e7",3080:"61ee1f62",3089:"4532b4f8",3171:"56fd8448",3213:"32dd75f8",3218:"7089b1b0",3429:"57acc729",3478:"b8e971a6",3492:"90907439",3516:"d9b156bf",3608:"582408aa",3625:"1e9911cc",3628:"b4fade03",3761:"b335245d",3838:"5c55b238",3965:"e6f36735",4003:"634fd7c7",4013:"fbcc85f1",4052:"735f448d",4059:"b1944282",4078:"64d3db4a",4186:"25ec1464",4195:"ea3b76f3",4325:"8650616e",4415:"7303ae16",4704:"676b1124",4710:"d46295b6",4729:"f0b56cc8",4788:"da59dcf0",4842:"c4a9586b",4972:"486cf118",4995:"91dd9f20",4998:"2ba7a442",5006:"7145707c",5035:"cf2d6d7c",5226:"789e430d",5230:"0adaf6be",5233:"3b916c07",5273:"125608d5",5327:"8186cc5c",5497:"077d63dd",5532:"d2787367",5586:"1bb99fc4",5696:"e8b72cc5",5732:"ad39b6db",5869:"1dc05f26",5905:"3dec41f3",5940:"90186f14",5941:"799d02e8",6033:"26af640a",6048:"9165c150",6103:"c18e6548",6126:"8d3943df",6232:"9d788f2d",6241:"7693dec7",6291:"72611369",6297:"dbc78f5b",6341:"ee2022e0",6363:"be0538c9",6368:"a5a18258",6435:"380ff2ab",6471:"ad8c53ac",6494:"33d74f39",6515:"5c51bc2c",6539:"56b225ab",6555:"9ce4f8c9",6562:"5921f26c",6585:"ff20b8ba",6682:"5e625d3e",6927:"b37a5356",6946:"a6931ed9",6965:"81151742",6971:"f90518cc",6972:"f5cb4514",7011:"0d8dfab1",7139:"27ab3fca",7143:"64523ca8",7222:"e2a9d663",7293:"9bc9258c",7294:"4579cba4",7322:"171064ae",7438:"82717406",7479:"8175778b",7499:"59a45b23",7531:"9e7d5b62",7538:"3d7e3bf1",7591:"bfeca907",7594:"52e4a8c3",7649:"884891e7",7667:"f9f0874b",7710:"73b0c096",7782:"e6ac824e",7797:"21c48443",7820:"54ba7352",7860:"48ec076b",7875:"7609aa54",7918:"27340309",7992:"43de0547",8017:"f554649b",8073:"d75008d1",8141:"9df2feb9",8192:"56cc8faf",8194:"5e6d9476",8266:"bf4c73bb",8292:"692a9f49",8351:"485f8fcf",8389:"8216ecd4",8392:"0decb8fe",8430:"56ce47de",8588:"c5f6ea1e",8589:"ebf0125c",8610:"3614e398",8639:"de6fd122",8655:"28f84d12",8710:"74de1478",8786:"6c170e10",8793:"3f984fa7",8799:"72e91b4f",8835:"a1ef6af4",8849:"b2aae603",8858:"ef585879",9038:"3b8ab0bf",9072:"209f5656",9140:"67f57568",9146:"5e3bcaf2",9200:"0fa4ee7a",9239:"b2883d9a",9249:"bb5deec9",9287:"4bb55d29",9376:"fff4da5d",9398:"ffa97e44",9444:"70ab5e61",9514:"c2da882e",9595:"2d4495ca",9667:"2fc26296",9671:"73b04fc3",9726:"ebb3805a",9759:"e6d969cf",9767:"506f4b14",9785:"e0c467d7",9817:"5ac78d9e",9899:"052af3ab",9936:"e031ee49",9976:"e76d7c3e"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),f={},b="user-handbook:",r.l=(e,c,a,d)=>{if(f[e])f[e].push(c);else{var t,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==b+a){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",b+a),t.src=e),f[e]=[c];var l=(c,a)=>{t.onerror=t.onload=null,clearTimeout(s);var b=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(a))),c)return c(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"7918",43521719:"9376",61794344:"6232","8eb4e46b":"1",acb99df2:"10","935f2afb":"53","238b6b00":"129","709d36d8":"176","6015355d":"198","83d480e9":"205","3152febb":"225",b1e57def:"266",fb3c1916:"276","6a78f460":"439",b2b675dd:"533",dc3c323e:"564",bfc2e843:"610","697a71fd":"712","414c86b4":"730","553b7761":"732","4d27f429":"788","1252ef76":"815","5dc151e9":"923","1af46bd3":"962","44fbbcc6":"1088","15d993af":"1174",ce4b3243:"1179",fd27e325:"1199","7dfbf03e":"1234","9e2a7473":"1258","9f1c7621":"1312","5a5e3510":"1315",a430b379:"1367","992a3bb7":"1415",b2f554cd:"1477","7650afbf":"1586",eb183be6:"1596","4912a2e0":"1598",a8c7fdc6:"1602",a7023ddc:"1713",a08943ae:"1800","7daa3c80":"1970",fe1dd7ae:"1979",ed85aa58:"1987","2ffd7dc7":"2073",f76a3b8e:"2184",c9a691cf:"2221","67152af3":"2322","814f3328":"2535","437de1b1":"2562",c4773fe1:"2612","9dd8190d":"2688",f96ae61b:"2700","22069e6c":"2852","5cb298ca":"2909","06a743f0":"3080",a6aa9e1f:"3089","5b4e4bee":"3171",d6a44406:"3213",af23c5f9:"3218","34cd4dc6":"3429","628b3074":"3478",a02b4022:"3492","4f68bcc6":"3516","9e4087bc":"3608","986bf1b5":"3625","9d21518d":"3628",c96c5262:"3761","97a045eb":"3838","7285d864":"3965",efb69e30:"4003","01a85c17":"4013","1b4ba274":"4052",f92b996b:"4059","4bb443f0":"4078","09058439":"4186",c4f5d8e4:"4195",f47fcb38:"4325",a6882456:"4415","16838ca5":"4704",ebdffa2e:"4710",b59bb8da:"4729","1ebd8798":"4788",c42e2be1:"4842",e4fed92d:"4995","48119dbc":"4998","49ced744":"5006",cc8d20ec:"5035",f041e880:"5226",d39fd6c2:"5230","8fe7a387":"5233",bf059cf9:"5273",eb09219a:"5327","917e8196":"5497",ef78badf:"5532","7df3f7bb":"5586","081d7fe1":"5696","1a25c548":"5732",d5f314f9:"5869","824a28c6":"5905",b273a073:"5940",a9159543:"5941","76493ef6":"6033",ccc49370:"6103",a9d2d00e:"6126",f146017a:"6241",a34f2ac7:"6291","2853a99a":"6297",bb772baa:"6341",fc0ce2b3:"6363","4e8da046":"6368",a19b8c23:"6435","8ec965fd":"6471",df814c0d:"6494","5420a7ba":"6515",cda43b61:"6539","6275ceb4":"6555","0a9e402c":"6562",e88d32a9:"6585",dc098020:"6682","693f9c9e":"6927","55d4c988":"6946",ce314f92:"6965","442b4cb8":"6971","3ce57273":"6972",e92b958d:"7011","3db42865":"7139","5a3f34f2":"7143","0be9de06":"7222","141cdfa9":"7293","3b599162":"7294",c11bf3c5:"7322","9c021584":"7438","5f6192c8":"7479","2c8522e6":"7499","13bbad87":"7531","142f86d0":"7538",a65a3c47:"7591","53cc4802":"7594",c14f15fd:"7649",ef243df7:"7667","5b041459":"7710","3a109bd3":"7782","4aa555c3":"7797",ed9713f0:"7820",b0404c31:"7860","947e3a34":"7875","663d5f0b":"7992","6b72ab5e":"8017","003ad223":"8073","98da7451":"8141","5e5faacc":"8192",c2081115:"8194","41c638ee":"8266",e62fac9c:"8292","840bb092":"8351","975564ee":"8389","15b89b76":"8392",f4bfc819:"8430","6575cef9":"8588",c063e42f:"8589","6875c492":"8610",ac6c2a1e:"8639","89c52e74":"8655","0d64c1d9":"8710",f928e8d9:"8786","39c54b43":"8793",b125d866:"8799",c747432f:"8835",b5c61d38:"8849",d66d73fd:"8858","0e3e2a9e":"9038","76913e45":"9072","1944a0c9":"9140",c94c4dfb:"9146","43b107c1":"9200",a6fe627e:"9239","9b12a270":"9249","6d453d64":"9287","017f0ba6":"9398","5beee875":"9444","1be78505":"9514","3e7ae638":"9595","38f00f86":"9667","0e384e19":"9671","4e96e24f":"9726","89f86a37":"9759","9bb37799":"9767","14eb3368":"9817","1075f7cd":"9899",c33e2c0d:"9936",a79c88c2:"9976"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(c,a)=>{var f=r.o(e,c)?e[c]:void 0;if(0!==f)if(f)a.push(f[2]);else if(/^(1303|532)$/.test(c))e[c]=0;else{var b=new Promise(((a,b)=>f=e[c]=[a,b]));a.push(f[2]=b);var d=r.p+r.u(c),t=new Error;r.l(d,(a=>{if(r.o(e,c)&&(0!==(f=e[c])&&(e[c]=void 0),f)){var b=a&&("load"===a.type?"missing":a.type),d=a&&a.target&&a.target.src;t.message="Loading chunk "+c+" failed.\n("+b+": "+d+")",t.name="ChunkLoadError",t.type=b,t.request=d,f[1](t)}}),"chunk-"+c,c)}},r.O.j=c=>0===e[c];var c=(c,a)=>{var f,b,d=a[0],t=a[1],o=a[2],n=0;if(d.some((c=>0!==e[c]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(c&&c(a);n<d.length;n++)b=d[n],r.o(e,b)&&e[b]&&e[b][0](),e[b]=0;return r.O(i)},a=self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[];a.forEach(c.bind(null,0)),a.push=c.bind(null,a.push.bind(a))})()})(); \ No newline at end of file diff --git a/build-staging/blog/archive/index.html b/build-staging/blog/archive/index.html new file mode 100644 index 00000000..d8f6f7bd --- /dev/null +++ b/build-staging/blog/archive/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html lang="en" dir="ltr" class="plugin-blog plugin-id-default"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v2.4.1"> +<title data-rh="true">Archive | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/blog/atom.xml b/build-staging/blog/atom.xml new file mode 100644 index 00000000..55dd93c3 --- /dev/null +++ b/build-staging/blog/atom.xml @@ -0,0 +1,276 @@ + + + https://docs.cwtch.im/blog + Cwtch Development Log + 2023-06-30T00:00:00.000Z + https://github.com/jpmonette/feed + + The latest insight into Cwtch Development and what the Cwtch team are working on + https://docs.cwtch.im/img/favicon.png + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/blog/cwtch-stable-roadmap-update-june + + 2023-06-30T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/blog/cwtch-nightly-1-12 + + 2023-06-16T00:00:00.000Z + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/blog/cwtch-nightly-v.11-74 + + 2023-06-07T00:00:00.000Z + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/blog/cwtch-developer-documentation + + 2023-04-28T00:00:00.000Z + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/blog/availability-status-profile-attributes + + 2023-04-06T00:00:00.000Z + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/blog/cwtch-stable-roadmap-update + + 2023-03-31T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/blog/cwtch-nightly-1-11 + + 2023-03-29T00:00:00.000Z + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/blog/cwtch-documentation + + 2023-03-10T00:00:00.000Z + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/blog/autobindings-ii + + 2023-03-03T00:00:00.000Z + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/blog/autobindings + + 2023-02-24T00:00:00.000Z + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/blog/cwtch-testing-ii + + 2023-02-17T00:00:00.000Z + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/blog/cwtch-android-reproducibility + + 2023-02-10T00:00:00.000Z + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/blog/cwtch-testing-i + + 2023-02-03T00:00:00.000Z + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/blog/cwtch-platform-support + + 2023-01-27T00:00:00.000Z + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/blog/cwtch-bindings-reproducible + + 2023-01-20T00:00:00.000Z + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/blog/cwtch-stable-api-design + + 2023-01-13T00:00:00.000Z + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/blog/path-to-cwtch-stable + + 2023-01-06T00:00:00.000Z + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+
\ No newline at end of file diff --git a/build-staging/blog/autobindings-ii/index.html b/build-staging/blog/autobindings-ii/index.html new file mode 100644 index 00000000..d36ef375 --- /dev/null +++ b/build-staging/blog/autobindings-ii/index.html @@ -0,0 +1,33 @@ + + + + + +Compile-time Optional Application Experiments (Autobindings) | The Cwtch Handbook + + + + + + + + + + + + +
+

Compile-time Optional Application Experiments (Autobindings)

· 5 min read
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/autobindings/index.html b/build-staging/blog/autobindings/index.html new file mode 100644 index 00000000..cabd5a25 --- /dev/null +++ b/build-staging/blog/autobindings/index.html @@ -0,0 +1,26 @@ + + + + + +Autogenerating Cwtch Bindings | The Cwtch Handbook + + + + + + + + + + + + +
+

Autogenerating Cwtch Bindings

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/availability-status-profile-attributes/index.html b/build-staging/blog/availability-status-profile-attributes/index.html new file mode 100644 index 00000000..5eed52d7 --- /dev/null +++ b/build-staging/blog/availability-status-profile-attributes/index.html @@ -0,0 +1,25 @@ + + + + + +Availability Status and Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Availability Status and Profile Attributes

· 2 min read
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-android-reproducibility/index.html b/build-staging/blog/cwtch-android-reproducibility/index.html new file mode 100644 index 00000000..9f761ce3 --- /dev/null +++ b/build-staging/blog/cwtch-android-reproducibility/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Android Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Android Bindings Reproducible

· 3 min read
Sarah Jamie Lewis

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-bindings-reproducible/index.html b/build-staging/blog/cwtch-bindings-reproducible/index.html new file mode 100644 index 00000000..65263870 --- /dev/null +++ b/build-staging/blog/cwtch-bindings-reproducible/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Bindings Reproducible

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-developer-documentation/index.html b/build-staging/blog/cwtch-developer-documentation/index.html new file mode 100644 index 00000000..5b925dba --- /dev/null +++ b/build-staging/blog/cwtch-developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly. | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.

· 3 min read
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-documentation/index.html b/build-staging/blog/cwtch-documentation/index.html new file mode 100644 index 00000000..e503ddcd --- /dev/null +++ b/build-staging/blog/cwtch-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Updates to Cwtch Documentation | The Cwtch Handbook + + + + + + + + + + + + +
+

Updates to Cwtch Documentation

· 3 min read
Sarah Jamie Lewis

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-nightly-1-11/index.html b/build-staging/blog/cwtch-nightly-1-11/index.html new file mode 100644 index 00000000..41d015b1 --- /dev/null +++ b/build-staging/blog/cwtch-nightly-1-11/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.11 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.11

· 3 min read
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-nightly-1-12/index.html b/build-staging/blog/cwtch-nightly-1-12/index.html new file mode 100644 index 00000000..1249f20c --- /dev/null +++ b/build-staging/blog/cwtch-nightly-1-12/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.12 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.12

· 3 min read
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-nightly-v.11-74/index.html b/build-staging/blog/cwtch-nightly-v.11-74/index.html new file mode 100644 index 00000000..d2e92784 --- /dev/null +++ b/build-staging/blog/cwtch-nightly-v.11-74/index.html @@ -0,0 +1,24 @@ + + + + + +New Cwtch Nightly (v1.11.0-74-g0406) | The Cwtch Handbook + + + + + + + + + + + + +
+

New Cwtch Nightly (v1.11.0-74-g0406)

· 2 min read
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-platform-support/index.html b/build-staging/blog/cwtch-platform-support/index.html new file mode 100644 index 00000000..fe9fc203 --- /dev/null +++ b/build-staging/blog/cwtch-platform-support/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI Platform Support | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch UI Platform Support

· 11 min read
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-stable-api-design/index.html b/build-staging/blog/cwtch-stable-api-design/index.html new file mode 100644 index 00000000..69f4d4d9 --- /dev/null +++ b/build-staging/blog/cwtch-stable-api-design/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable API Design | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable API Design

· 18 min read
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-stable-roadmap-update-june/index.html b/build-staging/blog/cwtch-stable-roadmap-update-june/index.html new file mode 100644 index 00000000..62a87c73 --- /dev/null +++ b/build-staging/blog/cwtch-stable-roadmap-update-june/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-stable-roadmap-update/index.html b/build-staging/blog/cwtch-stable-roadmap-update/index.html new file mode 100644 index 00000000..b2e329b5 --- /dev/null +++ b/build-staging/blog/cwtch-stable-roadmap-update/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-testing-i/index.html b/build-staging/blog/cwtch-testing-i/index.html new file mode 100644 index 00000000..e35bc6a4 --- /dev/null +++ b/build-staging/blog/cwtch-testing-i/index.html @@ -0,0 +1,25 @@ + + + + + +Notes on Cwtch UI Testing | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing

· 5 min read
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/cwtch-testing-ii/index.html b/build-staging/blog/cwtch-testing-ii/index.html new file mode 100644 index 00000000..a5ddd09c --- /dev/null +++ b/build-staging/blog/cwtch-testing-ii/index.html @@ -0,0 +1,26 @@ + + + + + +Notes on Cwtch UI Testing (II) | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing (II)

· 2 min read
Sarah Jamie Lewis

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/feed.json b/build-staging/blog/feed.json new file mode 100644 index 00000000..8b57f599 --- /dev/null +++ b/build-staging/blog/feed.json @@ -0,0 +1,292 @@ +{ + "version": "https://jsonfeed.org/version/1", + "title": "Cwtch Development Log", + "home_page_url": "https://docs.cwtch.im/blog", + "description": "The latest insight into Cwtch Development and what the Cwtch team are working on", + "items": [ + { + "id": "https://docs.cwtch.im/blog/cwtch-stable-roadmap-update-june", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-stable-roadmap-update-june", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals", + "date_modified": "2023-06-30T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-nightly-1-12", + "content_html": "

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-nightly-1-12", + "title": "Cwtch Beta 1.12", + "summary": "Cwtch Beta 1.12 is now available for download", + "date_modified": "2023-06-16T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-nightly-v.11-74", + "content_html": "

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-nightly-v.11-74", + "title": "New Cwtch Nightly (v1.11.0-74-g0406)", + "summary": "In this development log we take a look at the new Cwtch Nightly", + "date_modified": "2023-06-07T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-developer-documentation", + "content_html": "

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-developer-documentation", + "title": "Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.", + "summary": "In this development log we take a look at the new Cwtch developer docs!", + "date_modified": "2023-04-28T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/blog/availability-status-profile-attributes", + "content_html": "

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like\nours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are \"Away\" or \"Busy\".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/availability-status-profile-attributes", + "title": "Availability Status and Profile Attributes", + "summary": "Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.", + "date_modified": "2023-04-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "nightly" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-stable-roadmap-update", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-stable-roadmap-update", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more", + "date_modified": "2023-03-31T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-nightly-1-11", + "content_html": "

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-nightly-1-11", + "title": "Cwtch Beta 1.11", + "summary": "Cwtch Beta 1.11 is now available for download", + "date_modified": "2023-03-29T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-documentation", + "content_html": "

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-documentation", + "title": "Updates to Cwtch Documentation", + "summary": " In this development log we will highlight some of the major documentation updates over the last few weeks.", + "date_modified": "2023-03-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "documentation", + "security-handbook" + ] + }, + { + "id": "https://docs.cwtch.im/blog/autobindings-ii", + "content_html": "

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an\ninitialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can\npass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option exp which will call the function on the configured experiment, and global to allow the setting up\nof a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import \"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on\ngeneration of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the\nfeature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/autobindings-ii", + "title": "Compile-time Optional Application Experiments (Autobindings)", + "summary": "In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.", + "date_modified": "2023-03-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/blog/autobindings", + "content_html": "

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/autobindings", + "title": "Autogenerating Cwtch Bindings", + "summary": "In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.", + "date_modified": "2023-02-24T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-testing-ii", + "content_html": "

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-testing-ii", + "title": "Notes on Cwtch UI Testing (II)", + "summary": "In this development log we provide more updates on automated UI integration testing!", + "date_modified": "2023-02-17T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-android-reproducibility", + "content_html": "

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-android-reproducibility", + "title": "Making Cwtch Android Bindings Reproducible", + "summary": "In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible", + "date_modified": "2023-02-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-testing-i", + "content_html": "

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like \"take a screenshot\" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-testing-i", + "title": "Notes on Cwtch UI Testing", + "summary": "In this development log we provide an update on automated UI integration testing!", + "date_modified": "2023-02-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-platform-support", + "content_html": "

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\"

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

\"🟡\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-platform-support", + "title": "Cwtch UI Platform Support", + "summary": "This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.", + "date_modified": "2023-01-27T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-bindings-reproducible", + "content_html": "

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/cwtch-bindings-reproducible", + "title": "Making Cwtch Bindings Reproducible", + "summary": "How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.", + "date_modified": "2023-01-20T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/blog/cwtch-stable-api-design", + "content_html": "

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • \"Unencrypted\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \"unencrypted\".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
", + "url": "https://docs.cwtch.im/blog/cwtch-stable-api-design", + "title": "Cwtch Stable API Design", + "summary": "The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ", + "date_modified": "2023-01-13T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning", + "api" + ] + }, + { + "id": "https://docs.cwtch.im/blog/path-to-cwtch-stable", + "content_html": "

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/blog/path-to-cwtch-stable", + "title": "Path to Cwtch Stable", + "summary": "The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.", + "date_modified": "2023-01-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + } + ] +} \ No newline at end of file diff --git a/build-staging/blog/index.html b/build-staging/blog/index.html new file mode 100644 index 00000000..4cb4a1d8 --- /dev/null +++ b/build-staging/blog/index.html @@ -0,0 +1,26 @@ + + + + + +Development Log | The Cwtch Handbook + + + + + + + + + + + + +
+

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 2 min read
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 min read
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 min read
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 min read
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/page/2/index.html b/build-staging/blog/page/2/index.html new file mode 100644 index 00000000..627f420b --- /dev/null +++ b/build-staging/blog/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +Development Log | The Cwtch Handbook + + + + + + + + + + + + +
+

· 5 min read
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 min read
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 min read
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 min read
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/path-to-cwtch-stable/index.html b/build-staging/blog/path-to-cwtch-stable/index.html new file mode 100644 index 00000000..20b4cd09 --- /dev/null +++ b/build-staging/blog/path-to-cwtch-stable/index.html @@ -0,0 +1,24 @@ + + + + + +Path to Cwtch Stable | The Cwtch Handbook + + + + + + + + + + + + +
+

Path to Cwtch Stable

· 10 min read
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/blog/rss.xml b/build-staging/blog/rss.xml new file mode 100644 index 00000000..a6d04044 --- /dev/null +++ b/build-staging/blog/rss.xml @@ -0,0 +1,227 @@ + + + + Cwtch Development Log + https://docs.cwtch.im/blog + The latest insight into Cwtch Development and what the Cwtch team are working on + Fri, 30 Jun 2023 00:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + en + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/blog/cwtch-stable-roadmap-update-june + https://docs.cwtch.im/blog/cwtch-stable-roadmap-update-june + Fri, 30 Jun 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/blog/cwtch-nightly-1-12 + https://docs.cwtch.im/blog/cwtch-nightly-1-12 + Fri, 16 Jun 2023 00:00:00 GMT + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/blog/cwtch-nightly-v.11-74 + https://docs.cwtch.im/blog/cwtch-nightly-v.11-74 + Wed, 07 Jun 2023 00:00:00 GMT + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/blog/cwtch-developer-documentation + https://docs.cwtch.im/blog/cwtch-developer-documentation + Fri, 28 Apr 2023 00:00:00 GMT + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/blog/availability-status-profile-attributes + https://docs.cwtch.im/blog/availability-status-profile-attributes + Thu, 06 Apr 2023 00:00:00 GMT + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + nightly +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/blog/cwtch-stable-roadmap-update + https://docs.cwtch.im/blog/cwtch-stable-roadmap-update + Fri, 31 Mar 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/blog/cwtch-nightly-1-11 + https://docs.cwtch.im/blog/cwtch-nightly-1-11 + Wed, 29 Mar 2023 00:00:00 GMT + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/blog/cwtch-documentation + https://docs.cwtch.im/blog/cwtch-documentation + Fri, 10 Mar 2023 00:00:00 GMT + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + documentation + security-handbook +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/blog/autobindings-ii + https://docs.cwtch.im/blog/autobindings-ii + Fri, 03 Mar 2023 00:00:00 GMT + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/blog/autobindings + https://docs.cwtch.im/blog/autobindings + Fri, 24 Feb 2023 00:00:00 GMT + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/blog/cwtch-testing-ii + https://docs.cwtch.im/blog/cwtch-testing-ii + Fri, 17 Feb 2023 00:00:00 GMT + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/blog/cwtch-android-reproducibility + https://docs.cwtch.im/blog/cwtch-android-reproducibility + Fri, 10 Feb 2023 00:00:00 GMT + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/blog/cwtch-testing-i + https://docs.cwtch.im/blog/cwtch-testing-i + Fri, 03 Feb 2023 00:00:00 GMT + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/blog/cwtch-platform-support + https://docs.cwtch.im/blog/cwtch-platform-support + Fri, 27 Jan 2023 00:00:00 GMT + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/blog/cwtch-bindings-reproducible + https://docs.cwtch.im/blog/cwtch-bindings-reproducible + Fri, 20 Jan 2023 00:00:00 GMT + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/blog/cwtch-stable-api-design + https://docs.cwtch.im/blog/cwtch-stable-api-design + Fri, 13 Jan 2023 00:00:00 GMT + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ cwtch + cwtch-stable + planning + api +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/blog/path-to-cwtch-stable + https://docs.cwtch.im/blog/path-to-cwtch-stable + Fri, 06 Jan 2023 00:00:00 GMT + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+
+
\ No newline at end of file diff --git a/build-staging/blog/tags/api/index.html b/build-staging/blog/tags/api/index.html new file mode 100644 index 00000000..800e3397 --- /dev/null +++ b/build-staging/blog/tags/api/index.html @@ -0,0 +1,24 @@ + + + + + +One post tagged with "api" | The Cwtch Handbook + + + + + + + + + + + + +
+

One post tagged with "api"

View All Tags

· 18 min read
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/autobindings/index.html b/build-staging/blog/tags/autobindings/index.html new file mode 100644 index 00000000..bced3e64 --- /dev/null +++ b/build-staging/blog/tags/autobindings/index.html @@ -0,0 +1,25 @@ + + + + + +2 posts tagged with "autobindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "autobindings"

View All Tags

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/bindings/index.html b/build-staging/blog/tags/bindings/index.html new file mode 100644 index 00000000..1385b2f7 --- /dev/null +++ b/build-staging/blog/tags/bindings/index.html @@ -0,0 +1,25 @@ + + + + + +4 posts tagged with "bindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 posts tagged with "bindings"

View All Tags

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/cwtch-stable/index.html b/build-staging/blog/tags/cwtch-stable/index.html new file mode 100644 index 00000000..28e7e4b2 --- /dev/null +++ b/build-staging/blog/tags/cwtch-stable/index.html @@ -0,0 +1,26 @@ + + + + + +17 posts tagged with "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 posts tagged with "cwtch-stable"

View All Tags

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 2 min read
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 min read
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 min read
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 min read
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/cwtch-stable/page/2/index.html b/build-staging/blog/tags/cwtch-stable/page/2/index.html new file mode 100644 index 00000000..6e5a06b5 --- /dev/null +++ b/build-staging/blog/tags/cwtch-stable/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 posts tagged with "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 posts tagged with "cwtch-stable"

View All Tags

· 5 min read
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 min read
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 min read
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 min read
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/cwtch/index.html b/build-staging/blog/tags/cwtch/index.html new file mode 100644 index 00000000..f4dec78a --- /dev/null +++ b/build-staging/blog/tags/cwtch/index.html @@ -0,0 +1,26 @@ + + + + + +17 posts tagged with "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 posts tagged with "cwtch"

View All Tags

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 2 min read
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 min read
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 min read
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 min read
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/cwtch/page/2/index.html b/build-staging/blog/tags/cwtch/page/2/index.html new file mode 100644 index 00000000..801f05e7 --- /dev/null +++ b/build-staging/blog/tags/cwtch/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 posts tagged with "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 posts tagged with "cwtch"

View All Tags

· 5 min read
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 min read
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 min read
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 min read
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/developer-documentation/index.html b/build-staging/blog/tags/developer-documentation/index.html new file mode 100644 index 00000000..94e47b34 --- /dev/null +++ b/build-staging/blog/tags/developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +2 posts tagged with "developer-documentation" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "developer-documentation"

View All Tags

· 2 min read
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 min read
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/documentation/index.html b/build-staging/blog/tags/documentation/index.html new file mode 100644 index 00000000..3c7bb290 --- /dev/null +++ b/build-staging/blog/tags/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +One post tagged with "documentation" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/blog/tags/index.html b/build-staging/blog/tags/index.html new file mode 100644 index 00000000..52df4c12 --- /dev/null +++ b/build-staging/blog/tags/index.html @@ -0,0 +1,24 @@ + + + + + +Tags | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/blog/tags/libcwtch/index.html b/build-staging/blog/tags/libcwtch/index.html new file mode 100644 index 00000000..c04b6b5f --- /dev/null +++ b/build-staging/blog/tags/libcwtch/index.html @@ -0,0 +1,25 @@ + + + + + +2 posts tagged with "libcwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "libcwtch"

View All Tags

· 5 min read
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/nightly/index.html b/build-staging/blog/tags/nightly/index.html new file mode 100644 index 00000000..334a12b6 --- /dev/null +++ b/build-staging/blog/tags/nightly/index.html @@ -0,0 +1,25 @@ + + + + + +One post tagged with "nightly" | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/planning/index.html b/build-staging/blog/tags/planning/index.html new file mode 100644 index 00000000..45028fed --- /dev/null +++ b/build-staging/blog/tags/planning/index.html @@ -0,0 +1,24 @@ + + + + + +4 posts tagged with "planning" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 posts tagged with "planning"

View All Tags

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 6 min read
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 18 min read
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 min read
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/release/index.html b/build-staging/blog/tags/release/index.html new file mode 100644 index 00000000..b487f15b --- /dev/null +++ b/build-staging/blog/tags/release/index.html @@ -0,0 +1,24 @@ + + + + + +2 posts tagged with "release" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "release"

View All Tags

· 3 min read
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/repliqate/index.html b/build-staging/blog/tags/repliqate/index.html new file mode 100644 index 00000000..8cf7a291 --- /dev/null +++ b/build-staging/blog/tags/repliqate/index.html @@ -0,0 +1,24 @@ + + + + + +2 posts tagged with "repliqate" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "repliqate"

View All Tags

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/reproducible-builds/index.html b/build-staging/blog/tags/reproducible-builds/index.html new file mode 100644 index 00000000..697b6169 --- /dev/null +++ b/build-staging/blog/tags/reproducible-builds/index.html @@ -0,0 +1,24 @@ + + + + + +2 posts tagged with "reproducible-builds" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "reproducible-builds"

View All Tags

· 8 min read
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/security-handbook/index.html b/build-staging/blog/tags/security-handbook/index.html new file mode 100644 index 00000000..8254ffb1 --- /dev/null +++ b/build-staging/blog/tags/security-handbook/index.html @@ -0,0 +1,24 @@ + + + + + +One post tagged with "security-handbook" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/blog/tags/support/index.html b/build-staging/blog/tags/support/index.html new file mode 100644 index 00000000..fdff48c6 --- /dev/null +++ b/build-staging/blog/tags/support/index.html @@ -0,0 +1,24 @@ + + + + + +3 posts tagged with "support" | The Cwtch Handbook + + + + + + + + + + + + +
+

3 posts tagged with "support"

View All Tags

· 5 min read
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 min read
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

+ + + + \ No newline at end of file diff --git a/build-staging/blog/tags/testing/index.html b/build-staging/blog/tags/testing/index.html new file mode 100644 index 00000000..7484ec90 --- /dev/null +++ b/build-staging/blog/tags/testing/index.html @@ -0,0 +1,24 @@ + + + + + +2 posts tagged with "testing" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 posts tagged with "testing"

View All Tags

· 5 min read
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

+ + + + \ No newline at end of file diff --git a/build-staging/build/.nojekyll b/build-staging/build/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/build-staging/de/.nojekyll b/build-staging/de/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/build-staging/de/404.html b/build-staging/de/404.html new file mode 100644 index 00000000..a00a7b32 --- /dev/null +++ b/build-staging/de/404.html @@ -0,0 +1,24 @@ + + + + + +Seite nicht gefunden | The Cwtch Handbook + + + + + + + + + + + + +
+

Seite nicht gefunden

Wir konnten leider nicht finden, wonach du gesucht hast.

Bitte kontaktiere den/die Besitzer*in der Seite, die dich mit der ursprünglichen URL verlinkt hat, und teile mit, dass der Link nicht mehr funktioniert.

+ + + + \ No newline at end of file diff --git a/build-staging/de/assets/css/styles.c29a7aad.css b/build-staging/de/assets/css/styles.c29a7aad.css new file mode 100644 index 00000000..2ffda748 --- /dev/null +++ b/build-staging/de/assets/css/styles.c29a7aad.css @@ -0,0 +1,2 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center,figcaption,figure,figure p a img{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_tbUL,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.sidebar_re4s,.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_S0QG>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q>:last-child,.footer__items{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.sidebarItemTitle_pO2u,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#8e64a5;--ifm-font-color-base:#281831;--ifm-navbar-background-color:#fdf3fc;--ifm-code-font-size:95%;--ifm-footer-background-color:#fdf3fc;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#dfb9de;--ifm-font-color-base:#fdf3fc;--ifm-navbar-background-color:#281831;--ifm-footer-background-color:#281831;--docusaurus-highlighted-code-line-bg:#0000004d}.ui-button{background-color:#fdf3fc;height:24px;width:24px}td>img{vertical-align:sub}figcaption{font-size:10px}h1[class*=" blogPostTitle"],h1[class^=blogPostTitle],h2[class^=blogPostTitle]{font-size:2rem}[data-theme=dark] +.icon{filter:invert(1)}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_b6E3,.sidebarLogo_isFc,.themedImage_ToTc,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedImage--dark_i4oU,[data-theme=light] .themedImage--light_HNdA{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docMainContainer_gTbr,.docPage__5DB{display:flex;width:100%}.docPage__5DB{flex:1 0}.docsWrapper_BCFX{display:flex;flex:1 0 auto}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.buttons_AeoN,.features_t9lD{align-items:center;display:flex}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.heroBanner_qdFl{background:url(/de/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg) top no-repeat;color:#fdf3fc;height:670px;overflow:hidden;padding:4rem 0;position:relative;text-align:center}.heroBanner_qdFl p{color:#fdf3fc;font-weight:700;text-shadow:-1px -1px 0 #281831,1px -1px 0 #281831,-1px 1px 0 #281831,1px 1px 0 #281831}.buttons_AeoN{justify-content:center}.button_JGCe{background-color:#8e64a5;color:#fdf3fc}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.features_t9lD{padding:2rem 0;width:100%}.featureSvg_GfXr{height:200px;width:200px}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.img_ev3q{height:auto}.admonition_LlT9{margin-bottom:1em}.admonitionHeading_tbUL{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.3rem}.admonitionHeading_tbUL code{text-transform:none}.admonitionIcon_kALy{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_kALy svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.blogPostFooterDetailsFull_mRVl{flex-direction:column}.tableOfContents_bqdL{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.searchBox_ZlJk{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_BlDH,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_m80_:focus,.expandButton_m80_:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_m80_{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_BlDH{transform:rotate(180deg)}.docSidebarContainer_b6E3{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_b3ry{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_Xe31{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_gTbr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_Uz_u{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_czyv{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:996px){.heroBanner_qdFl{padding:2rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/build-staging/de/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/de/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/de/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/de/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/de/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/de/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/de/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/de/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/de/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/de/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/de/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/de/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/de/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png b/build-staging/de/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/de/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png differ diff --git a/build-staging/de/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/de/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/de/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/de/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/de/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/de/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/de/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/de/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/de/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/de/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/de/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/de/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/de/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/de/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/de/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/de/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/de/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/de/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/de/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/de/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/de/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/de/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/de/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/de/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/de/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/de/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/de/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/de/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png b/build-staging/de/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/de/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png differ diff --git a/build-staging/de/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png b/build-staging/de/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/de/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png differ diff --git a/build-staging/de/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/de/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/de/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/de/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/de/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/de/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/de/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/de/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/de/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/de/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/de/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/de/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/de/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png b/build-staging/de/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/de/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png differ diff --git a/build-staging/de/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png b/build-staging/de/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/de/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png differ diff --git a/build-staging/de/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png b/build-staging/de/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/de/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png differ diff --git a/build-staging/de/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png b/build-staging/de/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/de/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png differ diff --git a/build-staging/de/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png b/build-staging/de/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/de/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png differ diff --git a/build-staging/de/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png b/build-staging/de/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/de/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png differ diff --git a/build-staging/de/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png b/build-staging/de/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/de/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png differ diff --git a/build-staging/de/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png b/build-staging/de/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/de/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png differ diff --git a/build-staging/de/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png b/build-staging/de/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/de/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png differ diff --git a/build-staging/de/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png b/build-staging/de/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/de/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png differ diff --git a/build-staging/de/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png b/build-staging/de/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/de/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png differ diff --git a/build-staging/de/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png b/build-staging/de/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/de/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png differ diff --git a/build-staging/de/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png b/build-staging/de/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/de/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png differ diff --git a/build-staging/de/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/de/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/de/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/de/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg b/build-staging/de/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/de/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg differ diff --git a/build-staging/de/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/de/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/de/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/de/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/de/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/de/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/de/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/de/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/de/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/de/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/de/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/de/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/de/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/de/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/de/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/de/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/de/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/de/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/de/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/de/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/de/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/de/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/de/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/de/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/de/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg b/build-staging/de/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/de/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg differ diff --git a/build-staging/de/assets/js/001a236d.36952d55.js b/build-staging/de/assets/js/001a236d.36952d55.js new file mode 100644 index 00000000..542bbe9a --- /dev/null +++ b/build-staging/de/assets/js/001a236d.36952d55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3951],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},f=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),f=o,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return t?n.createElement(m,i(i({ref:r},p),{},{components:t})):n.createElement(m,i({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=f;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:3},i="Passwort \xe4ndern",s={unversionedId:"profiles/change-password",id:"profiles/change-password",title:"Passwort \xe4ndern",description:"1. Dr\xfccke den Stift neben dem Profil, das du bearbeiten m\xf6chtest",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/change-password.md",sourceDirName:"profiles",slug:"/profiles/change-password",permalink:"/de/docs/profiles/change-password",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-password.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"\xc4ndern Deines Anzeigenamens",permalink:"/de/docs/profiles/change-name"},next:{title:"Dein Profilbild \xe4ndern",permalink:"/de/docs/profiles/change-profile-image"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"passwort-\xe4ndern"},"Passwort \xe4ndern"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Dr\xfccke den Stift neben dem Profil, das du bearbeiten m\xf6chtest"),(0,o.kt)("li",{parentName:"ol"},"Gehe zum aktuellen Passwort und gib dein aktuelles Passwort ein"),(0,o.kt)("li",{parentName:"ol"},"Gehe zu neuem Passwort und gib dein neues Passwort ein"),(0,o.kt)("li",{parentName:"ol"},"Passwort erneut eingeben"),(0,o.kt)("li",{parentName:"ol"},"Profil speichern klicken")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/01a85c17.fbcc85f1.js b/build-staging/de/assets/js/01a85c17.fbcc85f1.js new file mode 100644 index 00000000..ea8df306 --- /dev/null +++ b/build-staging/de/assets/js/01a85c17.fbcc85f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4013],{9058:(e,t,a)=>{a.d(t,{Z:()=>E});var l=a(7294),r=a(6010),n=a(7961),s=a(7524),i=a(9960),c=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function o(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,c.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function g(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function b(e){return l.createElement(u.Zo,{component:g,props:e})}function d(e){let{sidebar:t}=e;const a=(0,s.i)();return t?.items.length?"mobile"===a?l.createElement(b,{sidebar:t}):l.createElement(o,{sidebar:t}):null}function E(e){const{sidebar:t,toc:a,children:s,...i}=e,c=t&&t.items.length>0;return l.createElement(n.Z,i,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(d,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":c,"col--9 col--offset-1":!c}),itemScope:!0,itemType:"http://schema.org/Blog"},s),a&&l.createElement("div",{className:"col col--2"},a))))}},1223:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var l=a(7294),r=a(6010),n=a(5999);const s=()=>(0,n.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var i=a(1944),c=a(5281),m=a(9058),o=a(3008);const u={tag:"tag_Nnez"};function g(e){let{letterEntry:t}=e;return l.createElement("article",null,l.createElement("h2",null,t.letter),l.createElement("ul",{className:"padding--none"},t.tags.map((e=>l.createElement("li",{key:e.permalink,className:u.tag},l.createElement(o.Z,e))))),l.createElement("hr",null))}function b(e){let{tags:t}=e;const a=function(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[l]=t;return a.localeCompare(l)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}(t);return l.createElement("section",{className:"margin-vert--lg"},a.map((e=>l.createElement(g,{key:e.letter,letterEntry:e}))))}var d=a(197);function E(e){let{tags:t,sidebar:a}=e;const n=s();return l.createElement(i.FG,{className:(0,r.Z)(c.k.wrapper.blogPages,c.k.page.blogTagsListPage)},l.createElement(i.d,{title:n}),l.createElement(d.Z,{tag:"blog_tags_list"}),l.createElement(m.Z,{sidebar:a},l.createElement("h1",null,n),l.createElement(b,{tags:t})))}},3008:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(7294),r=a(6010),n=a(9960);const s={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function i(e){let{permalink:t,label:a,count:i}=e;return l.createElement(n.Z,{href:t,className:(0,r.Z)(s.tag,i?s.tagWithCount:s.tagRegular)},a,i&&l.createElement("span",null,i))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/021fdb12.feb7c5a3.js b/build-staging/de/assets/js/021fdb12.feb7c5a3.js new file mode 100644 index 00000000..a8e1ad9c --- /dev/null +++ b/build-staging/de/assets/js/021fdb12.feb7c5a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8351],{2596:e=>{e.exports=JSON.parse('{"title":"Einstellungen","slug":"/category/settings","permalink":"/de/docs/category/settings","navigation":{"previous":{"title":"Wie man einen Server entsperrt","permalink":"/de/docs/servers/unlock-server"},"next":{"title":"Eine Einf\xfchrung in die Cwtch App-Einstellungen","permalink":"/de/docs/settings/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/03e998ac.0baefc34.js b/build-staging/de/assets/js/03e998ac.0baefc34.js new file mode 100644 index 00000000..6b3af482 --- /dev/null +++ b/build-staging/de/assets/js/03e998ac.0baefc34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8581],{4437:s=>{s.exports=JSON.parse('{"label":"bindings","permalink":"/de/blog/tags/bindings","allTagsPath":"/de/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0487f903.207c6625.js b/build-staging/de/assets/js/0487f903.207c6625.js new file mode 100644 index 00000000..5ef9fe1f --- /dev/null +++ b/build-staging/de/assets/js/0487f903.207c6625.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3629],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>p});var i=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var o=i.createContext({}),u=function(e){var n=i.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},l=function(e){var n=u(e.components);return i.createElement(o.Provider,{value:n},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},m=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,a=e.originalType,o=e.parentName,l=d(e,["components","mdxType","originalType","parentName"]),c=u(t),m=r,p=c["".concat(o,".").concat(m)]||c[m]||h[m]||a;return t?i.createElement(p,s(s({ref:n},l),{},{components:t})):i.createElement(p,s({ref:n},l))}));function p(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var a=t.length,s=new Array(a);s[0]=m;var d={};for(var o in n)hasOwnProperty.call(n,o)&&(d[o]=n[o]);d.originalType=e,d[c]="string"==typeof e?e:r,s[1]=d;for(var u=2;u{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>u});var i=t(7462),r=(t(7294),t(3905));const a={sidebar_position:6},s="Eine Datei teilen",d={unversionedId:"chat/share-file",id:"chat/share-file",title:"Eine Datei teilen",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Datei Teilen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/share-file.md",sourceDirName:"chat",slug:"/chat/share-file",permalink:"/de/docs/chat/share-file",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-file.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Auf eine Nachricht antworten",permalink:"/de/docs/chat/reply-to-message"},next:{title:"Einen Kontakt blockieren",permalink:"/de/docs/chat/block-contact"}},o={},u=[{value:"Wie funktioniert das Teilen von Dateien mit Gruppen? Sind meine Dateien irgendwo auf einem Server gespeichert?",id:"wie-funktioniert-das-teilen-von-dateien-mit-gruppen-sind-meine-dateien-irgendwo-auf-einem-server-gespeichert",level:2},{value:"Muss ich somit online sein, um eine Datei zu senden?",id:"muss-ich-somit-online-sein-um-eine-datei-zu-senden",level:2},{value:"Warum tauchen neue Kontakte in meiner Liste auf?",id:"warum-tauchen-neue-kontakte-in-meiner-liste-auf",level:2},{value:"Was hei\xdft "SHA512"?",id:"was-hei\xdft-sha512",level:2},{value:"Gibt es eine Begrenzung der Dateigr\xf6\xdfe?",id:"gibt-es-eine-begrenzung-der-dateigr\xf6\xdfe",level:2},{value:"Was sind diese .manifest Dateien?",id:"was-sind-diese-manifest-dateien",level:2},{value:"Was ist mit den Datei-Metadaten?",id:"was-ist-mit-den-datei-metadaten",level:2},{value:"Kann ich Dateien automatisch herunterladen?",id:"kann-ich-dateien-automatisch-herunterladen",level:2}],l={toc:u},c="wrapper";function h(e){let{components:n,...t}=e;return(0,r.kt)(c,(0,i.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"eine-datei-teilen"},"Eine Datei teilen"),(0,r.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"Datei Teilen Experiment")," eingeschaltet ist."),(0,r.kt)("p",{parentName:"admonition"},"Optional kannst du ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Bilder und Profilbilder Vorschau")," aktivieren, um geteilte Bilder als Vorschau im Konversationsfenster zu sehen.")),(0,r.kt)("p",null,"In einer Konversation"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Klicke auf das Anhang-Symbol"),(0,r.kt)("li",{parentName:"ol"},"Finde die Datei, die du senden m\xf6chtest"),(0,r.kt)("li",{parentName:"ol"},"Best\xe4tige, dass du es senden m\xf6chtest")),(0,r.kt)("h2",{id:"wie-funktioniert-das-teilen-von-dateien-mit-gruppen-sind-meine-dateien-irgendwo-auf-einem-server-gespeichert"},"Wie funktioniert das Teilen von Dateien mit Gruppen? Sind meine Dateien irgendwo auf einem Server gespeichert?"),(0,r.kt)("p",null,"Dateien werden \xfcber onion-to-onion Cwtch Verbindungen direkt von der Person verschickt, die die Datei dem Empf\xe4nger anbietet. Das urspr\xfcngliche Angebot zum Senden einer Datei wird als Standard Cwtch Konversation/Overlay-Nachricht ver\xf6ffentlicht. F\xfcr Gruppen bedeutet dies, dass das urspr\xfcngliche Angebot (welches den Dateinamen, die Gr\xf6\xdfe, Hash und eine Nonce beinhaltet) auf den Gruppenserver gestellt wird aber dann verbindet sich jeder Empf\xe4nger zu dir, um den eigentlichen Dateiinhalt zu erhalten."),(0,r.kt)("h2",{id:"muss-ich-somit-online-sein-um-eine-datei-zu-senden"},"Muss ich somit online sein, um eine Datei zu senden?"),(0,r.kt)("p",null,'Ja. Wenn die Person, die die Datei anbietet, offline geht, musst du warten, bis sie online kommt, um die \xdcbertragung fortzusetzen. Das zugrunde liegende Protokoll teilt die Dateien in einzelne, \xfcberpr\xfcfbare Chunks, so dass Sie in einer zuk\xfcnftigen Version eine Datei "rehosten" k\xf6nnen, die in einer Gruppe ver\xf6ffentlicht wird und sogar Download von mehreren Hosts auf einmal (eine Art von Bittorrent) m\xf6glich sein wird.'),(0,r.kt)("h2",{id:"warum-tauchen-neue-kontakte-in-meiner-liste-auf"},"Warum tauchen neue Kontakte in meiner Liste auf?"),(0,r.kt)("p",null,"Dies ist darauf zur\xfcckzuf\xfchren, wie Cwtch derzeit Verbindungen von unbekannten Adressen behandelt. Da eine Datei in eine Gruppe geschrieben wird, f\xfchrt dies dazu, dass Gruppenmitglieder sich direkt mit dir verbinden, einige dieser Mitglieder befinden sich m\xf6glicherweise noch nicht in deiner Kontaktliste, so dass deren Downloadverbindung zu dir als Kontaktanfrage in deiner Liste erscheint."),(0,r.kt)("h2",{id:"was-hei\xdft-sha512"},'Was hei\xdft "SHA512"?'),(0,r.kt)("p",null,"SHA512 ist ein ",(0,r.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Cryptographic_hash_function"},"kryptographischer Hash")," der verwendet werden kann, um zu \xfcberpr\xfcfen, dass die heruntergeladene Datei eine korrekte Kopie der angebotenen Datei ist. Cwtch macht diese Verifizierung automatisch, aber du bist herzlich eingeladen, es selbst auszuprobieren! Beachte, dass wir auch ein zuf\xe4lliges nonce in Datei-Angeboten einschlie\xdfen, so dass die Leute dich nicht einfach nach einem zuf\xe4lligen Hash fragen k\xf6nnen, den du haben kannst, oder Dateien aus Unterhaltungen, von denen sie nicht selber dabei sind."),(0,r.kt)("h2",{id:"gibt-es-eine-begrenzung-der-dateigr\xf6\xdfe"},"Gibt es eine Begrenzung der Dateigr\xf6\xdfe?"),(0,r.kt)("p",null,"Das aktuelle Limit betr\xe4gt 10 Gigabytes pro Datei."),(0,r.kt)("h2",{id:"was-sind-diese-manifest-dateien"},"Was sind diese .manifest Dateien?"),(0,r.kt)("p",null,"Die .manifest-Dateien werden beim Herunterladen der Datei verwendet, um zu \xfcberpr\xfcfen, ob einzelne Chunks korrekt empfangen werden, und um die Fortsetzung der unterbrochenen \xdcbertragung zu unterst\xfctzen. Sie enthalten auch die Informationen aus dem urspr\xfcnglichen Datei-Angebot. Du kannst diese sicher l\xf6schen, sobald der Download abgeschlossen ist. Auf Android werden die Manifeste im Cache der App gespeichert und k\xf6nnen \xfcber die Systemeinstellungen gel\xf6scht werden."),(0,r.kt)("h2",{id:"was-ist-mit-den-datei-metadaten"},"Was ist mit den Datei-Metadaten?"),(0,r.kt)("p",null,"Wir schicken den Namen der Datei als Vorschlag und um zu helfen, die Datei von anderen Dateiangeboten zu unterscheiden. Vor dem Absenden des Angebots wird der gesamte Pfad abgeschnitten. Du solltest dich vor versteckten Metadaten h\xfcten, die in der Datei selbst gespeichert sein k\xf6nnten, was je nach Dateiformat variiert. Zum Beispiel k\xf6nnen Bilder Geo-Lokationen und Informationen \xfcber die Kamera enthalten, die sie aufgenommen haben und PDF-Dateien sind daf\xfcr ber\xfcchtigt, versteckte Informationen wie den Namen des Autors oder die Maschine, auf der sie erstellt wurden, zu enthalten. Im Allgemeinen solltest du nur Dateien mit Leuten senden und empfangen, denen du vertraust."),(0,r.kt)("h2",{id:"kann-ich-dateien-automatisch-herunterladen"},"Kann ich Dateien automatisch herunterladen?"),(0,r.kt)("p",null,"Wenn das ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Bild-Vorschau und Profilbilder Experiment")," aktiviert ist, wird Cwtch automatisch Bilder von akzeptierten Unterhaltungen herunterladen."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0692a985.ebb8ca74.js b/build-staging/de/assets/js/0692a985.ebb8ca74.js new file mode 100644 index 00000000..204583f9 --- /dev/null +++ b/build-staging/de/assets/js/0692a985.ebb8ca74.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4228],{3905:(e,n,t)=>{t.d(n,{Zo:()=>h,kt:()=>m});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},h=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},d="mdxType",l={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,h=o(e,["components","mdxType","originalType","parentName"]),d=u(t),p=i,m=d["".concat(c,".").concat(p)]||d[p]||l[p]||a;return t?r.createElement(m,s(s({ref:n},h),{},{components:t})):r.createElement(m,s({ref:n},h))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,s=new Array(a);s[0]=p;var o={};for(var c in n)hasOwnProperty.call(n,c)&&(o[c]=n[c]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var u=2;u{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const a={sidebar_position:1},s="Cwtch Sicherheitshandbuch",o={unversionedId:"intro",id:"intro",title:"Cwtch Sicherheitshandbuch",description:"Willkommen im Cwtch Sicherheitshandbuch! Der Zweck dieses Handbuchs ist es, eine Anleitung f\xfcr die verschiedenen Komponenten des Cwtch \xd6kosystems zu liefern um die bekannten Risiken und Abschw\xe4chungen zu dokumentieren und Diskussionen \xfcber Verbesserungen und Aktualisierungen f\xfcr Cwtch sichere Entwicklungsprozesse zu erm\xf6glichen.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/intro.md",sourceDirName:".",slug:"/intro",permalink:"/de/security/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Risiko-Modell",permalink:"/de/security/risk"}},c={},u=[{value:"Was ist Cwtch?",id:"was-ist-cwtch",level:2},{value:"Eine (kurze) Geschichte des metadatenresistenten Chats",id:"eine-kurze-geschichte-des-metadatenresistenten-chats",level:2}],h={toc:u},d="wrapper";function l(e){let{components:n,...t}=e;return(0,i.kt)(d,(0,r.Z)({},h,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"cwtch-sicherheitshandbuch"},"Cwtch Sicherheitshandbuch"),(0,i.kt)("p",null,"Willkommen im Cwtch Sicherheitshandbuch! Der Zweck dieses Handbuchs ist es, eine Anleitung f\xfcr die verschiedenen Komponenten des Cwtch \xd6kosystems zu liefern um die bekannten Risiken und Abschw\xe4chungen zu dokumentieren und Diskussionen \xfcber Verbesserungen und Aktualisierungen f\xfcr Cwtch sichere Entwicklungsprozesse zu erm\xf6glichen."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/2.png",alt:null})),(0,i.kt)("h2",{id:"was-ist-cwtch"},"Was ist Cwtch?"),(0,i.kt)("p",null,'Cwtch (/k\u028at\u0283/ - ein walisisches Wort, das in etwa mit "eine Umarmung, die einen sicheren Ort schafft" \xfcbersetzt werden kann) ist ein dezentralisiertes, datenschutzfreundliches Mehrparteien-Nachrichtenprotokoll, das zum Aufbau metadatenresistenter Anwendungen verwendet werden kann.'),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Dezentralisiert und offen"),": Es gibt keinen \u201eCwtch-Dienst\u201c oder \u201eCwtch-Netzwerk\u201c. Die Cwtch Teilnehmer k\xf6nnen ihre eigenen sicheren R\xe4ume hosten oder ihre Infrastruktur anderen anbieten, die auf der Suche nach einem sicheren Raum sind. Das Cwtch-Protokoll ist offen und jeder kann Bots, Dienste und Benutzeroberfl\xe4chen erstellen und in Cwtch integrieren und interagieren."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Datenschutz wahrend"),": Alle Kommunikation in Cwtch ist Ende-zu-Ende verschl\xfcsselt und findet \xfcber Tor v3 onion Dienste statt."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Metadaten resistent"),": Cwtch wurde so konzipiert, dass ohne deine ausdr\xfcckliche Zustimmung keine Informationen ausgetauscht oder zug\xe4nglich sind einschlie\xdflich On-the-wire Nachrichten und Protokoll-Metadaten.")),(0,i.kt)("h2",{id:"eine-kurze-geschichte-des-metadatenresistenten-chats"},"Eine (kurze) Geschichte des metadatenresistenten Chats"),(0,i.kt)("p",null,"In den letzten Jahren ist das \xf6ffentliche Bewusstsein f\xfcr die Notwendigkeit und Vorteile von Ende-zu-Ende-verschl\xfcsselten L\xf6sungen mit Anwendungen wie ",(0,i.kt)("a",{parentName:"p",href:"https://signalapp.org"},"Signal"),", ",(0,i.kt)("a",{parentName:"p",href:"https://whatsapp.com"},"Whatsapp")," und ",(0,i.kt)("a",{parentName:"p",href:"https://wire.org"},"Wire")," gestiegen. Diese bieten Benutzern jetzt sichere Kommunikation."),(0,i.kt)("p",null,"Diese Werkzeuge ben\xf6tigen jedoch verschiedene Ebenen von Metadaten, um zu funktionieren und viele dieser Metadaten k\xf6nnen verwendet werden, um Details dar\xfcber zu erfahren, wie und warum eine Person ein Kommunikationstool nutzt. ",(0,i.kt)("a",{parentName:"p",href:"https://www.researchgate.net/profile/Peter_Kieseberg/publication/299984940_Privacy_and_data_protection_in_smartphone_messengers/links/5a1a9c29a6fdcc50adeb1335/Privacy-and-data-protection-in-smartphone-messengers.pdf"},"[rottermanner2015privacy]"),"."),(0,i.kt)("p",null,"Ein Werkzeug, das versucht hat, Metadaten zu reduzieren, ist ",(0,i.kt)("a",{parentName:"p",href:"https://ricochet.im"},"Ricochet")," welches 2014 zum ersten Mal ver\xf6ffentlicht wurde. Ricochet nutzte die Onion-Dienste von Tor v2, um eine sichere Ende-zu-Ende-verschl\xfcsselte Kommunikation zu gew\xe4hrleisten und die Metadaten der Kommunikation zu sch\xfctzen."),(0,i.kt)("p",null,"Es gab keine zentralisierten Server, die beim Routen von Ricochet Unterhaltungen helfen. Keine andere als die an einem Gespr\xe4ch beteiligten Parteien konnte wissen, dass ein solches Gespr\xe4ch stattfindet."),(0,i.kt)("p",null,"Ricochet war nicht ohne Einschr\xe4nkungen, es gab weder eine Multidevice Unterst\xfctzung noch einen Mechanismus zur Unterst\xfctzung der Gruppenkommunikation oder eine Unterst\xfctzung zum Senden von Nachrichten, w\xe4hrend ein Kontakt offline ist."),(0,i.kt)("p",null,"Dies machte die Annahme von Ricochet zu einer schwierigen Angelegenheit. selbst diejenigen in Umgebungen, die am besten von Metadatenresistenz profitieren w\xfcrden, wissen nicht, dass es ",(0,i.kt)("a",{parentName:"p",href:"https://www.academia.edu/download/53192589/ermoshina-12.pdf"},"[ermoshina2017can]")," gibt ",(0,i.kt)("a",{parentName:"p",href:"https://eprints.gla.ac.uk/116203/1/116203.pdf"},"[renaud2014doesn]"),"."),(0,i.kt)("p",null,"Dar\xfcber hinaus ist jede L\xf6sung f\xfcr dezentralisierte, metadatenresistente Kommunikation mit ",(0,i.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"grundlegenden Problemen")," konfrontiert, wenn es um Effizienz, Datenschutz und Gruppensicherheit geht (wie von ",(0,i.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"Konsens und Konsistenz der Transkription")," definiert)."),(0,i.kt)("p",null,"Moderne Alternativen zu Ricochet sind ",(0,i.kt)("a",{parentName:"p",href:"https://briarproject.org"},"Briar"),", ",(0,i.kt)("a",{parentName:"p",href:"https://www.zbay.app/"},"Zbay")," und ",(0,i.kt)("a",{parentName:"p",href:"https://www.ricochetrefresh.net/"},"Ricochet Refresh")," - Jedes Tool versucht, f\xfcr eine andere Reihe von Kompromissen zu optimieren, z. Briar m\xf6chte es Menschen erm\xf6glichen, ",(0,i.kt)("a",{parentName:"p",href:"https://briarproject.org/how-it-works/"},"auch dann zu kommunizieren, wenn die zugrunde liegende Netzwerkinfrastruktur ausgefallen ist"),", und bietet gleichzeitig Schutz vor Metadaten\xfcberwachung."),(0,i.kt)("hr",null),(0,i.kt)("p",null,"Das Cwtch-Projekt begann 2017 als ein Erweiterungsprotokoll f\xfcr Ricochet, das Gruppengespr\xe4che \xfcber nicht vertrauensw\xfcrdige Server, um dezentrale, metadatenresistente Anwendungen zu erm\xf6glichen (wie gemeinsame Listen und Bulletin Board)"),(0,i.kt)("p",null,"Eine Alpha-Version von Cwtch wurde ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/blog/2019/02/14/cwtch-alpha/"},"im Februar 2019 gestartet")," und seitdem hat das Cwtch-Team ( betrieben von der ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca"},"Open Privacy Research Society"),") Forschung und Entwicklung zu Cwtch und den zugrunde liegenden Protokollen und Bibliotheken und Problembereichen durchgef\xfchrt."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/07a1a58f.312624e8.js b/build-staging/de/assets/js/07a1a58f.312624e8.js new file mode 100644 index 00000000..8bfafebc --- /dev/null +++ b/build-staging/de/assets/js/07a1a58f.312624e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7460],{3905:(e,n,r)=>{r.d(n,{Zo:()=>u,kt:()=>m});var t=r(7294);function i(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function a(e){for(var n=1;n=0||(i[r]=e[r]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=t.createContext({}),c=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):a(a({},n),e)),r},u=function(e){var n=c(e.components);return t.createElement(l.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},h=t.forwardRef((function(e,n){var r=e.components,i=e.mdxType,s=e.originalType,l=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=c(r),h=i,m=p["".concat(l,".").concat(h)]||p[h]||d[h]||s;return r?t.createElement(m,a(a({ref:n},u),{},{components:r})):t.createElement(m,a({ref:n},u))}));function m(e,n){var r=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=r.length,a=new Array(s);a[0]=h;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[p]="string"==typeof e?e:i,a[1]=o;for(var c=2;c{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>c});var t=r(7462),i=(r(7294),r(3905));const s={sidebar_position:1},a="Cwtch technische Grundlagen",o={unversionedId:"components/intro",id:"components/intro",title:"Cwtch technische Grundlagen",description:"Diese Seite bietet einen kurzen technischen \xdcberblick \xfcber das Cwtch-Protokoll.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/intro.md",sourceDirName:"components",slug:"/components/intro",permalink:"/de/security/components/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Cwtch Components",permalink:"/de/security/category/cwtch-components"},next:{title:"Komponenten Ecosystem \xdcbersicht",permalink:"/de/security/components/ecosystem-overview"}},l={},c=[{value:"Ein Cwtch Profil",id:"ein-cwtch-profil",level:2},{value:"2-Parteien-Konversionen: Peer to Peer",id:"2-parteien-konversionen-peer-to-peer",level:2},{value:"Mehrparteien-Unterhaltungen: Gruppen und Kommunikation zwischen Peer to Server",id:"mehrparteien-unterhaltungen-gruppen-und-kommunikation-zwischen-peer-to-server",level:2},{value:"Server sind Peers",id:"server-sind-peers",level:3}],u={toc:c},p="wrapper";function d(e){let{components:n,...s}=e;return(0,i.kt)(p,(0,t.Z)({},u,s,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"cwtch-technische-grundlagen"},"Cwtch technische Grundlagen"),(0,i.kt)("p",null,"Diese Seite bietet einen kurzen technischen \xdcberblick \xfcber das Cwtch-Protokoll."),(0,i.kt)("h2",{id:"ein-cwtch-profil"},"Ein Cwtch Profil"),(0,i.kt)("p",null,"Benutzer k\xf6nnen eines von mehreren Cwtch Profilen erstellen. Jedes Profil erzeugt ein zuf\xe4lliges ed25519 Schl\xfcsselpaar, welches kompatibel mit Tor ist."),(0,i.kt)("p",null,"Zus\xe4tzlich zum kryptographischen Material enth\xe4lt ein Profil auch eine Liste von Kontakten (\xf6ffentliche Schl\xfcssel f\xfcr das Cwtch-Profil + zugeordnete Daten \xfcber dieses Profil wie Nickname und (optional) historische Nachrichten), eine Liste von Gruppen (mit kryptographischem Gruppenmaterial zus\xe4tzlich zu anderen zugeh\xf6rigen Daten wie dem Gruppennickname und historischen Nachrichten)."),(0,i.kt)("h2",{id:"2-parteien-konversionen-peer-to-peer"},"2-Parteien-Konversionen: Peer to Peer"),(0,i.kt)("p",null,(0,i.kt)("img",{src:r(7868).Z,width:"960",height:"540"})),(0,i.kt)("p",null,'Damit 2 Parteien ein Peer-to-Peer-Gespr\xe4ch f\xfchren k\xf6nnen, m\xfcssen beide online sein, aber nur eine Partei muss \xfcber ihren Onion-Dienst erreichbar sein. Um der Klarheit willen kennzeichnen wir oft eine Partei als den "eingehenden Peer" (die Person, die den Onion-Dienst beherbergt) und die andere Partei den "ausgehenden Peer" (der sich mit dem Onion-Dienst verbindet).'),(0,i.kt)("p",null,"Nach einer Verbindung beteiligen sich beide Seiten an einem -Authentifizierungsprotokoll von:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Behauptet, dass jede Partei Zugriff auf den privaten Schl\xfcssel hat, der mit ihrer \xf6ffentlichen Identit\xe4t verbunden ist."),(0,i.kt)("li",{parentName:"ul"},"Erzeugt einen kurzlebigen Sitzungs-Schl\xfcssel, der zur Verschl\xfcsselung aller weiteren Kommunikation w\xe4hrend der Sitzung verwendet wird.")),(0,i.kt)("p",null,"Dieser Austausch (detailliert im ",(0,i.kt)("a",{parentName:"p",href:"/de/security/components/tapir/authentication_protocol"},"-Authentifizierungsprotokoll"),"dokumentiert) ist ",(0,i.kt)("em",{parentName:"p"},"offline verweigerbar")," d. h. es ist m\xf6glich f\xfcr jede Seite Transkripte dieses Protokoll-Austausches zu f\xe4lschen und daher ist es unm\xf6glich definitiv zu beweisen, dass der Austausch \xfcberhaupt stattgefunden hat."),(0,i.kt)("p",null,"Nach dem Authentifizierungsprotokoll k\xf6nnen beide Parteien frei miteinander kommunizieren."),(0,i.kt)("h2",{id:"mehrparteien-unterhaltungen-gruppen-und-kommunikation-zwischen-peer-to-server"},"Mehrparteien-Unterhaltungen: Gruppen und Kommunikation zwischen Peer to Server"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Hinweis: Metadaten resistente Kommunikation ist noch ein aktives Entwicklungsfeld und was hier dokumentiert ist wird sehr wahrscheinlich in der Zukunft sich \xe4ndern.")),(0,i.kt)("p",null,"Wenn eine Person eine Gruppendiskussion starten m\xf6chte, generiert sie einen zuf\xe4lligen geheimen ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel"),". Alle Gruppenkommunikation wird mit diesem Schl\xfcssel verschl\xfcsselt."),(0,i.kt)("p",null,"Zusammen mit dem ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel")," entscheidet der Gruppenersteller sich auch f\xfcr einen ",(0,i.kt)("strong",{parentName:"p"},"Cwtch Server")," als Host der Gruppe zu verwenden. Weitere Informationen dar\xfcber, wie Server sich selbst authentifizieren, findest du unter ",(0,i.kt)("a",{parentName:"p",href:"/de/security/components/cwtch/key_bundles"},"Schl\xfcsselb\xfcndel"),"."),(0,i.kt)("p",null,"Ein ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppen Identifikator")," wird mit dem Gruppenschl\xfcssel und dem Gruppenserver generiert und diese drei Elemente sind in einer Einladung verpackt, die an potenzielle Gruppenmitglieder gesendet werden kann (z.B. \xfcber existierende Peer-to-Peer-Verbindungen)."),(0,i.kt)("p",null,"Um eine Nachricht an die Gruppe zu senden, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt (siehe unten), und verschl\xfcsselt deine Nachricht mit dem ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel")," und erzeugt eine kryptographische Signatur \xfcber die ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppen-Id"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppen Server")," und die entschl\xfcsselte Nachricht (siehe: ",(0,i.kt)("a",{parentName:"p",href:"/de/security/components/cwtch/message_formats"},"Nachrichtenformate")," f\xfcr weitere Informationen)."),(0,i.kt)("p",null,"Um Nachrichten von der Gruppe zu erhalten, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt und l\xe4dt ",(0,i.kt)("em",{parentName:"p"},"alle")," Nachrichten (seit seiner vorherigen Verbindung) herunter. Die Profile versuchen dann jede Nachricht mit dem ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel")," zu entschl\xfcsseln und wenn dies erfolgreich war, dann die Signatur zu verifizieren (siehe ",(0,i.kt)("a",{parentName:"p",href:"/de/security/components/cwtch/server"},"Cwtch Server")," ",(0,i.kt)("a",{parentName:"p",href:"/de/security/components/cwtch/groups"},"Cwtch Gruppen")," f\xfcr einen \xdcberblick \xfcber Attacken und Abschw\xe4chungen)."),(0,i.kt)("h3",{id:"server-sind-peers"},"Server sind Peers"),(0,i.kt)("p",null,"In vielerlei Hinsicht ist die Kommunikation mit einem Server identisch mit einer regul\xe4ren Cwtch Gegenstelle, die gleichen Schritte oben werden durchgef\xfchrt, aber der Server fungiert immer als eingehender Peer, und der ausgehende Peer verwendet immer neu generierte ",(0,i.kt)("strong",{parentName:"p"},"kurzlebige Schl\xfcsselpaare"),' als "Langfristige Identit\xe4t".'),(0,i.kt)("p",null,"Somit unterscheidet sich die Peer zu Server Konversation nur in der ",(0,i.kt)("em",{parentName:"p"},"Art")," der Nachrichten, die zwischen zwei Seiten gesendet werden, mit dem Server, der alle Nachrichten, die er erh\xe4lt, weiterleitet und au\xdferdem den Clients erlaubt den Server nach \xe4lteren Nachrichten abzufragen."))}d.isMDXComponent=!0},7868:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0831902b.07b29433.js b/build-staging/de/assets/js/0831902b.07b29433.js new file mode 100644 index 00000000..4395fbff --- /dev/null +++ b/build-staging/de/assets/js/0831902b.07b29433.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8932],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>v});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,s=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(r),m=i,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||s;return r?n.createElement(v,a(a({ref:t},p),{},{components:r})):n.createElement(v,a({ref:t},p))}));function v(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=r.length,a=new Array(s);a[0]=m;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[u]="string"==typeof e?e:i,a[1]=o;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const s={sidebar_position:5},a="Wie du dein Server-Schl\xfcsselpaket teilst",o={unversionedId:"servers/share-key",id:"servers/share-key",title:"Wie du dein Server-Schl\xfcsselpaket teilst",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/share-key.md",sourceDirName:"servers",slug:"/servers/share-key",permalink:"/de/docs/servers/share-key",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/share-key.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Wie man einen Server l\xf6scht",permalink:"/de/docs/servers/delete-server"},next:{title:"Wie man einen Server entsperrt",permalink:"/de/docs/servers/unlock-server"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"wie-du-dein-server-schl\xfcsselpaket-teilst"},"Wie du dein Server-Schl\xfcsselpaket teilst"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," eingeschaltet ist.")),(0,i.kt)("p",null,"Dein Server-Schl\xfcsselb\xfcndel ist das Datenpaket, das eine Cwtch-App ben\xf6tigt, um einen Server nutzen zu k\xf6nnen. Wenn du nur andere Cwtch-Benutzer auf deinen Server aufmerksam machen m\xf6chtest, kannst du dies mit ihnen teilen. Dann haben sie die M\xf6glichkeit, eigene Gruppen auf dem Server zu erstellen."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zum Server-Symbol gehen"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle den gew\xfcnschten Server aus"),(0,i.kt)("li",{parentName:"ol"},"Benutze das Kopier-Adressen-Symbol um die Server-Schl\xfcssel zu kopieren"),(0,i.kt)("li",{parentName:"ol"},"Teile die Schl\xfcssel nicht mit Leuten, denen du nicht vertraust")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Server_Keys.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0861b93e.20851427.js b/build-staging/de/assets/js/0861b93e.20851427.js new file mode 100644 index 00000000..af83900f --- /dev/null +++ b/build-staging/de/assets/js/0861b93e.20851427.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2287],{3208:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/support","page":1,"postsPerPage":10,"totalPages":1,"totalCount":3,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0bd16fd2.cc975847.js b/build-staging/de/assets/js/0bd16fd2.cc975847.js new file mode 100644 index 00000000..eea70cbb --- /dev/null +++ b/build-staging/de/assets/js/0bd16fd2.cc975847.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6419],{2738:e=>{e.exports=JSON.parse('{"label":"developer-documentation","permalink":"/de/blog/tags/developer-documentation","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0c915b16.73cbc157.js b/build-staging/de/assets/js/0c915b16.73cbc157.js new file mode 100644 index 00000000..4c24345c --- /dev/null +++ b/build-staging/de/assets/js/0c915b16.73cbc157.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2833],{6317:e=>{e.exports=JSON.parse('{"label":"cwtch","permalink":"/de/blog/tags/cwtch","allTagsPath":"/de/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0d64c1d9.74653bc5.js b/build-staging/de/assets/js/0d64c1d9.74653bc5.js new file mode 100644 index 00000000..9d65ba21 --- /dev/null +++ b/build-staging/de/assets/js/0d64c1d9.74653bc5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8710],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>b});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):r(r({},t),e)),i},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(i),h=a,b=p["".concat(s,".").concat(h)]||p[h]||u[h]||o;return i?n.createElement(b,r(r({ref:t},d),{},{components:i})):n.createElement(b,r({ref:t},d))}));function b(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=i.length,r=new Array(o);r[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=i(7462),a=(i(7294),i(3905));const o={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/de/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"20. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/de/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"repliqate",permalink:"/de/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/de/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/de/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"How Cwtch Bindings are Built",id:"how-cwtch-bindings-are-built",level:2},{value:"Making libCwtch Reproducible",id:"making-libcwtch-reproducible",level:2},{value:"Linux Specific Considerations",id:"linux-specific-considerations",level:3},{value:"Windows Specific Considerations",id:"windows-specific-considerations",level:3},{value:"Android Specific Considerations",id:"android-specific-considerations",level:3},{value:"OSX Specific Considerations",id:"osx-specific-considerations",level:3},{value:"Introducing Repliqate!",id:"introducing-repliqate",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...o}=e;return(0,a.kt)(p,(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,a.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,a.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,a.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,a.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."),(0,a.kt)("h2",{id:"how-cwtch-bindings-are-built"},"How Cwtch Bindings are Built"),(0,a.kt)("p",null,"Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process."),(0,a.kt)("p",null,"When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms."),(0,a.kt)("p",null,"The Cwtch Bindings build pipeline results in four compiled libraries:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.so")," \u2013 For Linux Platforms, built using the ",(0,a.kt)("a",{parentName:"li",href:"https://hub.docker.com/_/golang"},"official golang:1.19.X Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.dll")," \u2013 For Windows Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/mingw-go"},"mingw-go Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.ld")," \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"cwtch.aar")," \u2013 For Android Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/android-go-mobile"},"Android/GoMobile Docker Image"))),(0,a.kt)("p",null,"These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI."),(0,a.kt)("h2",{id:"making-libcwtch-reproducible"},"Making libCwtch Reproducible"),(0,a.kt)("p",null,"Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Go Build ID"),": By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Build Paths and Go Environment Variables"),": By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimPath")," option, which we now specify for all bindings builds.")),(0,a.kt)("h3",{id:"linux-specific-considerations"},"Linux Specific Considerations"),(0,a.kt)("p",null,"After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against."),(0,a.kt)("p",null,"Our Drone/Docker build environments are based on ",(0,a.kt)("a",{parentName:"p",href:"https://www.debian.org/releases/bullseye/"},"Debian Bullseye")," which provides ",(0,a.kt)("a",{parentName:"p",href:"https://packages.debian.org/bullseye/i386/libc6-dev"},"libc6-dev version 2.31"),". Other development setups will likely link libc-dev 2.34+."),(0,a.kt)("p",null,"libc6-dev 2.34 is notable ",(0,a.kt)("a",{parentName:"p",href:"https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread"},"because it removed dependencies on libpthread and libdl")," \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file."),(0,a.kt)("p",null,"This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on ",(0,a.kt)("a",{parentName:"p",href:"#next-steps"},"Next Steps")," for more information)."),(0,a.kt)("h3",{id:"windows-specific-considerations"},"Windows Specific Considerations"),(0,a.kt)("p",null,"The headers of PE files technically contain a timestamp field. In recent years an ",(0,a.kt)("a",{parentName:"p",href:"https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705"},"effort has been made to use this field for other purposes"),", but by default ",(0,a.kt)("inlineCode",{parentName:"p"},"go build")," will still include the timestamp of the file when producing a DLL file (at least when using CGO)."),(0,a.kt)("p",null,"Fortunately this field can be zeroed out through passing ",(0,a.kt)("inlineCode",{parentName:"p"},"-Xlinker \u2013no-insert-timestamp")," into the ",(0,a.kt)("inlineCode",{parentName:"p"},"mingw32-gcc")," process."),(0,a.kt)("p",null,"With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment."),(0,a.kt)("h3",{id:"android-specific-considerations"},"Android Specific Considerations"),(0,a.kt)("p",null,"With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Cwtch makes use of ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/golang/mobile"},"GoMobile")," for compiling Android libraries. We pin to a specific version ",(0,a.kt)("inlineCode",{parentName:"li"},"43a0384520996c8376bfb8637390f12b44773e65")," in our Docker containers. Unlike ",(0,a.kt)("inlineCode",{parentName:"li"},"go build"),", the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimpPath")," parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized ",(0,a.kt)("inlineCode",{parentName:"li"},"/tmp/go-build*")," references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced."),(0,a.kt)("li",{parentName:"ul"},"We still use ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/releases/sdk-tools"},"sdk-tools")," instead of the new ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/command-line"},"commandline-tools"),". The latest version of sdk-tools is ",(0,a.kt)("inlineCode",{parentName:"li"},"4333796")," and available from: ",(0,a.kt)("a",{parentName:"li",href:"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"},"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"),". As part of our plans for Cwtch Stable we will be updating this dependency."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated ",(0,a.kt)("inlineCode",{parentName:"li"},"openjdk:8")," image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. ")),(0,a.kt)("p",null,"All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles."),(0,a.kt)("h3",{id:"osx-specific-considerations"},"OSX Specific Considerations"),(0,a.kt)("p",null,"Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds."),(0,a.kt)("p",null,"As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine."),(0,a.kt)("p",null,"In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1."),(0,a.kt)("p",null,"In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a ",(0,a.kt)("a",{parentName:"p",href:"https://www.apple.com/legal/sla/docs/xcode.pdf"},"proprietary SDK"),". There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware."),(0,a.kt)("p",null,"Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions."),(0,a.kt)("h2",{id:"introducing-repliqate"},"Introducing Repliqate!"),(0,a.kt)("p",null,"With all the above changes, ",(0,a.kt)("strong",{parentName:"p"},"Cwtch Bindings for Linux and Windows are fully reproducible!")),(0,a.kt)("p",null,"That alone is great, but we also want to make it easier for ",(0,a.kt)("strong",{parentName:"p"},"you")," to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team."),(0,a.kt)("p",null,"To make this process accessible we are releasing a new tool called ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate"),"."),(0,a.kt)("p",null,"Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution."),(0,a.kt)("p",null,"Repliqate runs ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script"},"build-scripts")," to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"builds.openprivacy.ca"),"."),(0,a.kt)("p",null,"We now provide ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"Repliqate build-scripts")," for reproducible both ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script"},"Linux libCwtch.so builds"),", ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script"},"Windows libCwtch.dll builds"),"!"),(0,a.kt)("p",null,"We also have a partially repeatable ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script"},"Android cwtch.aar build")," script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section."),(0,a.kt)("p",null,"You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings."),(0,a.kt)("p",null,"As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!"),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4515:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0eb0d69b.26f61e30.js b/build-staging/de/assets/js/0eb0d69b.26f61e30.js new file mode 100644 index 00000000..14f94227 --- /dev/null +++ b/build-staging/de/assets/js/0eb0d69b.26f61e30.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1725],{7483:e=>{e.exports=JSON.parse('{"label":"nightly","permalink":"/de/blog/tags/nightly","allTagsPath":"/de/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/0f04f840.97f5d109.js b/build-staging/de/assets/js/0f04f840.97f5d109.js new file mode 100644 index 00000000..41520aaf --- /dev/null +++ b/build-staging/de/assets/js/0f04f840.97f5d109.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1118],{3099:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/repliqate","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/113ce370.ee3364d0.js b/build-staging/de/assets/js/113ce370.ee3364d0.js new file mode 100644 index 00000000..368a74cb --- /dev/null +++ b/build-staging/de/assets/js/113ce370.ee3364d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7216],{3279:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/release","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/12959a59.7fe15889.js b/build-staging/de/assets/js/12959a59.7fe15889.js new file mode 100644 index 00000000..88e6c6b9 --- /dev/null +++ b/build-staging/de/assets/js/12959a59.7fe15889.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3249],{7097:e=>{e.exports=JSON.parse('{"title":"Cwtch","slug":"/category/cwtch","permalink":"/de/security/category/cwtch","navigation":{"previous":{"title":"Authentifizierungsprotokoll","permalink":"/de/security/components/tapir/authentication_protocol"},"next":{"title":"Nachrichtenformate","permalink":"/de/security/components/cwtch/message_formats"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/141cdfa9.087acaed.js b/build-staging/de/assets/js/141cdfa9.087acaed.js new file mode 100644 index 00000000..590bb2cd --- /dev/null +++ b/build-staging/de/assets/js/141cdfa9.087acaed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7293],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(a),m=n,h=u["".concat(c,".").concat(m)]||u[m]||f[m]||i;return a?r.createElement(h,o(o({ref:t},p),{},{components:a})):r.createElement(h,o({ref:t},p))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=a.length,o=new Array(i);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const i={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"6. April 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/de/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/de/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/de/blog/cwtch-stable-roadmap-update"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},u="wrapper";function f(e){let{components:t,...a}=e;return(0,n.kt)(u,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,n.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,n.kt)("p",null,"The Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/14eb3368.5ac78d9e.js b/build-staging/de/assets/js/14eb3368.5ac78d9e.js new file mode 100644 index 00000000..b466bfa7 --- /dev/null +++ b/build-staging/de/assets/js/14eb3368.5ac78d9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9817],{1310:(e,t,a)=>{a.d(t,{Z:()=>E});var n=a(7462),r=a(7294),i=a(6010),l=a(5281),s=a(2802),c=a(8596),o=a(9960),m=a(5999),d=a(4996);function u(e){return r.createElement("svg",(0,n.Z)({viewBox:"0 0 24 24"},e),r.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const h={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,d.Z)("/");return r.createElement("li",{className:"breadcrumbs__item"},r.createElement(o.Z,{"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},r.createElement(u,{className:h.breadcrumbHomeIcon})))}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g(e){let{children:t,href:a,isLast:n}=e;const i="breadcrumbs__link";return n?r.createElement("span",{className:i,itemProp:"name"},t):a?r.createElement(o.Z,{className:i,href:a,itemProp:"item"},r.createElement("span",{itemProp:"name"},t)):r.createElement("span",{className:i},t)}function p(e){let{children:t,active:a,index:l,addMicrodata:s}=e;return r.createElement("li",(0,n.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,i.Z)("breadcrumbs__item",{"breadcrumbs__item--active":a})}),t,r.createElement("meta",{itemProp:"position",content:String(l+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?r.createElement("nav",{className:(0,i.Z)(l.k.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},r.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&r.createElement(b,null),e.map(((t,a)=>{const n=a===e.length-1;return r.createElement(p,{key:a,active:n,index:a,addMicrodata:!!t.href},r.createElement(g,{href:t.href,isLast:n},t.label))})))):null}},4228:(e,t,a)=>{a.r(t),a.d(t,{default:()=>y});var n=a(7294),r=a(1944),i=a(2802),l=a(4996),s=a(6010),c=a(9960),o=a(3919),m=a(5999);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:a}=e;return n.createElement(c.Z,{href:t,className:(0,s.Z)("card padding--lg",d.cardContainer)},a)}function h(e){let{href:t,icon:a,title:r,description:i}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,s.Z)("text--truncate",d.cardTitle),title:r},a," ",r),i&&n.createElement("p",{className:(0,s.Z)("text--truncate",d.cardDescription),title:i},i))}function b(e){let{item:t}=e;const a=(0,i.Wl)(t);return a?n.createElement(h,{href:a,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,m.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const a=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return n.createElement(h,{href:t.href,icon:a,title:t.label,description:t.description??r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(v,{item:t});case"category":return n.createElement(b,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function p(e){let{className:t}=e;const a=(0,i.jA)();return n.createElement(E,{items:a.items,className:t})}function E(e){const{items:t,className:a}=e;if(!t)return n.createElement(p,e);const r=(0,i.MN)(t);return n.createElement("section",{className:(0,s.Z)("row",a)},r.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}var f=a(49),N=a(3120),Z=a(4364),k=a(1310),_=a(2503);const L={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function T(e){let{categoryGeneratedIndex:t}=e;return n.createElement(r.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,l.Z)(t.image)})}function x(e){let{categoryGeneratedIndex:t}=e;const a=(0,i.jA)();return n.createElement("div",{className:L.generatedIndexPage},n.createElement(N.Z,null),n.createElement(k.Z,null),n.createElement(Z.Z,null),n.createElement("header",null,n.createElement(_.Z,{as:"h1",className:L.title},t.title),t.description&&n.createElement("p",null,t.description)),n.createElement("article",{className:"margin-top--lg"},n.createElement(E,{items:a.items,className:L.list})),n.createElement("footer",{className:"margin-top--lg"},n.createElement(f.Z,{previous:t.navigation.previous,next:t.navigation.next})))}function y(e){return n.createElement(n.Fragment,null,n.createElement(T,e),n.createElement(x,e))}},49:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7462),r=a(7294),i=a(5999),l=a(2244);function s(e){const{previous:t,next:a}=e;return r.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,i.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&r.createElement(l.Z,(0,n.Z)({},t,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),a&&r.createElement(l.Z,(0,n.Z)({},a,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,a)=>{a.d(t,{Z:()=>c});var n=a(7294),r=a(6010),i=a(5999),l=a(5281),s=a(4477);function c(e){let{className:t}=e;const a=(0,s.E)();return a.badge?n.createElement("span",{className:(0,r.Z)(t,l.k.docs.docVersionBadge,"badge badge--secondary")},n.createElement(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:a.label}},"Version: {versionLabel}")):null}},3120:(e,t,a)=>{a.d(t,{Z:()=>g});var n=a(7294),r=a(6010),i=a(2263),l=a(9960),s=a(5999),c=a(143),o=a(5281),m=a(373),d=a(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function h(e){const t=u[e.versionMetadata.banner];return n.createElement(t,e)}function b(e){let{versionLabel:t,to:a,onClick:r}=e;return n.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:n.createElement("b",null,n.createElement(l.Z,{to:a,onClick:r},n.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function v(e){let{className:t,versionMetadata:a}=e;const{siteConfig:{title:l}}=(0,i.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,m.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:v}=(0,c.Jo)(s),g=u??(p=v).docs.find((e=>e.id===p.mainDocId));var p;return n.createElement("div",{className:(0,r.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},n.createElement("div",null,n.createElement(h,{siteTitle:l,versionMetadata:a})),n.createElement("div",{className:"margin-top--md"},n.createElement(b,{versionLabel:v.label,to:g.path,onClick:()=>d(v.name)})))}function g(e){let{className:t}=e;const a=(0,d.E)();return a.banner?n.createElement(v,{className:t,versionMetadata:a}):null}},2503:(e,t,a)=>{a.d(t,{Z:()=>m});var n=a(7462),r=a(7294),i=a(6010),l=a(5999),s=a(6668),c=a(9960);const o={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function m(e){let{as:t,id:a,...m}=e;const{navbar:{hideOnScroll:d}}=(0,s.L)();if("h1"===t||!a)return r.createElement(t,(0,n.Z)({},m,{id:void 0}));const u=(0,l.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof m.children?m.children:a});return r.createElement(t,(0,n.Z)({},m,{className:(0,i.Z)("anchor",d?o.anchorWithHideOnScrollNavbar:o.anchorWithStickyNavbar,m.className),id:a}),m.children,r.createElement(c.Z,{className:"hash-link",to:`#${a}`,"aria-label":u,title:u},"\u200b"))}},2244:(e,t,a)=>{a.d(t,{Z:()=>l});var n=a(7294),r=a(6010),i=a(9960);function l(e){const{permalink:t,title:a,subLabel:l,isNext:s}=e;return n.createElement(i.Z,{className:(0,r.Z)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},l&&n.createElement("div",{className:"pagination-nav__sublabel"},l),n.createElement("div",{className:"pagination-nav__label"},a))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/15c93cf0.d9154bf1.js b/build-staging/de/assets/js/15c93cf0.d9154bf1.js new file mode 100644 index 00000000..69b34f24 --- /dev/null +++ b/build-staging/de/assets/js/15c93cf0.d9154bf1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7970],{9712:e=>{e.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable","allTagsPath":"/de/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/16771999.1ff393da.js b/build-staging/de/assets/js/16771999.1ff393da.js new file mode 100644 index 00000000..f506e774 --- /dev/null +++ b/build-staging/de/assets/js/16771999.1ff393da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3271],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>f});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function c(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=r.createContext({}),s=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},l=function(e){var n=s(e.components);return r.createElement(p.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},g=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,c=e.originalType,p=e.parentName,l=o(e,["components","mdxType","originalType","parentName"]),u=s(t),g=a,f=u["".concat(p,".").concat(g)]||u[g]||d[g]||c;return t?r.createElement(f,i(i({ref:n},l),{},{components:t})):r.createElement(f,i({ref:n},l))}));function f(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var c=t.length,i=new Array(c);i[0]=g;var o={};for(var p in n)hasOwnProperty.call(n,p)&&(o[p]=n[p]);o.originalType=e,o[u]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>s});var r=t(7462),a=(t(7294),t(3905));const c={sidebar_position:1},i="Sprache wechseln",o={unversionedId:"settings/appearance/change-language",id:"settings/appearance/change-language",title:"Sprache wechseln",description:"Dank der Hilfe von Freiwilligenwurde die Cwtch-App in viele Sprachen \xfcbersetzt.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/change-language.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/change-language",permalink:"/de/docs/settings/appearance/change-language",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/change-language.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Appearance",permalink:"/de/docs/category/appearance"},next:{title:"Helles/Dunkles Design und Theme-Aufteilung",permalink:"/de/docs/settings/appearance/light-dark-mode"}},p={},s=[],l={toc:s},u="wrapper";function d(e){let{components:n,...t}=e;return(0,a.kt)(u,(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"sprache-wechseln"},"Sprache wechseln"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"Dank der Hilfe von Freiwilligen"),"wurde die Cwtch-App in viele Sprachen \xfcbersetzt."),(0,a.kt)("p",null,"Um die in Cwtch verwendete Sprache zu \xe4ndern:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Einstellungen \xf6ffnen"),(0,a.kt)("li",{parentName:"ol"},'Die oberste Einstellung ist "Sprache", Du kannst das Drop-Down-Men\xfc benutzen, um die Sprache auszuw\xe4hlen, die Du verwenden m\xf6chtest.')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/17896441.27340309.js b/build-staging/de/assets/js/17896441.27340309.js new file mode 100644 index 00000000..d1e2980a --- /dev/null +++ b/build-staging/de/assets/js/17896441.27340309.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7918],{1310:(e,t,n)=>{n.d(t,{Z:()=>E});var a=n(7462),l=n(7294),o=n(6010),r=n(5281),s=n(2802),c=n(8596),i=n(9960),d=n(5999),m=n(4996);function u(e){return l.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},e),l.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const v={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,m.Z)("/");return l.createElement("li",{className:"breadcrumbs__item"},l.createElement(i.Z,{"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},l.createElement(u,{className:v.breadcrumbHomeIcon})))}const p={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function h(e){let{children:t,href:n,isLast:a}=e;const o="breadcrumbs__link";return a?l.createElement("span",{className:o,itemProp:"name"},t):n?l.createElement(i.Z,{className:o,href:n,itemProp:"item"},l.createElement("span",{itemProp:"name"},t)):l.createElement("span",{className:o},t)}function f(e){let{children:t,active:n,index:r,addMicrodata:s}=e;return l.createElement("li",(0,a.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,o.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n})}),t,l.createElement("meta",{itemProp:"position",content:String(r+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?l.createElement("nav",{className:(0,o.Z)(r.k.docs.docBreadcrumbs,p.breadcrumbsContainer),"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},l.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&l.createElement(b,null),e.map(((t,n)=>{const a=n===e.length-1;return l.createElement(f,{key:n,active:a,index:n,addMicrodata:!!t.href},l.createElement(h,{href:t.href,isLast:a},t.label))})))):null}},5154:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});var a=n(7294),l=n(1944),o=n(902);const r=a.createContext(null);function s(e){let{children:t,content:n}=e;const l=function(e){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return a.createElement(r.Provider,{value:l},t)}function c(){const e=(0,a.useContext)(r);if(null===e)throw new o.i6("DocProvider");return e}function i(){const{metadata:e,frontMatter:t,assets:n}=c();return a.createElement(l.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var d=n(6010),m=n(7524),u=n(49);function v(){const{metadata:e}=c();return a.createElement(u.Z,{previous:e.previous,next:e.next})}var b=n(3120),p=n(4364),h=n(5281),f=n(5999);function E(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:a.createElement("b",null,a.createElement("time",{dateTime:new Date(1e3*t).toISOString()},n))}}," on {date}")}function g(e){let{lastUpdatedBy:t}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:a.createElement("b",null,t)}}," by {user}")}function L(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:l}=e;return a.createElement("span",{className:h.k.common.lastUpdated},a.createElement(f.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?a.createElement(E,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:l?a.createElement(g,{lastUpdatedBy:l}):""}},"Last updated{atDate}{byUser}"),!1)}var C=n(4881),N=n(1526);const Z={lastUpdated:"lastUpdated_vwxv"};function k(e){return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterTagsRow,"row margin-bottom--sm")},a.createElement("div",{className:"col"},a.createElement(N.Z,e)))}function _(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:l,formattedLastUpdatedAt:o}=e;return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterEditMetaRow,"row")},a.createElement("div",{className:"col"},t&&a.createElement(C.Z,{editUrl:t})),a.createElement("div",{className:(0,d.Z)("col",Z.lastUpdated)},(n||l)&&a.createElement(L,{lastUpdatedAt:n,formattedLastUpdatedAt:o,lastUpdatedBy:l})))}function x(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:l,lastUpdatedBy:o,tags:r}=e,s=r.length>0,i=!!(t||n||o);return s||i?a.createElement("footer",{className:(0,d.Z)(h.k.docs.docFooter,"docusaurus-mt-lg")},s&&a.createElement(k,{tags:r}),i&&a.createElement(_,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:o,formattedLastUpdatedAt:l})):null}var T=n(6043),H=n(3743),U=n(7462);const y={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function A(e){let{collapsed:t,...n}=e;return a.createElement("button",(0,U.Z)({type:"button"},n,{className:(0,d.Z)("clean-btn",y.tocCollapsibleButton,!t&&y.tocCollapsibleButtonExpanded,n.className)}),a.createElement(f.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component"},"On this page"))}const w={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function M(e){let{toc:t,className:n,minHeadingLevel:l,maxHeadingLevel:o}=e;const{collapsed:r,toggleCollapsed:s}=(0,T.u)({initialState:!0});return a.createElement("div",{className:(0,d.Z)(w.tocCollapsible,!r&&w.tocCollapsibleExpanded,n)},a.createElement(A,{collapsed:r,onClick:s}),a.createElement(T.z,{lazy:!0,className:w.tocCollapsibleContent,collapsed:r},a.createElement(H.Z,{toc:t,minHeadingLevel:l,maxHeadingLevel:o})))}const I={tocMobile:"tocMobile_ITEo"};function B(){const{toc:e,frontMatter:t}=c();return a.createElement(M,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,d.Z)(h.k.docs.docTocMobile,I.tocMobile)})}var O=n(9407);function S(){const{toc:e,frontMatter:t}=c();return a.createElement(O.Z,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:h.k.docs.docTocDesktop})}var V=n(2503),P=n(1506);function D(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return a.createElement("div",{className:(0,d.Z)(h.k.docs.docMarkdown,"markdown")},n&&a.createElement("header",null,a.createElement(V.Z,{as:"h1"},n)),a.createElement(P.Z,null,t))}var R=n(1310);const F={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function z(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),l=e.hide_table_of_contents,o=!l&&t.length>0;return{hidden:l,mobile:o?a.createElement(B,null):void 0,desktop:!o||"desktop"!==n&&"ssr"!==n?void 0:a.createElement(S,null)}}();return a.createElement("div",{className:"row"},a.createElement("div",{className:(0,d.Z)("col",!n.hidden&&F.docItemCol)},a.createElement(b.Z,null),a.createElement("div",{className:F.docItemContainer},a.createElement("article",null,a.createElement(R.Z,null),a.createElement(p.Z,null),n.mobile,a.createElement(D,null,t),a.createElement(x,null)),a.createElement(v,null))),n.desktop&&a.createElement("div",{className:"col col--3"},n.desktop))}function j(e){const t=`docs-doc-id-${e.content.metadata.unversionedId}`,n=e.content;return a.createElement(s,{content:e.content},a.createElement(l.FG,{className:t},a.createElement(i,null),a.createElement(z,null,a.createElement(n,null))))}},49:(e,t,n)=>{n.d(t,{Z:()=>s});var a=n(7462),l=n(7294),o=n(5999),r=n(2244);function s(e){const{previous:t,next:n}=e;return l.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,o.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&l.createElement(r.Z,(0,a.Z)({},t,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),n&&l.createElement(r.Z,(0,a.Z)({},n,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,n)=>{n.d(t,{Z:()=>c});var a=n(7294),l=n(6010),o=n(5999),r=n(5281),s=n(4477);function c(e){let{className:t}=e;const n=(0,s.E)();return n.badge?a.createElement("span",{className:(0,l.Z)(t,r.k.docs.docVersionBadge,"badge badge--secondary")},a.createElement(o.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label}},"Version: {versionLabel}")):null}},3120:(e,t,n)=>{n.d(t,{Z:()=>h});var a=n(7294),l=n(6010),o=n(2263),r=n(9960),s=n(5999),c=n(143),i=n(5281),d=n(373),m=n(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function v(e){const t=u[e.versionMetadata.banner];return a.createElement(t,e)}function b(e){let{versionLabel:t,to:n,onClick:l}=e;return a.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:a.createElement("b",null,a.createElement(r.Z,{to:n,onClick:l},a.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function p(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:r}}=(0,o.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:m}=(0,d.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:p}=(0,c.Jo)(s),h=u??(f=p).docs.find((e=>e.id===f.mainDocId));var f;return a.createElement("div",{className:(0,l.Z)(t,i.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},a.createElement("div",null,a.createElement(v,{siteTitle:r,versionMetadata:n})),a.createElement("div",{className:"margin-top--md"},a.createElement(b,{versionLabel:p.label,to:h.path,onClick:()=>m(p.name)})))}function h(e){let{className:t}=e;const n=(0,m.E)();return n.banner?a.createElement(p,{className:t,versionMetadata:n}):null}},9407:(e,t,n)=>{n.d(t,{Z:()=>d});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",i="table-of-contents__link--active";function d(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(s.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:i})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>b});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function s(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=s({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function m(e){const t=(0,l.useRef)(void 0),n=d();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=i(s,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===d)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const v=l.memo(u);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:d,maxHeadingLevel:u,...b}=e;const p=(0,o.L)(),h=d??p.tableOfContents.minHeadingLevel,f=u??p.tableOfContents.maxHeadingLevel,E=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>s({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:h,maxHeadingLevel:f});return m((0,l.useMemo)((()=>{if(c&&i)return{linkClassName:c,linkActiveClassName:i,minHeadingLevel:h,maxHeadingLevel:f}}),[c,i,h,f])),l.createElement(v,(0,a.Z)({toc:E,className:n,linkClassName:c},b))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/18aaeea6.de5edb8b.js b/build-staging/de/assets/js/18aaeea6.de5edb8b.js new file mode 100644 index 00000000..618717c2 --- /dev/null +++ b/build-staging/de/assets/js/18aaeea6.de5edb8b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6354],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=i,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(m,o(o({ref:t},l),{},{components:n})):r.createElement(m,o({ref:t},l))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:3},o="Dateifreigabe",s={unversionedId:"settings/experiments/file-sharing",id:"settings/experiments/file-sharing",title:"Dateifreigabe",description:'Diese Einstellung aktiviert Cwtch Dateisharing-Funktionalit\xe4t. Dies zeigt die Option "Datei teilen" im Konversationsbereich an und erlaubt dir Dateien von Konversationen herunterzuladen.',source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/file-sharing.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/file-sharing",permalink:"/de/docs/settings/experiments/file-sharing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/file-sharing.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Server Hosting",permalink:"/de/docs/settings/experiments/server-hosting"},next:{title:"Bildvorschau und Profilbilder",permalink:"/de/docs/settings/experiments/image-previews-and-profile-pictures"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"dateifreigabe"},"Dateifreigabe"),(0,i.kt)("p",null,"Diese Einstellung aktiviert Cwtch ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/share-file"},"Dateisharing-Funktionalit\xe4t"),'. Dies zeigt die Option "Datei teilen" im Konversationsbereich an und erlaubt dir Dateien von Konversationen herunterzuladen.'),(0,i.kt)("p",null,"Optional kannst du ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Bildvorschau und Profilbilder")," aktivieren, um Bilddateien automatisch herunterzuladen, Bilder im Konversationsfenster anzuzeigen und die Funktion ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profilbilder")," aktivieren;"),(0,i.kt)("admonition",{title:"Info",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/1908c298.fa350f38.js b/build-staging/de/assets/js/1908c298.fa350f38.js new file mode 100644 index 00000000..dd9d798d --- /dev/null +++ b/build-staging/de/assets/js/1908c298.fa350f38.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5578],{4630:e=>{e.exports=JSON.parse('{"label":"testing","permalink":"/de/blog/tags/testing","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/1a25c548.952c300d.js b/build-staging/de/assets/js/1a25c548.952c300d.js new file mode 100644 index 00000000..e94ef268 --- /dev/null +++ b/build-staging/de/assets/js/1a25c548.952c300d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5732],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=r,u=h["".concat(c,".").concat(m)]||h[m]||g[m]||o;return a?n.createElement(u,i(i({ref:t},p),{},{components:a})):n.createElement(u,i({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const o={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"6. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/de/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,r.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,r.kt)("strong",{parentName:"p"},"Beta")," to ",(0,r.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,r.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}g.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/1a97c86e.536b8e99.js b/build-staging/de/assets/js/1a97c86e.536b8e99.js new file mode 100644 index 00000000..43849587 --- /dev/null +++ b/build-staging/de/assets/js/1a97c86e.536b8e99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3727],{9074:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/de/blog","blogDescription":"Die neuste Aktualisierung der Cwtch Entwicklung.","blogTitle":"Entwicklungsprotokoll"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/1be78505.c2da882e.js b/build-staging/de/assets/js/1be78505.c2da882e.js new file mode 100644 index 00000000..fb0a6ec0 --- /dev/null +++ b/build-staging/de/assets/js/1be78505.c2da882e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9514,4972],{9963:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ge});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),c=n(3320),i=n(2802),s=n(4477),d=n(1116),m=n(7961),u=n(5999),b=n(2466),p=n(5936);const h={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};function E(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,l]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:r,cancelScroll:c}=(0,b.Ct)();return(0,b.RF)(((e,n)=>{let{scrollY:a}=e;const r=n?.scrollY;r&&(o.current?o.current=!1:a>=r?(c(),l(!1)):a{e.location.hash&&(o.current=!0,l(!1))})),{shown:n,scrollToTop:()=>r(0)}}({threshold:300});return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,l.Z)("clean-btn",r.k.common.backToTopButton,h.backToTopButton,e&&h.backToTopButtonShow),type:"button",onClick:t})}var f=n(1442),g=n(6550),k=n(7524),_=n(6668),v=n(1327),C=n(7462);function S(e){return a.createElement("svg",(0,C.Z)({width:"20",height:"20","aria-hidden":"true"},e),a.createElement("g",{fill:"#7a7a7a"},a.createElement("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),a.createElement("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})))}const I={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function N(e){let{onClick:t}=e;return a.createElement("button",{type:"button",title:(0,u.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,l.Z)("button button--secondary button--outline",I.collapseSidebarButton),onClick:t},a.createElement(S,{className:I.collapseSidebarButtonIcon}))}var T=n(9689),Z=n(902);const x=Symbol("EmptyContext"),B=a.createContext(x);function y(e){let{children:t}=e;const[n,l]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:l})),[n]);return a.createElement(B.Provider,{value:o},t)}var w=n(6043),L=n(8596),A=n(9960),M=n(2389);function F(e){let{categoryLabel:t,onClick:n}=e;return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel",message:"Toggle the collapsible sidebar category '{label}'",description:"The ARIA label to toggle the collapsible sidebar category"},{label:t}),type:"button",className:"clean-btn menu__caret",onClick:n})}function H(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{items:m,label:u,collapsible:b,className:p,href:h}=t,{docs:{sidebar:{autoCollapseCategories:E}}}=(0,_.L)(),f=function(e){const t=(0,M.Z)();return(0,a.useMemo)((()=>e.href?e.href:!t&&e.collapsible?(0,i.Wl)(e):void 0),[e,t])}(t),g=(0,i._F)(t,o),k=(0,L.Mg)(h,o),{collapsed:v,setCollapsed:S}=(0,w.u)({initialState:()=>!!b&&(!g&&t.collapsed)}),{expandedItem:I,setExpandedItem:N}=function(){const e=(0,a.useContext)(B);if(e===x)throw new Z.i6("DocSidebarItemsExpandedStateProvider");return e}(),T=function(e){void 0===e&&(e=!v),N(e?null:s),S(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:l}=e;const o=(0,Z.D9)(t);(0,a.useEffect)((()=>{t&&!o&&n&&l(!1)}),[t,o,n,l])}({isActive:g,collapsed:v,updateCollapsed:T}),(0,a.useEffect)((()=>{b&&null!=I&&I!==s&&E&&S(!0)}),[b,I,s,S,E]),a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemCategory,r.k.docs.docSidebarItemCategoryLevel(c),"menu__list-item",{"menu__list-item--collapsed":v},p)},a.createElement("div",{className:(0,l.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":k})},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!h&&b,"menu__link--active":g}),onClick:b?e=>{n?.(t),h?T(!1):(e.preventDefault(),T())}:()=>{n?.(t)},"aria-current":k?"page":void 0,"aria-expanded":b?!v:void 0,href:b?f??"#":f},d),u),h&&b&&a.createElement(F,{categoryLabel:u,onClick:e=>{e.preventDefault(),T()}})),a.createElement(w.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:v},a.createElement(j,{items:m,tabIndex:v?-1:0,onItemClick:n,activePath:o,level:c+1})))}var P=n(3919),W=n(9471);const D={menuExternalLink:"menuExternalLink_NmtK"};function R(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{href:m,label:u,className:b,autoAddBaseUrl:p}=t,h=(0,i._F)(t,o),E=(0,P.Z)(m);return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(c),"menu__list-item",b),key:u},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",!E&&D.menuExternalLink,{"menu__link--active":h}),autoAddBaseUrl:p,"aria-current":h?"page":void 0,to:m},E&&{onClick:n?()=>n(t):void 0},d),u,!E&&a.createElement(W.Z,null)))}const V={menuHtmlItem:"menuHtmlItem_M9Kj"};function z(e){let{item:t,level:n,index:o}=e;const{value:c,defaultStyle:i,className:s}=t;return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(n),i&&[V.menuHtmlItem,"menu__list-item"],s),key:o,dangerouslySetInnerHTML:{__html:c}})}function U(e){let{item:t,...n}=e;switch(t.type){case"category":return a.createElement(H,(0,C.Z)({item:t},n));case"html":return a.createElement(z,(0,C.Z)({item:t},n));default:return a.createElement(R,(0,C.Z)({item:t},n))}}function K(e){let{items:t,...n}=e;return a.createElement(y,null,t.map(((e,t)=>a.createElement(U,(0,C.Z)({key:t,item:e,index:t},n)))))}const j=(0,a.memo)(K),G={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:o}=e;const c=function(){const{isActive:e}=(0,T.nT)(),[t,n]=(0,a.useState)(e);return(0,b.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return a.createElement("nav",{"aria-label":(0,u.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,l.Z)("menu thin-scrollbar",G.menu,c&&G.menuWithAnnouncementBar,o)},a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:n,activePath:t,level:1})))}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",X="sidebarHidden_VK0M",J="sidebarLogo_isFc";function Q(e){let{path:t,sidebar:n,onCollapse:o,isHidden:r}=e;const{navbar:{hideOnScroll:c},docs:{sidebar:{hideable:i}}}=(0,_.L)();return a.createElement("div",{className:(0,l.Z)(q,c&&O,r&&X)},c&&a.createElement(v.Z,{tabIndex:-1,className:J}),a.createElement(Y,{path:t,sidebar:n}),i&&a.createElement(N,{onClick:o}))}const $=a.memo(Q);var ee=n(3102),te=n(2961);const ne=e=>{let{sidebar:t,path:n}=e;const o=(0,te.e)();return a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&o.toggle(),"link"===e.type&&o.toggle()},level:1}))};function ae(e){return a.createElement(ee.Zo,{component:ne,props:e})}const le=a.memo(ae);function oe(e){const t=(0,k.i)(),n="desktop"===t||"ssr"===t,l="mobile"===t;return a.createElement(a.Fragment,null,n&&a.createElement($,e),l&&a.createElement(le,e))}const re={expandButton:"expandButton_m80_",expandButtonIcon:"expandButtonIcon_BlDH"};function ce(e){let{toggleSidebar:t}=e;return a.createElement("div",{className:re.expandButton,title:(0,u.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t},a.createElement(S,{className:re.expandButtonIcon}))}const ie={docSidebarContainer:"docSidebarContainer_b6E3",docSidebarContainerHidden:"docSidebarContainerHidden_b3ry",sidebarViewport:"sidebarViewport_Xe31"};function se(e){let{children:t}=e;const n=(0,d.V)();return a.createElement(a.Fragment,{key:n?.name??"noSidebar"},t)}function de(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}=e;const{pathname:c}=(0,g.TH)(),[i,s]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{i&&s(!1),!i&&(0,f.n)()&&s(!0),o((e=>!e))}),[o,i]);return a.createElement("aside",{className:(0,l.Z)(r.k.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&s(!0)}},a.createElement(se,null,a.createElement("div",{className:(0,l.Z)(ie.sidebarViewport,i&&ie.sidebarViewportHidden)},a.createElement(oe,{sidebar:t,path:c,onCollapse:d,isHidden:i}),i&&a.createElement(ce,{toggleSidebar:d}))))}const me={docMainContainer:"docMainContainer_gTbr",docMainContainerEnhanced:"docMainContainerEnhanced_Uz_u",docItemWrapperEnhanced:"docItemWrapperEnhanced_czyv"};function ue(e){let{hiddenSidebarContainer:t,children:n}=e;const o=(0,d.V)();return a.createElement("main",{className:(0,l.Z)(me.docMainContainer,(t||!o)&&me.docMainContainerEnhanced)},a.createElement("div",{className:(0,l.Z)("container padding-top--md padding-bottom--lg",me.docItemWrapper,t&&me.docItemWrapperEnhanced)},n))}const be={docPage:"docPage__5DB",docsWrapper:"docsWrapper_BCFX"};function pe(e){let{children:t}=e;const n=(0,d.V)(),[l,o]=(0,a.useState)(!1);return a.createElement(m.Z,{wrapperClassName:be.docsWrapper},a.createElement(E,null),a.createElement("div",{className:be.docPage},n&&a.createElement(de,{sidebar:n.items,hiddenSidebarContainer:l,setHiddenSidebarContainer:o}),a.createElement(ue,{hiddenSidebarContainer:l},t)))}var he=n(4972),Ee=n(197);function fe(e){const{versionMetadata:t}=e;return a.createElement(a.Fragment,null,a.createElement(Ee.Z,{version:t.version,tag:(0,c.os)(t.pluginId,t.version)}),a.createElement(o.d,null,t.noIndex&&a.createElement("meta",{name:"robots",content:"noindex, nofollow"})))}function ge(e){const{versionMetadata:t}=e,n=(0,i.hI)(e);if(!n)return a.createElement(he.default,null);const{docElement:c,sidebarName:m,sidebarItems:u}=n;return a.createElement(a.Fragment,null,a.createElement(fe,e),a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.docsPages,r.k.page.docsDocPage,e.versionMetadata.className)},a.createElement(s.q,{version:t},a.createElement(d.b,{name:m,items:u},a.createElement(pe,null,c)))))}},4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});var a=n(7294),l=n(5999),o=n(1944),r=n(7961);function c(){return a.createElement(a.Fragment,null,a.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/1ebd8798.30d73187.js b/build-staging/de/assets/js/1ebd8798.30d73187.js new file mode 100644 index 00000000..6549a147 --- /dev/null +++ b/build-staging/de/assets/js/1ebd8798.30d73187.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4788],{3905:(e,t,n)=>{n.d(t,{Zo:()=>g,kt:()=>u});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},g=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,g=c(e,["components","mdxType","originalType","parentName"]),p=s(n),h=i,u=p["".concat(l,".").concat(h)]||p[h]||d[h]||r;return n?a.createElement(u,o(o({ref:t},g),{},{components:n})):a.createElement(u,o({ref:t},g))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>s});var a=n(7462),i=(n(7294),n(3905));const r={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/de/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"24. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"autobindings",permalink:"/de/blog/tags/autobindings"},{label:"libcwtch",permalink:"/de/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/de/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/de/blog/cwtch-testing-ii"}},l={authorsImageUrls:[void 0]},s=[],g={toc:s},p="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,a.Z)({},g,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,i.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,i.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}d.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/2114bf44.9b098c3d.js b/build-staging/de/assets/js/2114bf44.9b098c3d.js new file mode 100644 index 00000000..1511abc6 --- /dev/null +++ b/build-staging/de/assets/js/2114bf44.9b098c3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7252],{3905:(e,n,t)=>{t.d(n,{Zo:()=>d,kt:()=>m});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var u=r.createContext({}),l=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},d=function(e){var n=l(e.components);return r.createElement(u.Provider,{value:n},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},b=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,u=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),c=l(t),b=i,m=c["".concat(u,".").concat(b)]||c[b]||p[b]||o;return t?r.createElement(m,a(a({ref:n},d),{},{components:t})):r.createElement(m,a({ref:n},d))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=b;var s={};for(var u in n)hasOwnProperty.call(n,u)&&(s[u]=n[u]);s.originalType=e,s[c]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=t(7462),i=(t(7294),t(3905));const o={sidebar_position:5},a="Tor",s={unversionedId:"tor",id:"tor",title:"Tor",description:'Cwtch verwendet Tor um Routing und Verbindungen bereitzustellen. Die Verwendung von Tor-versteckten Diensten f\xfcr das Hosten von Profilen und nebenbei generierte "ephemerale" Verbindungen, wenn eine Verbindung aufgebaut wird, bietet eine starke Anonymit\xe4t f\xfcr Benutzer von Cwtch.',source:"@site/i18n/de/docusaurus-plugin-content-docs/current/tor.md",sourceDirName:".",slug:"/tor",permalink:"/de/docs/tor",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/tor.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"QR Codes",permalink:"/de/docs/settings/experiments/qrcodes"},next:{title:"Contribute",permalink:"/de/docs/category/contribute"}},u={},l=[{value:"Tor-\xdcbersicht",id:"tor-\xfcbersicht",level:2},{value:"Reset Tor",id:"reset-tor",level:3},{value:"Cache-Tor-Konsens",id:"cache-tor-konsens",level:3},{value:"Erweiterte Tor Einstellungen",id:"erweiterte-tor-einstellungen",level:3}],d={toc:l},c="wrapper";function p(e){let{components:n,...o}=e;return(0,i.kt)(c,(0,r.Z)({},d,o,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"tor"},"Tor"),(0,i.kt)("p",null,"Cwtch verwendet ",(0,i.kt)("a",{parentName:"p",href:"https://www.torproject.org/"},"Tor"),' um Routing und Verbindungen bereitzustellen. Die Verwendung von Tor-versteckten Diensten f\xfcr das Hosten von Profilen und nebenbei generierte "ephemerale" Verbindungen, wenn eine Verbindung aufgebaut wird, bietet eine starke Anonymit\xe4t f\xfcr Benutzer von Cwtch.'),(0,i.kt)("h2",{id:"tor-\xfcbersicht"},"Tor-\xdcbersicht"),(0,i.kt)("p",null,"Da wir Cwtch eine zus\xe4tzliche Netzwerk-Ebene hinzuf\xfcgen, bieten wir eine \xdcbersicht, um den Tor-Netzwerk-Status zu sehen und \xc4nderungen vorzunehmen. Um darauf zuzugreifen"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Klicke auf das Tor-Symbol in der Profilliste ",(0,i.kt)("img",{alt:"tor icon",src:t(4525).Z,width:"32",height:"32"})),(0,i.kt)("li",{parentName:"ol"},"Den Tor Netzwerkstatus anzeigen")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"Tor-Status: Online\nTorversion: 0.4.6.9\n")),(0,i.kt)("h3",{id:"reset-tor"},"Reset Tor"),(0,i.kt)("p",null,"Das Tor-Netzwerk selbst kann gelegentlich veraltete Verbindungen haben, die nicht sofort von ihm oder Cwtch erkannt werden (wir versuchen dies immer weiter zu verbessern). Manchmal kann ein Benutzer Kontakte oder Gruppen finden, die offline erscheinen, auch wenn diese meinen, dass sie online sein sollten. Wenn du alle Netzwerkverbindungen in Cwtch neu starten m\xf6chtest, bieten wir einen Mechanismus zum Tor Neustart von innerhalb der App an. Der ",(0,i.kt)("strong",{parentName:"p"},"Reset")," Button startet Tor aus der Cwtch App heraus neu."),(0,i.kt)("h3",{id:"cache-tor-konsens"},"Cache-Tor-Konsens"),(0,i.kt)("p",null,"Standardm\xe4\xdfig starten wir jedesmal einen neuen Tor-Prozess, wenn die App bootet, und es erfordert das Herunterladen eines Tor-Netzwerk-Zustandes, bevor dieser gestartet werden kann. Dieser Prozess ist nicht so schnell. Wenn du den Cwtch-Start beschleunigen m\xf6chtest, kannst du den Tor-Cache-Konsens aktivieren, um zuk\xfcnftige Starts zu beschleunigen. Wenn du in ein Start Problem kommst, wo die Daten veraltet oder korrupt sind und Cwtch meldet, dass es nicht starten kann, dann deaktiviere diese Einstellung und ",(0,i.kt)("strong",{parentName:"p"},"reset")," Tor erneut, dann sollte es funktionieren."),(0,i.kt)("h3",{id:"erweiterte-tor-einstellungen"},"Erweiterte Tor Einstellungen"),(0,i.kt)("p",null,"Wir bieten dir auch die M\xf6glichkeit an, in diesem Abschnitt eine erweiterte Tor-Konfiguration bereitzustellen, indem wir dir erlauben:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Gib einen benutzerdefinierten SOCKS-Port an, um eine Verbindung zu einem bestehenden Tor herzustellen"),(0,i.kt)("li",{parentName:"ul"},"Gib einen benutzerdefinierten Kontroll-Port an, um eine Verbindung zu einem bestehenden Tor herzustellen"),(0,i.kt)("li",{parentName:"ul"},"und gib weitere Optionen an, indem du benutzerdefinierte ",(0,i.kt)("inlineCode",{parentName:"li"},"torrc")," Optionen eingibst")))}p.isMDXComponent=!0},4525:(e,n,t)=>{t.d(n,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAATrwAAE68BY+aOwwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMUSURBVFiFvZZPiNVVFMc/Z546zkwzOikaxlSSFRklQVBQCEWmmRK1CYIWLabIReC6TdCiVtamlaUlQbhrkfTPiMxF0KoyhtISyjBpgkZszJnGT4vfefXT3u817zfvzYHHvffc8873+zv33HsO9EDUsfna9vUAfBcwlPMrFoWAukQN9WXgNNBQ9wPX/99/l3SDAHArsAMYBG4HXge2R8SXXfJfLeom9Xn1jHpY/UPd3HPgEoED6kn1N3VGfWAxwZeqU/4rzywaeBLYXALfV8dHrSRUHwRWAnek6gfg2Tq+6l7DCWAjcBz4DtgbEedq+qon6ls53p1HUCvzF/IQrcixcdm69wTU9aXlZI671UYr+66KujMfnKvUAXVY/SmP4aB6Za+AV6hvqq8l6Op8B1aqT5au46S6S41ugm9Uj6hbSroNOV6bhehzL5V3uxINdYv6abnGq2vV0Zzfk9Vwm/+Vr9SRhYDfpH7W/JL80lXq8lw3Mg+25t5UCxLvLITAh+rVOe9TB0t7oV6nrlMfyXw42oKA5aO7XCqvoboV+CIifs6EWhoR0yWTbRTNxwhwGHgIOFbhbnfHBICdQDN8/RFxIYkNqePAidQNAOeAMeD3Cl/3qcOdEtgETKj/2KjXAE8BByLieKq/pmi9+oDzFb76qWjP2hFoANNAIyL+zGN4HHilFI1RigjMAWeBdk3o2lbKduX4PEXJnQZmgXuBgxFhgq8GbgHOpJ854IY2/iZbKdtF4FvgLuBi3uWxiDhZ2n8UOAKsAn6haEarCtIscKJTAoeA8YiYocj0IXWotP9jRmMQWAasS7tW8lFETHVK4H3gRos6PwN8DzwGoC6jyHwSdD3wK3Bzha89VSCVBCJiDngaeBsYBk4BO9SRjMpoicAwRTIOtHD1RkR83DGBJHEUeA54jyLMe4E9FnV/TdMM2A7c2cLFofyIaox2m01R7wdeBT4AvgFuoziSCeAJ4GGKXGjKX8CLwAsRMTsfjPmQWK6Oq59k0bmgzuXPHI+pL3lpx9RWajUNaj9F1jfr/VngdJ3O+G/ZO0GaKrbieAAAAABJRU5ErkJggg=="}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/2250486b.30003be1.js b/build-staging/de/assets/js/2250486b.30003be1.js new file mode 100644 index 00000000..09a08927 --- /dev/null +++ b/build-staging/de/assets/js/2250486b.30003be1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7015],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>f});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=r.createContext({}),u=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c=function(e){var n=u(e.components);return r.createElement(s.Provider,{value:n},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),l=u(t),m=i,f=l["".concat(s,".").concat(m)]||l[m]||d[m]||o;return t?r.createElement(f,a(a({ref:n},c),{},{components:t})):r.createElement(f,a({ref:n},c))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=m;var p={};for(var s in n)hasOwnProperty.call(n,s)&&(p[s]=n[s]);p.originalType=e,p[l]="string"==typeof e?e:i,a[1]=p;for(var u=2;u{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const o={sidebar_position:4},a="Einladungen an eine Gruppe senden",p={unversionedId:"groups/send-invite",id:"groups/send-invite",title:"Einladungen an eine Gruppe senden",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/send-invite.md",sourceDirName:"groups",slug:"/groups/send-invite",permalink:"/de/docs/groups/send-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/send-invite.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Eine neue Gruppe erstellen",permalink:"/de/docs/groups/create-group"},next:{title:"Eine Gruppeneinladung annehmen",permalink:"/de/docs/groups/accept-group-invite"}},s={},u=[],c={toc:u},l="wrapper";function d(e){let{components:n,...t}=e;return(0,i.kt)(l,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"einladungen-an-eine-gruppe-senden"},"Einladungen an eine Gruppe senden"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Gehe zu einem Chat mit einem Kontakt"),(0,i.kt)("li",{parentName:"ol"},"Klicke auf das Einladungs-Symbol"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle die Gruppe aus, in die du einladen m\xf6chtest"),(0,i.kt)("li",{parentName:"ol"},"Klicke Einladen"),(0,i.kt)("li",{parentName:"ol"},"Du hast eine Einladung gesendet")),(0,i.kt)("div",null,(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Group_Invite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/291c70d7.e1cc0c5e.js b/build-staging/de/assets/js/291c70d7.e1cc0c5e.js new file mode 100644 index 00000000..90514dbc --- /dev/null +++ b/build-staging/de/assets/js/291c70d7.e1cc0c5e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[725],{9574:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"cwtch-stable-roadmap-update-june","metadata":{"permalink":"/de/blog/cwtch-stable-roadmap-update-june","source":"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","date":"2023-06-30T00:00:00.000Z","formattedDate":"30. Juni 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/de/blog/tags/planning"}],"readingTime":5.26,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","slug":"cwtch-stable-roadmap-update-june","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"nextItem":{"title":"Cwtch Beta 1.12","permalink":"/de/blog/cwtch-nightly-1-12"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the Cwtch Stable Roadmap\\n\\nBack in March we extended and updated several goals from [our January roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document \u2705 - [Release Process](https://docs.cwtch.im/developing/release/#official-releases)\\n - A Cwtch Packaging Document \u2705 - [Packaging Documentation](https://docs.cwtch.im/developing/release/)\\n - Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new [documentation style guide](/docs/contribute/documentation), and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries \u2705 - [Building a Cwtch App](https://docs.cwtch.im/developing/category/building-a-cwtch-app)\\n - Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. \\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129) \ud83d\udfe1 - currently in [active development](https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information \u2705 - released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12)\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593) \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12). We now believe these changes will be complete in Cwtch Beta 1.13.\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms) \ud83d\udfe1 - we have already launched an environment for testing [Tails](/docs/platforms/tails). Other platforms are underway.\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\n\\n## Next Steps, Refinements, Additional Work\\n\\nAs you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. \\n\\nOther work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.\\n\\nHowever, [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12) featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.\\n\\nThe work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.\\n\\nWe are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-12","metadata":{"permalink":"/de/blog/cwtch-nightly-1-12","source":"@site/blog/2023-06-16-cwtch-1.12.md","title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","date":"2023-06-16T00:00:00.000Z","formattedDate":"16. Juni 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"release","permalink":"/de/blog/tags/release"}],"readingTime":2.455,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","slug":"cwtch-nightly-1-12","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog13_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/de/blog/cwtch-stable-roadmap-update-june"},"nextItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/de/blog/cwtch-nightly-v.11-74"}},"content":"[Cwtch 1.12 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new features like [profile attributes](https://docs.cwtch.im/docs/profiles/profile-info), support for new platforms like [Tails](https://docs.cwtch.im/docs/platforms/tails), and multiple improvements to performance and stability.\\n\\n![](/img/devlog13.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n
\\n\\n[![](/img/picnic1.12.png)](/img/picnic1.12.png)\\n\\n
A screenshot of Cwtch 1.12
\\n
\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Profile Attributes** - profiles can now be augmented with [additional public information](https://docs.cwtch.im/docs/profiles/profile-info)\\n - **Availability Status** - you can now notify contacts that you [are **away** or **busy**](https://docs.cwtch.im/docs/profiles/availability-status)\\n - **Five New Supported Localizations**: **Japanese**, **Korean**, **Slovak**, **Swahili** and **Swedish**\\n - **Support for Tails** - adds an [OnionGrater](https://docs.cwtch.im/docs/platforms/tails) configuration and a new `CWTCH_TAILS` environment variable that enables special Tor behaviour.\\n- **Bug Fixes / Improvements:**\\n - Based on Flutter 3.10\\n - Inter is now the main UI font\\n - New Font Scaling setting\\n - New Network Management code to better manage Tor on unstable networks\\n - File Sharing Experiment Fixes\\n \\t- Fix performance issues for file bubble\\n \\t- Allow restarting of file shares that have timed out\\n \\t- Fix NPE in FileBubble caused by deleting the underlying file\\n \\t- Move from RetVal to UpdateConversationAttributes to minimze UI thread issues\\n - Updates to Linux install scripts to support more distributions\\n - Add a Retry Peer connection to prioritize connection attempts for certain conversations\\n - Updates to `_FlDartProject` to allow custom setting of Flutter asset paths\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Slovak**, **Spanish**, **Swahili**, **Swedish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Japanese** (29%), **Korean** (23%), **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n## Reproducible Bindings\\n\\nCwtch 1.12 is based on libCwtch version `libCwtch-autobindings-2023-06-13-10-50-v0.0.5`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-v.11-74","metadata":{"permalink":"/de/blog/cwtch-nightly-v.11-74","source":"@site/blog/2023-06-07-new-nightly.md","title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","date":"2023-06-07T00:00:00.000Z","formattedDate":"7. Juni 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/de/blog/tags/developer-documentation"}],"readingTime":1.845,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","slug":"cwtch-nightly-v.11-74","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog10_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.12","permalink":"/de/blog/cwtch-nightly-1-12"},"nextItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/de/blog/cwtch-developer-documentation"}},"content":"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog10.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-06-05-17-36-v1.11.0-74-g0406](https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/).\\n\\nThis version has a large number of improvements and bug fixes including:\\n\\n* A new Font Scaling setting\\n* Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.\\n* Updated UI font styles\\n* Dependency updates, including a new base of Flutter 3.10.\\n* A fix for stuck file downloading notifications on Android\\n* A fix for missing profile images in certain edge cases on Android\\n* Japanese, Swedish, and Swahili translation options\\n* A new retry peer connection button for prompting Cwtch to prioritize specific connections\\n* [Tails support](/docs/platforms/tails)\\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-developer-documentation","metadata":{"permalink":"/de/blog/cwtch-developer-documentation","source":"@site/blog/2023-04-28-developer-docs.md","title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","date":"2023-04-28T00:00:00.000Z","formattedDate":"28. April 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/de/blog/tags/developer-documentation"}],"readingTime":2.595,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","slug":"cwtch-developer-documentation","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/de/blog/cwtch-nightly-v.11-74"},"nextItem":{"title":"Availability Status and Profile Attributes","permalink":"/de/blog/availability-status-profile-attributes"}},"content":"One of the larger remaining goals outlined in our [Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. \\n\\nIn this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!\\n\\nWe are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog9.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Cwtch Development Handbook\\n\\nWe have created a new documentation section, [the developers handbook](/developing/intro). This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).\\n\\n### Release and Packaging Process\\n\\nThe new handbook features a breakdown of [Cwtch release processes](/developing/release) - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.\\n\\n### Cwtch Application Development and Cwtchbot v0.1.0!\\n\\nFor the first time ever we now have [comprehensive documentation on how to build a Cwtch Application](/developing/category/building-a-cwtch-app). This section of the development handbook covers everything from [choosing a Cwtch library](/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library), to [building your first application](/developing/building-a-cwtch-app/building-an-echobot).\\n\\nTogether with this new documentation we have also [released version 0.1 of the Cwtchbot framework](https://git.openprivacy.ca/sarah/cwtchbot), updating calls to use the [new Cwtch Stable API](/blog/cwtch-stable-api-design).\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-04-26-20-57-v1.11.0-33-gb4371](https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/).\\n\\nThis version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the [in-development Tails support](/docs/platforms/tails). \\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"availability-status-profile-attributes","metadata":{"permalink":"/de/blog/availability-status-profile-attributes","source":"@site/blog/2023-04-06-availability-and-profile-attributes.md","title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","date":"2023-04-06T00:00:00.000Z","formattedDate":"6. April 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"nightly","permalink":"/de/blog/tags/nightly"}],"readingTime":1.445,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","slug":"availability-status-profile-attributes","tags":["cwtch","cwtch-stable","nightly"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/de/blog/cwtch-developer-documentation"},"nextItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/de/blog/cwtch-stable-roadmap-update"}},"content":"Two new Cwtch features are now available to test in nightly: [Availability Status](/docs/profiles/availability-status) and [Profile Information](/docs/profiles/profile-info).\\n\\nAdditionally, we have also published draft guidance on [running Cwtch on Tails](/docs/platforms/tails) that we would like volunteers to test and report back on.\\n \\nThe Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like\\nours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Availability Status\\n\\nNew in this nightly is the ability to notify your conversations that you are \\"Away\\" or \\"Busy\\".\\n\\n
\\n\\n[![](/img/profiles/status-tooltip-busy-set.png)](/img/profiles/status-tooltip-busy-set.png)\\n\\n
\\n
\\n\\nRead more: [Availability Status](/docs/profiles/availability-status)\\n\\n## Profile Attributes\\n\\nAlso new is the ability to augment your profile with a few small pieces of **public** information.\\n\\n
\\n\\n[![](/img/profiles/attributes-set.png)](/img/profiles/attributes-set.png)\\n\\n
\\n
\\n\\nRead more: [Profile Information](/docs/profiles/profile-info)\\n \\n## Downloading the Nightly\\n\\n[Nightly builds](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. Download links for **2023-04-05-18-28-v1.11.0-7-g0290** are available below.\\n\\n* Windows: [https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/)\\n* Linux: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n* Mac: [https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/)\\n* Android: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-roadmap-update","metadata":{"permalink":"/de/blog/cwtch-stable-roadmap-update","source":"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","date":"2023-03-31T00:00:00.000Z","formattedDate":"31. M\xe4rz 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/de/blog/tags/planning"}],"readingTime":5.61,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","slug":"cwtch-stable-roadmap-update","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Availability Status and Profile Attributes","permalink":"/de/blog/availability-status-profile-attributes"},"nextItem":{"title":"Cwtch Beta 1.11","permalink":"/de/blog/cwtch-nightly-1-11"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap](/blog/path-to-cwtch-stable) we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the January Roadmap\\n\\nBack in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)\\n\\n- By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705\\n- By **1st February 2023**, the Cwtch team will have [finalized a feature set that defines Cwtch Stable](/blog/cwtch-stable-api-design) and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705\\n- By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:\\n - [Security and Design Documents](/security/intro) \u2705\\n - Infrastructure and [Support](/docs/getting-started/supported_platforms) \ud83d\udfe1\\n - in addition to a new development blog. \u2705\\n- By **31st March 2023**, the Cwtch team will have created:\\n - a [style guide for documentation](/docs/contribute/documentation), and \u2705\\n - have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1\\n - with at least one screenshot (where applicable). \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have published: \\n - a Cwtch [Interface Specification Document](/blog/cwtch-stable-api-design) \u2705\\n - a Cwtch Release Process Document \ud83d\udfe1\\n - a Cwtch [Support Plan document](/blog/cwtch-platform-support) \u2705\\n - a Cwtch Packaging Document \ud83d\udfe1\\n - a document describing the [Reproducible Builds Process](/blog/cwtch-bindings-reproducible) \u2705\\n - These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705\\n- By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c\\n- By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)\\n\\nWhile we didn\'t hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:\\n\\n* [Cwtch Autobindings](/blog/autobindings) with [compile-time optional experiments](/blog/autobindings-ii)\\n* [Cwtch 1.11](/blog/cwtch-nightly-1-11) - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements.\\n* [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.\\n\\n## A Timeline for Cwtch Stable\\n\\nNow for the big news, we plan on releasing a candidate Cwtch Stable release during **Summer 2023**. Here is our plan for getting there:\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document\\n - A Cwtch Packaging Document\\n - Completion of documentation of existing Cwtch features, including relevant screenshots.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries\\n - Automatically generated API documentation for libCwtch\\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593)\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms)\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-11","metadata":{"permalink":"/de/blog/cwtch-nightly-1-11","source":"@site/blog/2023-03-29-cwtch-1.11.md","title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","date":"2023-03-29T00:00:00.000Z","formattedDate":"29. M\xe4rz 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"release","permalink":"/de/blog/tags/release"}],"readingTime":2.365,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","slug":"cwtch-nightly-1-11","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog12_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/de/blog/cwtch-stable-roadmap-update"},"nextItem":{"title":"Updates to Cwtch Documentation","permalink":"/de/blog/cwtch-documentation"}},"content":"[Cwtch 1.11 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new [reproducible](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) and [automatically generated](https://docs.cwtch.im/blog/autobindings) bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.\\n\\n![](/img/devlog12.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n
\\n\\n[![](/img/picnic.png)](/img/picnic.png)\\n\\n
A screenshot of Cwtch 1.11
\\n
\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Based on new Reproducible Cwtch Stable Autobuilds** - this is the first release of cwtch based on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) in addition to our new [automatically generated](https://docs.cwtch.im/blog/autobindings)\\n - **Two New Supported Localizations**: **Slovak** and **Korean**\\n- **Bug Fixes / Improvements:**\\n - When preserving a message draft, quoted messages are now also saved\\n - Layout issues caused by pathological unicode are now prevented\\n - Improved performance of message row rendering\\n - Clickable Links: Links in replies are now selectable\\n - Clickable Links: Fixed error when highlighting certain URIs \\n - File Downloading: Fixes for file downloading and exporting on 32bit Android devices\\n - Server Hosting: Fixes for several layout issues\\n - Build pipeline now runs automated UI tests\\n - Fix issues caused by scrollbar controller overriding\\n - Initial support for the Blodeuwedd Assistant (currently compile-time disabled)\\n - Cwtch Library:\\n - [New Stable Cwtch Peer API](/blog/cwtch-stable-api-design)\\n - Ported File Downloading and Image Previews experiments into Cwtch\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Spanish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n\\n\\n## Reproducible Bindings\\n\\nCwtch 1.11 is based on libCwtch version `2023-03-16-15-07-v0.0.3-1-g50c853a`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-documentation","metadata":{"permalink":"/de/blog/cwtch-documentation","source":"@site/blog/2023-03-10-cwtch-documentation.md","title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","date":"2023-03-10T00:00:00.000Z","formattedDate":"10. M\xe4rz 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"documentation","permalink":"/de/blog/tags/documentation"},{"label":"security-handbook","permalink":"/de/blog/tags/security-handbook"}],"readingTime":2.57,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","slug":"cwtch-documentation","tags":["cwtch","cwtch-stable","documentation","security-handbook"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.11","permalink":"/de/blog/cwtch-nightly-1-11"},"nextItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/de/blog/autobindings-ii"}},"content":"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.\\n\\n![](/img/devlog9.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Cwtch Secure Development Handbook\\n \\nOne of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.\\n\\nWe have [now ported the the handbook to this documentation site](/security/intro), along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. \\n\\n## Volunteer Development\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Next Steps\\n\\nWe still have more work to do on the documentation front:\\n\\n* Ensuring all pages [implement the new documentation style guide](/docs/contribute/documentation), and include appropriate screenshots and descriptions.\\n* Expanding the security handbook to provide information on [reproducible builds](/blog/cwtch-bindings-reproducible), [the new Cwtch Stable API](/blog/cwtch-stable-api-design) and upcoming improvements around fuzz testing.\\n* Creating new documentation sections on the [libCwtch autobindings API](/blog/autobindings) and building applications on top of Cwtch.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings-ii","metadata":{"permalink":"/de/blog/autobindings-ii","source":"@site/blog/2023-03-03-autobindings-optional-experiments.md","title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","date":"2023-03-03T00:00:00.000Z","formattedDate":"3. M\xe4rz 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/de/blog/tags/bindings"},{"label":"autobindings","permalink":"/de/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/de/blog/tags/libcwtch"}],"readingTime":4.655,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","slug":"autobindings-ii","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Updates to Cwtch Documentation","permalink":"/de/blog/cwtch-documentation"},"nextItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/de/blog/autobindings"}},"content":"[Last time we looked at autobindings](https://docs.cwtch.im/blog/autobindings) we mentioned that one of the next steps was introducing support for **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)**. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## The Structure of an Application Experiment\\n\\nAn application-level experiment consists of:\\n\\n1. A set of top-level APIs, e.g. `CreateServer`, `LoadServer`, `DeleteServer` - these are the APIs that we want to expose to calling applications.\\n2. An encapsulating structure for the set of APIs, e.g. `ServersFunctionality` - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.\\n3. A global variable that exists at the top level of libCwtch, e.g. `var serverExperiment *servers.ServersFunctionality servers` - our single pointer to the underlying functionality.\\n4. A set of management-related APIs, e.g. `Init`, `UpdateSettings`, `OnACNEvent` - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).\\n5. Management code within `_startCwtch` and `_reconnectCwtch` that calls the management APIs on the global variable.\\n\\nFrom a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\\nof on `application` or a specific `profile`.\\n\\nMost of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.\\n\\n### New Required Management APIs\\n\\nTo achieve this weaving, we now require application-level experiments to implement an `EventHandlerInterface` interface and expose itself via an\\ninitialize constructor `Init(acn, appDir) -> EventHandlerInterface`, and `Enable(app, acn)`.\\n\\nFor now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.\\n\\nWe can then generate, and optionally include blocks of code like:\\n\\n\\t\\t = .Init(&globalACN, appDir)\\n\\t\\teventHandler.AddModule()\\n\\t\\t.Enable(application, &globalACN)\\n\\nand place them at specific points in the code. `EventHandler` has also been extended to maintain a collection of `modules` so that it can\\npass on interesting events.\\n\\n### Adding Support for Application Experiments in the Spec File\\n\\nWe have introduced a new `!` operator which can be used to gate APIs behind a configured experiment. Along with a new\\ntemplating option `exp` which will call the function on the configured experiment, and `global` to allow the setting up\\nof a global functionality within the library.\\n\\n\\t\\t# Server Hosting Experiment\\n\\t\\t!serverExperiment import \\"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\\"\\n\\t\\t!serverExperiment global serverExperiment *servers.ServersFunctionality servers\\n\\t\\t!serverExperiment exp CreateServer application password string:description bool:autostart\\n\\t\\t!serverExperiment exp SetServerAttribute application string:handle string:key string:val\\n\\t\\t!serverExperiment exp LoadServers application acn password\\n\\t\\t!serverExperiment exp LaunchServers application acn\\n\\t\\t!serverExperiment exp LaunchServer application string:handle\\n\\t\\t!serverExperiment exp StopServer application string:handle\\n\\t\\t!serverExperiment exp StopServers application\\n\\t\\t!serverExperiment exp DestroyServers\\n\\t\\t!serverExperiment exp DeleteServer application string:handle password\\n\\n### Generation-Time Inclusion\\n\\n Without any arguments provided `generate-bindings` will not generate code for any experiments.\\n\\n In order to determine what experimental code to generate, `generate-bindings` now interprets arguments as enabled compile time experiments, e.g. `generate-bindings serverExperiment` will turn on\\n generation of server hosting code, per the spec file above.\\n\\n### Cwtch UI Integration\\n\\nThe UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. `c_LoadServers` - if it doesn\'t then the UI is safe to assume the\\nfeature is not available.\\n\\n
\\n\\n![](/img/dev9-host-disabled.png)\\n\\n
A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.
\\n
\\n\\n## Nightlies & Next Steps\\n\\nWe are now publishing [nightlies](https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/) of autobinding derived libCwtch-go, along with [Repliqate scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2) for reproducibility.\\n\\nWith application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.\\n\\nHowever, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:\\n\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs).\\n * **Documentation generation**: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings","metadata":{"permalink":"/de/blog/autobindings","source":"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md","title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","date":"2023-02-24T00:00:00.000Z","formattedDate":"24. Februar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/de/blog/tags/bindings"},{"label":"autobindings","permalink":"/de/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/de/blog/tags/libcwtch"}],"readingTime":4.545,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","slug":"autobindings","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/de/blog/autobindings-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/de/blog/cwtch-testing-ii"}},"content":"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to **automatically generate** these bindings: [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings).\\n\\nThis this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the [path to Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable).\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## A Brief History of Cwtch Bindings\\n\\nPrior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by [therecipe/qt](https://github.com/therecipe/qt). However, after encountering numerous\\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.\\n\\nAs part of early prototyping efforts for Flutter we built out a first version of [libCwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go), and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.\\n\\nThis approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular [experimental features](https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape) - handle settings, [duplication of logic between Cwtch and libCwtch-go](https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings), and [special behaviour in libCwtch-go that better belongs in the core Cwtch library](https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go).\\n\\nAs part of a broader effort to [refine the Cwtch API in preparation for Cwtch Stable](https://docs.cwtch.im/blog/cwtch-stable-api-design) we have taken the opportunity to fix many of these problems.\\n\\n## Cwtch Autobindings\\n\\nThe current `lib.go` file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the `BlockContact` API implementation is:\\n\\n\\t//export c_BlockContact\\n\\tfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\\n\\t\\tBlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\\n\\t}\\n\\n\\tfunc BlockContact(profileOnion string, conversationID int) {\\n\\t\\tprofile := application.GetPeer(profileOnion)\\n\\t\\tif profile != nil {\\n\\t\\t\\tprofile.BlockConversation(conversationID)\\n\\t\\t}\\n\\t}\\n\\nAll that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.\\n\\nIn the new [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings) we reduce these multiple lines to [a single one](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19):\\n\\n\\tprofile BlockConversation conversation\\n\\nDefining a `profile`-level function, called `BlockConversation` which takes in a single parameter of type `conversation`.\\n\\nUsing a similar boilerplate-reduction for the reset of `lib.go` yields [5-basic function prototypes](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format):\\n\\n* Application-level functions e.g. `CreateProfile`\\n* Profile-level functions e.g. `BlockConversation`\\n* Profile-level functions that return data e.g. `GetMessage`\\n* Experimental Profile-level feature functions e.g. `DownloadFile`\\n* Experimental Profile-level feature functions that return data e.g. `ShareFile`\\n\\nOnce aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be [described in fewer than 50 lines, including comments](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec). Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).\\n\\n## Next Steps\\n\\nCwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:\\n\\n * **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)** (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on `cwtch-server`). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don\'t support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart-side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs)\\n * **Documentation generation**: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n * **Cwtch API**: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the [Cwtch Stable API redesign](https://docs.cwtch.im/blog/cwtch-stable-api-design). In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-ii","metadata":{"permalink":"/de/blog/cwtch-testing-ii","source":"@site/blog/2023-02-17-cwtch-testing-ii.md","title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","date":"2023-02-17T00:00:00.000Z","formattedDate":"17. Februar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"support","permalink":"/de/blog/tags/support"},{"label":"testing","permalink":"/de/blog/tags/testing"}],"readingTime":1.75,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","slug":"cwtch-testing-ii","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog7_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/de/blog/autobindings"},"nextItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/de/blog/cwtch-android-reproducibility"}},"content":"In this development log, we investigate some text-based UI bugs encountered by [Fuzzbot](https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot), add more [automated UI tests](/blog/cwtch-testing-i) to the pipeline, and announce a new release of the Cwtchbot library.\\n\\n![](/img/devlog7.png)\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Constraining Cwtch UI Fields\\n\\nFuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\\ndoesn\'t pose a safety issue, it is unsightly.\\n\\n
\\n\\n[![](/img/dl7-before.png)](/img/dl7-before.png)\\n\\n
Screenshot demonstrating how certain strings would violate the bounds of their containers.
\\n
\\n\\nThese cases were fixed by parenting impacted elements in a `Container` with `clip: hardEdge` and `decoration:BoxDecoration()` (note that both of these are required as Container widgets in Flutter cannot set clipping logic\\nwithout an associated decoration).\\n\\n
\\n\\n[![](/img/dl7-after.png)](/img/dl7-after.png)\\n\\n
Now these clipped strings are tightly constrained to their container bounds.
\\n
\\n\\nThese fixes are available in the [latest Cwtch Nightly](/docs/contribute/testing#cwtch-nightlies), and will be officially released in Cwtch 1.11.\\n\\n## More Automated UI Tests\\n\\nWe have added two new sets of automated UI tests to our pipeline:\\n\\n- *02: Global Settings* - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. ([PR: 628](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628))\\n- *04: Profile Management* - these tests check that creating, unlocking, and deleting a profile work as expected. ([PR: 632](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632))\\n\\n## New Release of Cwtchbot\\n\\n[Cwtchbot](https://git.openprivacy.ca/sarah/cwtchbot) has been updated to use the latest Cwtch 0.18.10 API.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-android-reproducibility","metadata":{"permalink":"/de/blog/cwtch-android-reproducibility","source":"@site/blog/2023-02-10-android-reproducibility.md","title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","date":"2023-02-10T00:00:00.000Z","formattedDate":"10. Februar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/de/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/de/blog/tags/bindings"},{"label":"repliqate","permalink":"/de/blog/tags/repliqate"}],"readingTime":2.92,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","slug":"cwtch-android-reproducibility","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog6_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/de/blog/cwtch-testing-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing","permalink":"/de/blog/cwtch-testing-i"}},"content":"In this development log, we continue our previous work on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible), uncovering the final few sources of variation between our [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!\\n\\n![](/img/devlog6.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Changes Necessary for Reproducible Android Bindings\\n\\nAfter a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:\\n\\n- **Insufficient path stripping introduced by Android NDK tools** - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 [changed the binutils and default linker](https://github.com/android/ndk/wiki/Changelog-r22) to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our [long term support plan](https://docs.cwtch.im/blog/cwtch-platform-support), we will be moving towards adopting the latest NDK in the future.\\n- **Paths in DWARF entries** - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.\\n\\n
\\n\\n[![](/img/aar-diff.png)](/img/aar-diff.png)\\n\\n
Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
\\n
\\n\\n- **Go Compiler Acquisition** - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there *was* a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.\\n\\n## Repliqate Scripts\\n\\nWith those issues now fixed, Cwtch Android bindings are **officially reproducible!** The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under [cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script) in the [Cwtch Repliqate scripts repository](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/).\\n\\nThis is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-i","metadata":{"permalink":"/de/blog/cwtch-testing-i","source":"@site/blog/2023-02-03-cwtch-testing-i.md","title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","date":"2023-02-03T00:00:00.000Z","formattedDate":"3. Februar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"support","permalink":"/de/blog/tags/support"},{"label":"testing","permalink":"/de/blog/tags/testing"}],"readingTime":4.74,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","slug":"cwtch-testing-i","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog5_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/de/blog/cwtch-android-reproducibility"},"nextItem":{"title":"Cwtch UI Platform Support","permalink":"/de/blog/cwtch-platform-support"}},"content":"We first [introduced UI tests last January](https://openprivacy.ca/discreet-log/23-cucumber-testing/). At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.\\n\\nOne of the main threads of work that needs to be complete early in the [Cwtch Stable roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.\\n\\n![](/img/devlog5.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Current Limitations of Flutter Gherkin\\n\\nThe original [flutter_gherkin](https://pub.dev/packages/flutter_gherkin) is under semi-active development; however, the latest published versions don\'t support using it with `flutter test`.\\n\\n- **Flutter Test** was originally intended to run single widget/unit tests for a Flutter project.\\n- **Flutter Drive** was originally intended to run integration tests *on a device or an emulator*.\\n\\nHowever, in recent releases these lines have become blurred. The new [integration_test](https://docs.flutter.dev/testing/integration-tests) package that comes built into newer Flutter releases has support for both `flutter drive` and `flutter test`. This was a great change because it decreases the required overhead to run larger integration tests (`flutter drive` sets up a host-controller model that requires a dedicated control channel to be setup, whereas `flutter test` can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).\\n\\nThere is thankfully code in the `flutter_gherkin` repository that supports running tests with `flutter test`, however this code currently has a few issues:\\n\\n- The test code generation produces code that doesn\'t compile without minor changes.\\n- Certain functionality like \\"take a screenshot\\" does not work on desktop.\\n\\nAdditionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:\\n\\n- Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.\\n- Certain Flutter widgets like `DropdownButton` are not compatible with built-in steps like `tap` because they internally contain multiple copies of the same widget.\\n\\nBecause of the above issues we have chosen to [fork flutter_gherkin](https://git.openprivacy.ca/openprivacy/flutter_gherkin) to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.\\n\\n## Integrating Tests into the Pipeline\\n\\nOne of the major limitations of `flutter test` is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.\\n\\nThankfully it is possible to use [Xfvb](https://en.wikipedia.org/wiki/Xvfb) to create a virtual framebuffer, and set `DISPLAY` to render to that buffer:\\n\\n export DISPLAY=:99\\n Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\\n\\nThis allows us to neutralize our main issue with `flutter test`, and efficiently run tests in our pipeline.\\n\\n## Catching Bugs!\\n\\nThis small amount of integration work has already caught its first bug.\\n\\nOnce we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. [02_save_load.feature](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature) simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.\\n\\nThe cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory `$USER_HOME/Downloads` didn\'t exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.\\n\\nAs we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!\\n\\n## Next Steps\\n\\n- **More automated tests:** We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.\\n- **More platforms:** Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across [our target platforms](https://docs.cwtch.im/docs/getting-started/supported_platforms). We expect to start this work soon; expect more news in a future Cwtch Testing update!\\n\\n- **More steps:** One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the `expect to see the message` step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. `send a file` or `set profile picture`.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-platform-support","metadata":{"permalink":"/de/blog/cwtch-platform-support","source":"@site/blog/2023-01-27-platform-support.md","title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","date":"2023-01-27T00:00:00.000Z","formattedDate":"27. Januar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"support","permalink":"/de/blog/tags/support"}],"readingTime":10.535,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","slug":"cwtch-platform-support","tags":["cwtch","cwtch-stable","support"],"image":"/img/devlog4_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing","permalink":"/de/blog/cwtch-testing-i"},"nextItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/de/blog/cwtch-bindings-reproducible"}},"content":"One of the [tenets for Cwtch Stable is **Universal Availability and Cohesive Support**](https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable):\\n\\n> \\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\"\\n\\nThis development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.\\n\\nThe questions we aim to answer in this post are: \\n\\n- What systems do we currently support?\\n- How do we decide what systems are supported?\\n- How do we handle new OS versions?\\n- How does application support differ from library support?\\n- What blockers exist for systems we wish to support, but currently cannot e.g ios?\\n\\n![](/img/devlog4.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Constraints on support\\n\\nFrom CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. \\n\\nIn this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.\\n\\n### Limitations on general-purpose computing \\n\\nIn order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to *other* onion services). \\n\\nOn desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, **blocked entirely**. \\n\\nThis is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.\\n\\nWhile we expect that [Arti](https://gitlab.torproject.org/tpo/core/arti) will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. \\n\\nAs Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.\\n\\nWe encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don\'t place restrictions on what you can do with your own device.\\n\\n### Constraints introduced by the Flutter SDK\\n\\nThe Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by [platforms that are supported by the Flutter SDK](https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms).\\n\\nTo summarize, as of writing this document those platforms are:\\n\\n- Android API 16 and above (arm, arm64, and amd64)\\n- Debian-based Linux Distributions (64-bit only)\\n- macOS El Capitan (10.11) and above\\n- Windows 7 & above (64-bit only)\\n\\nTo put it plainly, without porting Cwtch UI to a different UI platform **we cannot support a 32-bit desktop version**.\\n\\n### Constraints introduced by Appstore Policy \\n\\nAs of writing, [Google is pushing applications to target API 31 or above](https://developer.android.com/google/play/requirements/target-sdk). This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.\\n\\n### CPU Architecture and Cwtch Bindings\\n\\nWe currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.\\n\\nIt is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.\\n\\n| Architecture / Platform | Windows | Linux | macOS | Android |\\n|--------------------------|---------|-----|-------| -------------|\\n| arm | \u274c | \u274c | \u274c | \u2705\ufe0f| \\n| arm64 | \u274c | \ud83d\udfe1 | \u2705 | \u2705\ufe0f | \\n| x86-64 / amd64 | \u2705 | \u2705 | \u2705\ufe0f | \u2705\ufe0f |\\n\\n\\"\ud83d\udfe1\\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).\\n\\n### Testing and official support\\n\\nAs a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the [Cwtch Release Candidate Testers](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.\\n\\nWe officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.\\n\\n### End-of-life platforms\\n\\nOperating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. [Windows 7 fell out of support on January 14, 2020](https://www.microsoft.com/en-us/windows/end-of-support), Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.\\n\\nLikewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.\\n\\nThe same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. [Cwtch currently requires libc 2.31+](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations).\\n\\nAndroid versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our [Cwtch Release Candidate Testers groups](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to help us understand the limitations of Android support across different API versions.\\n\\n## How we decide to officially support a platform\\n\\nTo help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:\\n\\n1. **The target platform needs to be officially supported by our development tools** - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.\\n2. **The target operating system needs to be supported by the Vendor** - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).\\n3. **The target platform must be backwards compatible with the most recent version in general use** - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch *may* run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).\\n4. **People want to use Cwtch on that platform** - We will generally only consider new platform support if people ask us about it. If Cwtch isn\'t available for a platform you want to use it on, then please get in touch and ask us about it!\\n\\n## Summary of official support\\n\\nThe table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). \\n\\nIn many cases we are looking for testers to confirm that various functionality works. A version of this table will be [maintained as part of the Cwtch Handbook](/docs/getting-started/supported_platforms).\\n\\n**Legend:**\\n\\n- \u2705: **Officially Supported**. Cwtch should work on these platforms without issue. Regressions are treated as high priority.\\n- \ud83d\udfe1: **Best Effort Support**. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.\\n- \u274c: **Not Supported**. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.\\n\\n\\n\\n| Platform | Official Cwtch Builds | Source Support | Notes |\\n|-----------------------------|-----------------------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------|\\n| Windows 11 | \u2705 | \u2705 | 64-bit amd64 only. |\\n| Windows 10 |\u2705 | \u2705 | 64-bit amd64 only. Not officially supported, but official builds may work. |\\n| Windows 8 and below | \u274c | \ud83d\udfe1 | Not supported. Dedicated builds from source may work. Testing Needed. |\\n| OSX 10 and below | \u274c | \ud83d\udfe1 | 64-bit Only. Official builds have been reported to work on Catalina but not High Sierra |\\n| OSX 11 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 12 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 13 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| Debian 11 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Debian 10 | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. |\\n| Debian 9 and below | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies. |\\n| Ubuntu 22.04 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Other Ubuntu | \ud83d\udfe1 | \u2705 | 64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies. | \\n| CentOS | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Gentoo | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Arch | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Whonix | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support. ](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550) |\\n| Raspian (arm64) | \ud83d\udfe1 | \u2705 | Builds from source work. |\\n| Other Linux Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Android 9 and below | \ud83d\udfe1 | \ud83d\udfe1 | Official builds may work. |\\n| Android 10 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 11 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 12 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 13 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| LineageOS | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support.](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607) |\\n| Other Android Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-bindings-reproducible","metadata":{"permalink":"/de/blog/cwtch-bindings-reproducible","source":"@site/blog/2023-01-20-reproducible-builds-bindings.md","title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","date":"2023-01-20T00:00:00.000Z","formattedDate":"20. Januar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/de/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/de/blog/tags/bindings"},{"label":"repliqate","permalink":"/de/blog/tags/repliqate"}],"readingTime":7.915,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","slug":"cwtch-bindings-reproducible","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog3_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch UI Platform Support","permalink":"/de/blog/cwtch-platform-support"},"nextItem":{"title":"Cwtch Stable API Design","permalink":"/de/blog/cwtch-stable-api-design"}},"content":"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.\\n\\nBut open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.\\n\\nThe whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can **independently verify** that the binaries we release are built from the Cwtch source code.\\n\\nIn this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.\\n\\n\x3c!--truncate--\x3e\\n\\n## How Cwtch Bindings are Built\\n\\nSince we launched Cwtch Beta we have used Docker containers as part of our continuous build process.\\n\\nWhen a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.\\n\\nThe Cwtch Bindings build pipeline results in four compiled libraries:\\n\\n- **libcwtch.so** \u2013 For Linux Platforms, built using the [official golang:1.19.X Docker Image](https://hub.docker.com/_/golang)\\n- **libcwtch.dll** \u2013 For Windows Platforms, built using our own [mingw-go Docker Image](https://git.openprivacy.ca/openprivacy/mingw-go)\\n- **libcwtch.ld** \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)\\n- **cwtch.aar** \u2013 For Android Platforms, built using our own [Android/GoMobile Docker Image](https://git.openprivacy.ca/openprivacy/android-go-mobile)\\n\\nThese compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.\\n\\n## Making libCwtch Reproducible\\n\\nDocker containers alone aren\'t enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:\\n\\n* **Go Build ID**: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.\\n* **Build Paths and Go Environment Variables**: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the `trimPath` option, which we now specify for all bindings builds.\\n\\n### Linux Specific Considerations\\n\\nAfter the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.\\n\\nOur Drone/Docker build environments are based on [Debian Bullseye](https://www.debian.org/releases/bullseye/) which provides [libc6-dev version 2.31](https://packages.debian.org/bullseye/i386/libc6-dev). Other development setups will likely link libc-dev 2.34+.\\n\\nlibc6-dev 2.34 is notable [because it removed dependencies on libpthread and libdl](https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread) \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.\\n\\nThis means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on [Next Steps](#next-steps) for more information).\\n\\n### Windows Specific Considerations\\n\\nThe headers of PE files technically contain a timestamp field. In recent years an [effort has been made to use this field for other purposes](https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705), but by default `go build` will still include the timestamp of the file when producing a DLL file (at least when using CGO).\\n\\nFortunately this field can be zeroed out through passing `-Xlinker \u2013no-insert-timestamp` into the `mingw32-gcc` process.\\n\\nWith that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.\\n\\n\\n### Android Specific Considerations\\n\\nWith the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:\\n\\n* Cwtch makes use of [GoMobile](https://github.com/golang/mobile) for compiling Android libraries. We pin to a specific version `43a0384520996c8376bfb8637390f12b44773e65` in our Docker containers. Unlike `go build`, the `trimpPath` parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized `/tmp/go-build*` references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.\\n* We still use [sdk-tools](https://developer.android.com/studio/releases/sdk-tools) instead of the new [commandline-tools](https://developer.android.com/studio/command-line). The latest version of sdk-tools is `4333796` and available from: [https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip](https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip). As part of our plans for Cwtch Stable we will be updating this dependency.\\n* Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated `openjdk:8` image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. \\n\\nAll of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.\\n\\n### OSX Specific Considerations\\n\\nPerhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.\\n\\nAs with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.\\n\\nIn order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.\\n\\nIn an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a [proprietary SDK](https://www.apple.com/legal/sla/docs/xcode.pdf). There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.\\n\\nBecause of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.\\n\\n## Introducing Repliqate!\\n\\nWith all the above changes, **Cwtch Bindings for Linux and Windows are fully reproducible!**\\n\\nThat alone is great, but we also want to make it easier for **you** to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.\\n\\nTo make this process accessible we are releasing a new tool called [repliqate](https://git.openprivacy.ca/openprivacy/repliqate).\\n\\nRepliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.\\n\\nRepliqate runs [build-scripts](https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script) to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from [builds.openprivacy.ca](https://build.openprivacy.ca/files/).\\n\\nWe now provide [Repliqate build-scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts) for reproducible both [Linux libCwtch.so builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script), [Windows libCwtch.dll builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script)!\\n\\nWe also have a partially repeatable [Android cwtch.aar build](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script) script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.\\n\\nYou can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.\\n\\n## Next Steps\\n\\nReproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.\\n\\nAs we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-api-design","metadata":{"permalink":"/de/blog/cwtch-stable-api-design","source":"@site/blog/2023-01-13-cwtch-stable-api-design.md","title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","date":"2023-01-13T00:00:00.000Z","formattedDate":"13. Januar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/de/blog/tags/planning"},{"label":"api","permalink":"/de/blog/tags/api"}],"readingTime":17.28,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","slug":"cwtch-stable-api-design","tags":["cwtch","cwtch-stable","planning","api"],"image":"/img/devlog2_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/de/blog/cwtch-bindings-reproducible"},"nextItem":{"title":"Path to Cwtch Stable","permalink":"/de/blog/path-to-cwtch-stable"}},"content":"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. \\n\\nAs we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.\\n\\nAs we move out of Beta and [towards Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable) it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.\\n\\nIn this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.\\n\\n![](/img/devlog2.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Clarifying Terminology\\n\\nOver the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:\\n\\n- **Cwtch** refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. \\n- **Cwtchlib** refers to the [reference implementation of the Cwtch Protocol](https://git.openprivacy.ca/cwtch.im/cwtch) / Application framework, currently written in Go.\\n- **Bindings** refers to C/Java/Kotlin/Rust bindings (primarily [libcwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go)) that act as an interface between Cwtchlib and downstream applications.\\n- `CwtchPeer` is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).\\n- `ProtocolEngine` is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, `ProtocolEngine` is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.\\n\\n\\n### Tenets of the Cwtch API Design\\n\\nBased on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:\\n\\n- **Robustness** - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.\\n- **Completeness** - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.\\n- **Security** \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.\\n\\n### The Cwtch Experiment Landscape\\n\\nA summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.\\n\\n- **Groups** \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized `ProtocolEngine` functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. \\n - **Hybrid Groups** - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.\\n- **Filesharing** \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in `ProtocolEngine`.\\n- **Profile Images** \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.\\n- **Server Hosting** \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.\\n- **Message Formatting** \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history\\n- **Search / Microblogging** \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.\\n- **Status / Profile Metadata** \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.\\n\\n### The Problem with Experiments\\n\\nWe have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the `SendMessages` interface that only allows callers to send messages.\\n\\nWe have also worked to package experimental functionality into so-called **Gated Functionalities** that are only available if a given experiment is turned on.\\n\\nTogether, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:\\n\\n- The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. `SendMessages` \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).\\n- The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.\\n- This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.\\n\\n### Restricting Powerful Cwtch APIs\\n\\nTo carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:\\n\\n- Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through `Application` and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.\\n- Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a `RestrictedCwtchConversationInterface` which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact.\\n- Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow `CwtchPeer` to control which experiments get access to which events at a given time.\\n\\n#### Pre-Registered Hooks\\n\\nIn order to implement certain functionality actions need to take place in-between events handled by `CwtchPeer`. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).\\n\\nThis is currently only possible with invasive changes to the `CwtchPeer` interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.\\n\\nWe are introducing a new set of Cwtch APIs designed for this purpose:\\n\\n- `OnNewPeerMessage` - hooked prior to inserting the message into the database.\\n- `OnPeerMessageConfirmed` \u2013 hooked after a peer message has been inserted into the database.\\n- `OnEncryptedGroupMessage` \u2013 hooked after receiving an encrypted message from a group server.\\n- `OnGroupMessageReceived` \u2013 hooked after a successful decryption of a group message, but before inserting it into the database.\\n- `OnContactRequestValue` \u2013 hooked on request of a scoped (the permission level of the attribute e.g. `public` or `conversation` level attributes), zoned ( relating to a specific feature e.g. `filesharing` or `chat`), and keyed (the name of the attribute e.g. `name` or `manifest`) value from a contact.\\n- `OnContactReceiveValue` \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.\\n\\nIncluding the following APIs for managing hooked functionality:\\n\\n- `RegisterEvents` - returns a set of events that the extension is interested processing.\\n- `RegisterExperiments` - returns a set of experiments that the extension is interested in being notified about\\n- `OnEvent` - to be called by `CwtchPeer` whenever an event registered with `RegisterEvents` is called (assuming all experiments registered through `RegisterExperiments` is active)\\n\\n#### `ProtocolEngine` Subsystems\\n\\nAs mentioned in our experiment summary, some functionality needs to be implemented directly in the `ProtocolEngine`. The `ProtocolEngine` is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).\\n\\nSome types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a `ProtocolEngine`.\\n\\nAt the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to `ProtocolEngine` that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider `ProtocolEngine` ecosystem. \\n\\nWe are formalizing this subsystem into an interface, similar to the hooked functionality in `CwtchPeer`:\\n\\n- `RegisterEvents` - returns a set of events that the subsystem needs to consume to operate.\\n- `OnEvent` \u2013 to be called by `ProtocolEngine` whenever an event registered with `RegisterEvents` is called (when all the experiments registered through `RegisterExperiments` are active)\\n- `RegisterContexts` - returns the set of contexts that the subsystem implements e.g. `im.cwtch.filesharing`\\n\\nThis also requires a formalization of two *engine specific* events (for use on the event bus):\\n\\n- `SendCwtchMessage` \u2013 encapsulating the existing `CwtchPeerMessage` that is used internally in `ProtocolEngine` for messages between subsystems.\\n- `CwtchMessageReceived` \u2013 encapsulating the existing `handlePeerMessage` function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.\\n\\nAnd the introduction of three **additional** `ProtocolEnine` specific events:\\n\\n- `StartEngineSubsystem` \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.\\n- `StopEngineSubsystem` \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.\\n- `SubsystemStatus` \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging\\n\\nThis will allow us to move the following functionality, currently part of `ProtocolEngine` itself, into generic subsystems:\\n\\n- **Attribute Lookup Handling** - this functionality is currently part of the overloaded `handlePeerMessage` function, filtered using the `Context` parameter of the `CwtchPeerMessage`. As such it can be entirely delegated to a subsystem. \\n- **Filesharing Chunk Request Handling** \u2013 this is also part of handlePeerMessage, also filtered using the `Context` parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by `handlePeerMessage`)\\n- **Filesharing Start File Share/Stop File Share** \u2013 this is currently part of the `handleEvent` behaviour of `ProtocolEngine` and can be moved into an `OnEvent` handler of the file sharing subsystem (where such events are already processed).\\n\\nThe introduction of pre-registered hooks in combination with the formalizations of `ProtocolEngine` subsystems will allow the follow functionality, currently implemented in `CwtchPeer` or libcwtch-go to be moved to standalone packages:\\n\\n- **Filesharing** makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. \\n - Filesharing also depends on the file sharing subsystem to be enabled in a `ProtocolEngine`. This subsystem is responsible for processing chunk requests.\\n- **Profile Images** \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)\\n- **Legacy Groups** \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.\\n- **Status/Profile Metadata** \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.\\n \\n#### Impact on Enabling (Powerful) New Functionality\\n\\nNone of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:\\n\\n- **Search** \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.\\n- **Non Chat Conversation Contexts** - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.\\n\\n## Application Experiments\\n\\nOne kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers.\\n\\nThis kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library.\\n\\nThis functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.\\n\\n## Bindings\\n\\nThe last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.\\n\\nWe can split the bindings into four core areas:\\n\\n- **Application Management** - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.\\n- **Application Experiments** - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.\\n- **Core Profile Management** - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.\\n- **Experimental Profile Features** \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.\\n\\nThe flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.\\n\\nIn an ideal future, all of these bindings could be **generated automatically** from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)\\n\\nWe can define three types of C/Java/Kotlin interface function templates:\\n\\n- `ProfileMethodName(profilehandle String, args...)` \u2013 which directly resolves the Cwtch Profile and calls the function.\\n- `ProfileExperimentalMethodName(profilehandle String, args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.\\n- `ApplicationExperimentalMethodName(args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.\\n\\nAll we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context `ProfileInterface` for the first, exported methods of the various `Functionalities` for the second, and `ApplicationExperiment` definitions for the third.\\n\\n## Timelines and Next Actions\\n\\n- **Freeze any changes to the bindings interface** - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib.\\n- As part of Cwtch 1.11 and 1.12 Release Cycles\\n - Implement the `ProtocolEngine` Subsystem Design as outlined above.\\n - Implement the Hooks API.\\n - Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting).\\n - Move event handling from the bindings into Application.\\n - Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions.\\n- Once Automated UI Tests have been integrated into the Cwtch UI Repository:\\n - Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings **and** a dart calling convention library from cwtchlib and any configured application experiments libraries\\n - Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).\\n - At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)\\n\\n## Appendix A: Special Behaviour Defined by libcwtch-go\\n\\nThe following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:\\n\\n- Application Settings\\n - Including Enabling / Disabling Experiment\\n- ACN Process Management - starting/stopping/restarting/configuring Tor.\\n- Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)\\n- Logging Levels - configuring appropriate logging levels (e.g. `INFO` or `DEBUG`)\\n- Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.\\n- UI Contact Structures - aggregating contact information for the main Cwtch UI.\\n- Group Experiment Functionality\\n - Experiment Gating\\n - GetServerInfoList\\n - GetServerInfo\\n - UI Server Struct Definition\\n- Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.\\n- \\"Unencrypted\\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \\"unencrypted\\".\\n- Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).\\n- Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.\\n- Cwtch Profile Engine Activation - starting/stopping a `ProtocolEngine` when requested by the UI, or in response to changes in ACN state.\\n- UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.\\n- File sharing restarts \\n- UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn\'t directly embedded within the event (e.g. converting `handle` to a `conversation id`). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.\\n- Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)"},{"id":"path-to-cwtch-stable","metadata":{"permalink":"/de/blog/path-to-cwtch-stable","source":"@site/blog/2023-01-06-path-to-cwtch-stable.md","title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","date":"2023-01-06T00:00:00.000Z","formattedDate":"6. Januar 2023","tags":[{"label":"cwtch","permalink":"/de/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/de/blog/tags/planning"}],"readingTime":9.995,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","slug":"path-to-cwtch-stable","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable API Design","permalink":"/de/blog/cwtch-stable-api-design"}},"content":"As of December 2022 we have released 10 versions of Cwtch Beta since the [initial launch, 18 months ago, in June 2021](https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/).\\n\\nThere is a consensus among the team that the next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable.\\n\\nThis post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.\\n\\n![](/img/devlog1.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Tenets of Cwtch Stable\\n\\nIt is important to state that Cwtch Stable **does not mean an end to Cwtch development**. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:\\n\\n1. **Consistent Interface** \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.\\n2. **Universal Availability and Cohesive Support** \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\n3. **Reproducible Builds** \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.\\n4. **Proven Security** \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.\\n\\n### Known Problems\\n\\nTo begin, let\'s outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.\\n\\n1. **Lack of a Stable API for future feature development** \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)\\n2. **Special functionality in libCwtch-go** \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)\\n3. **libCwtch-rs partial support** - we currently do not officially consider [libCwtch-rs](https://lib.rs/crates/libcwtch) when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)\\n4. **Lack of Reproducible Pipelines** - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)\\n5. **Lack of up to date, and translated, Security Documentation** \u2013 the [Cwtch security handbook](https://docs.openprivacy.ca/cwtch-security-handbook/) is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)\\n6. **No Automated UI Tests** \u2013 we put a lot of work into [building out a testing framework for the UI](https://openprivacy.ca/discreet-log/23-cucumber-testing/), but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)\\n7. **Code Signing Provider** \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)\\n8. **Second-class Android Support** - while we have put [a lot of effort behind Android support](https://openprivacy.ca/discreet-log/27-android-improvements/) across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)\\n9. **Lack of Fuzzing** \u2013 while [Fuzzbot](https://openprivacy.ca/discreet-log/07-fuzzbot/) sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)\\n10. **Lack of Formal Release Acceptance Process** \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)\\n11. **Inconsistent Cwtch Information Discovery** \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)\\n12. **Incomplete Documentation** \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)\\n\\n### Plan of Action\\n\\nOutside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:\\n\\n1. **Define, Publish, and Implement a Cwtch Interface Specification Documentation** \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)\\n2. **Define, Publish, and Implement a Cwtch Release Process** \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)\\n3. **Define, Publish, and Implement a Cwtch Support Document** - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)\\n4. **Define, Publish, and Implement a Cwtch Packaging Document** - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)\\n5. **Define, Publish, and Implement a Reproducible Builds Document** \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)\\n6. **Expand the Cwtch Documentation Site** \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)\\n7. **Expand our Automated Testing to include UI and Fuzzing** - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)\\n8. **Re-evaluate all Issues across all Cwtch related repositories** \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.\\n9. **Define a Stable Feature Set** \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)\\n\\n### Goals and Timelines\\n\\nWith all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:\\n\\n1. By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).\\n2. By **1st February 2023**, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.\\n3. By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.\\n4. By **31st March 2023**, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).\\n5. By **31st March 2023** the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.\\n6. By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.\\n7. By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.\\n8. By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.\\n\\nAs these documents are written, and these goals met we will be posting them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, Cwtch development.\\n\\n### Help us get there!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"}]}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/2bb9f32f.067a6a9d.js b/build-staging/de/assets/js/2bb9f32f.067a6a9d.js new file mode 100644 index 00000000..183eb4f9 --- /dev/null +++ b/build-staging/de/assets/js/2bb9f32f.067a6a9d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9162],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),d=p(r),m=o,f=d["".concat(c,".").concat(m)]||d[m]||l[m]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[d]="string"==typeof e?e:o,s[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:9},s="QR Codes",a={unversionedId:"settings/experiments/qrcodes",id:"settings/experiments/qrcodes",title:"QR Codes",description:"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem du es mit vergr\xf6\xdferst.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/qrcodes.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/qrcodes",permalink:"/de/docs/settings/experiments/qrcodes",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/qrcodes.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{sidebar_position:9},sidebar:"tutorialSidebar",previous:{title:"Nachrichtenformatierung",permalink:"/de/docs/settings/experiments/message-formatting"},next:{title:"Tor",permalink:"/de/docs/tor"}},c={},p=[],u={toc:p},d="wrapper";function l(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"qr-codes"},"QR Codes"),(0,o.kt)("admonition",{title:"Info",type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/326317af.7d99625d.js b/build-staging/de/assets/js/326317af.7d99625d.js new file mode 100644 index 00000000..5fb6407e --- /dev/null +++ b/build-staging/de/assets/js/326317af.7d99625d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5733],{5571:e=>{e.exports=JSON.parse('{"label":"libcwtch","permalink":"/de/blog/tags/libcwtch","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/373c7d5f.5c158d00.js b/build-staging/de/assets/js/373c7d5f.5c158d00.js new file mode 100644 index 00000000..c09bd7f2 --- /dev/null +++ b/build-staging/de/assets/js/373c7d5f.5c158d00.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9085],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=i,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:2},a="Wie man einen Server erstellt",s={unversionedId:"servers/create-server",id:"servers/create-server",title:"Wie man einen Server erstellt",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/create-server.md",sourceDirName:"servers",slug:"/servers/create-server",permalink:"/de/docs/servers/create-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/create-server.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Server Einf\xfchrung",permalink:"/de/docs/servers/introduction"},next:{title:"Wie man einen Server bearbeitet",permalink:"/de/docs/servers/edit-server"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"wie-man-einen-server-erstellt"},"Wie man einen Server erstellt"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," eingeschaltet ist.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zum Server-Symbol gehen"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke den + Action-Button, um einen neuen Server zu erstellen"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle einen Namen f\xfcr deinen Server"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle ein Passwort f\xfcr deinen Server"),(0,i.kt)("li",{parentName:"ol"},'Klicke auf "Server hinzuf\xfcgen"')),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Server_New.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/37c407d1.d2079a43.js b/build-staging/de/assets/js/37c407d1.d2079a43.js new file mode 100644 index 00000000..5d268bb7 --- /dev/null +++ b/build-staging/de/assets/js/37c407d1.d2079a43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2612],{4517:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/nightly","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/39333829.65f7ccd9.js b/build-staging/de/assets/js/39333829.65f7ccd9.js new file mode 100644 index 00000000..7a2c551b --- /dev/null +++ b/build-staging/de/assets/js/39333829.65f7ccd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2708],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>m});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},u=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=a,m=p["".concat(l,".").concat(h)]||p[h]||d[h]||i;return t?r.createElement(m,o(o({ref:n},u),{},{components:t})):r.createElement(m,o({ref:n},u))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,o=new Array(i);o[0]=h;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[p]="string"==typeof e?e:a,o[1]=s;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=t(7462),a=(t(7294),t(3905));const i={sidebar_position:1},o="Cwtch in Tails laufen lassen",s={unversionedId:"platforms/tails",id:"platforms/tails",title:"Cwtch in Tails laufen lassen",description:"Diese Funktionalit\xe4t ist derzeit nur verf\xfcgbar in den N\xe4chtlichen Release Builds von Cwtch.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/platforms/tails.md",sourceDirName:"platforms",slug:"/platforms/tails",permalink:"/de/docs/platforms/tails",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/platforms/tails.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Platforms",permalink:"/de/docs/category/platforms"}},l={},c=[{value:"Onion Grater Konfiguration",id:"onion-grater-konfiguration",level:2},{value:"Dauerhaft",id:"dauerhaft",level:2}],u={toc:c},p="wrapper";function d(e){let{components:n,...t}=e;return(0,a.kt)(p,(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cwtch-in-tails-laufen-lassen"},"Cwtch in Tails laufen lassen"),(0,a.kt)("admonition",{title:"Warnung Feature des n\xe4chtlichen Releases",type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"Diese Funktionalit\xe4t ist derzeit ",(0,a.kt)("strong",{parentName:"p"},"nur ")," verf\xfcgbar in den ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"N\xe4chtlichen Release")," Builds von Cwtch."),(0,a.kt)("p",{parentName:"admonition"},"Diese Funktionalit\xe4t kann unvollst\xe4ndig und/oder gef\xe4hrlich sein, wenn sie falsch benutzt wird. Bitte hilf uns bei der \xdcberpr\xfcfung und dem Test.")),(0,a.kt)("p",null,"Die folgenden Schritte erfordern, dass Tails mit einem ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/first_steps/welcome_screen/administration_password/"},"Administrationspasswort gestartet wurde"),"."),(0,a.kt)("p",null,"Tails verwendet ",(0,a.kt)("a",{parentName:"p",href:"https://gitlab.tails.boum.org/tails/tails/-/blob/master/config/chroot_local-includes/usr/local/lib/onion-grater#L3"},"Onion Grater")," um den Zugriff auf den Kontrollport zu sch\xfctzen. Wir haben eine Onion Gratar Konfiguration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," paketiert und ein Skript (",(0,a.kt)("inlineCode",{parentName:"p"},"install-tails.sh"),") mit dem Cwtch unter Linux eingerichtet."),(0,a.kt)("p",null,"Der Tails-spezifische Teil des Skripts wird unten reproduziert:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," # Tails needs to be have been setup up with an Administration account\n # \n # Make Auth Cookie Readable\n sudo chmod o+r /var/run/tor/control.authcookie\n # Copy Onion Grater Config\n sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml\n # Restart Onion Grater so the Config Takes effect\n sudo systemctl restart onion-grater.service\n")),(0,a.kt)("p",null,"Beim Start sollte Cwtch auf Tails die ",(0,a.kt)("inlineCode",{parentName:"p"},"CWTCH_TAILS=true")," Umgebungsvariable \xfcbergeben werden, um Cwtch automatisch f\xfcr die Ausf\xfchrung in einer Tails-\xe4hnlichen Umgebung zu konfigurieren:"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch")),(0,a.kt)("admonition",{title:"Installationsort",type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Der obige Befehl und die unten stehende Onion Gratar Konfiguration gehen davon aus, dass Cwtch in ",(0,a.kt)("inlineCode",{parentName:"p"},"~/.local/lib/cwtch/cwtch")," installiert wurde - wenn Cwtch irgendwo anders installiert wurde (oder wenn Du es direkt aus dem Download-Ordner laufen l\xe4sst) musst du die Befehle anpassen.")),(0,a.kt)("h2",{id:"onion-grater-konfiguration"},"Onion Grater Konfiguration"),(0,a.kt)("p",null,"Die Onion Gratar Konfiguration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," wird unten reproduziert. Wie erw\xe4hnt, kann diese Konfiguration wahrscheinlich noch viel weiter eingeschr\xe4nkt werden. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," ---\n # TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern\n\n - apparmor-profiles:\n - '/home/amnesia/.local/lib/cwtch/cwtch'\n users:\n\n - 'amnesia'\n commands:\n AUTHCHALLENGE:\n\n - 'SAFECOOKIE .*'\n SETEVENTS:\n\n - 'CIRC WARN ERR'\n - 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'\n GETINFO:\n\n - '.*'\n GETCONF:\n\n - 'DisableNetwork'\n SETCONF:\n\n - 'DisableNetwork.*'\n ADD_ONION:\n\n - '.*'\n DEL_ONION:\n\n - '.+'\n HSFETCH:\n\n - '.+'\n events:\n CIRC:\n suppress: true\n ORCONN:\n suppress: true\n INFO:\n suppress: true\n NOTICE:\n suppress: true\n WARN:\n suppress: true\n ERR:\n suppress: true\n HS_DESC:\n response:\n\n - pattern: '650 HS_DESC CREATED (\\S+) (\\S+) (\\S+) \\S+ (.+)'\n replacement: '650 HS_DESC CREATED {} {} {} redacted {}'\n\n - pattern: '650 HS_DESC UPLOAD (\\S+) (\\S+) .*'\n replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'\n\n - pattern: '650 HS_DESC UPLOADED (\\S+) (\\S+) .+'\n replacement: '650 HS_DESC UPLOADED {} {} redacted'\n\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH'\n\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'\n\n - pattern: '650 HS_DESC RECEIVED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'\n\n - pattern: '.*'\n replacement: ''\n HS_DESC_CONTENT:\n suppress: true\n")),(0,a.kt)("h2",{id:"dauerhaft"},"Dauerhaft"),(0,a.kt)("p",null,"Standardm\xe4\xdfig erstellt Cwtch ",(0,a.kt)("inlineCode",{parentName:"p"},"$HOME/.cwtch")," und speichert dort alle verschl\xfcsselten Profile und Einstellungsdateien. Um Profil/Konversationen in Cwtch auf Tails zu speichern, musst du diesen Ordner in einem nicht fl\xfcchtigen Zuhause sichern."),(0,a.kt)("p",null,"Siehe Tails Dokumentation zum Einrichten von ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/persistent_storage/"},"Dauerhaftem Speicher")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/3a109bd3.5c0e28ac.js b/build-staging/de/assets/js/3a109bd3.5c0e28ac.js new file mode 100644 index 00000000..a54e9589 --- /dev/null +++ b/build-staging/de/assets/js/3a109bd3.5c0e28ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7782],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>g});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),p=s(n),h=o,g=p["".concat(l,".").concat(h)]||p[h]||u[h]||a;return n?r.createElement(g,i(i({ref:t},m),{},{components:n})):r.createElement(g,i({ref:t},m))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:o,i[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/de/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"10. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/de/blog/tags/documentation"},{label:"security-handbook",permalink:"/de/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/de/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/de/blog/autobindings-ii"}},l={authorsImageUrls:[void 0]},s=[],m={toc:s},p="wrapper";function u(e){let{components:t,...a}=e;return(0,o.kt)(p,(0,r.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/3c1e1d04.a4fd9050.js b/build-staging/de/assets/js/3c1e1d04.a4fd9050.js new file mode 100644 index 00000000..86be23fd --- /dev/null +++ b/build-staging/de/assets/js/3c1e1d04.a4fd9050.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[563],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var a=n.createContext({}),c=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},p=function(e){var r=c(e.components);return n.createElement(a.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(t),d=o,m=u["".concat(a,".").concat(d)]||u[d]||f[d]||i;return t?n.createElement(m,s(s({ref:r},p),{},{components:t})):n.createElement(m,s({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=d;var l={};for(var a in r)hasOwnProperty.call(r,a)&&(l[a]=r[a]);l.originalType=e,l[u]="string"==typeof e?e:o,s[1]=l;for(var c=2;c{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:5},s="Verschl\xfcsselte Profile entsperren",l={unversionedId:"profiles/unlock-profile",id:"profiles/unlock-profile",title:"Verschl\xfcsselte Profile entsperren",description:"Wenn du Cwtch neu startest und ein Passwort in deinem Profil benutzst, dann wird es nicht als Standard geladen, sondern Du musst es erst entsperren.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/unlock-profile.md",sourceDirName:"profiles",slug:"/profiles/unlock-profile",permalink:"/de/docs/profiles/unlock-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/unlock-profile.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Dein Profilbild \xe4ndern",permalink:"/de/docs/profiles/change-profile-image"},next:{title:"Ein Profil l\xf6schen",permalink:"/de/docs/profiles/delete-profile"}},a={},c=[],p={toc:c},u="wrapper";function f(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"verschl\xfcsselte-profile-entsperren"},"Verschl\xfcsselte Profile entsperren"),(0,o.kt)("p",null,"Wenn du Cwtch neu startest und ein ",(0,o.kt)("a",{parentName:"p",href:"/docs/profiles/change-password/"},"Passwort")," in deinem Profil benutzst, dann wird es nicht als Standard geladen, sondern Du musst es erst entsperren."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Dr\xfccke das rosa Entsperr-Symbol ",(0,o.kt)("img",{src:"/img/lock_open-24px.webp",className:"ui-button",alt:"Entsperr-Symbol"})),(0,o.kt)("li",{parentName:"ol"},"Kennwort eingeben"),(0,o.kt)("li",{parentName:"ol"},'Klicke auf "Profil entsperren"')),(0,o.kt)("p",null,"Siehe auch: ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Cwtch Sicherheits-Handbuch: Profil Verschl\xfcsselung & Speicher")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/3db42865.27ab3fca.js b/build-staging/de/assets/js/3db42865.27ab3fca.js new file mode 100644 index 00000000..c1f2d599 --- /dev/null +++ b/build-staging/de/assets/js/3db42865.27ab3fca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7139],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/3e3471db.9ff1a319.js b/build-staging/de/assets/js/3e3471db.9ff1a319.js new file mode 100644 index 00000000..ba5a9e08 --- /dev/null +++ b/build-staging/de/assets/js/3e3471db.9ff1a319.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8510],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function l(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),s=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):l(l({},r),e)),t},p=function(e){var r=s(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=s(t),d=i,m=u["".concat(c,".").concat(d)]||u[d]||f[d]||o;return t?n.createElement(m,l(l({ref:r},p),{},{components:t})):n.createElement(m,l({ref:r},p))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,l=new Array(o);l[0]=d;var a={};for(var c in r)hasOwnProperty.call(r,c)&&(a[c]=r[c]);a.originalType=e,a[u]="string"==typeof e?e:i,l[1]=a;for(var s=2;s{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>l,default:()=>f,frontMatter:()=>o,metadata:()=>a,toc:()=>s});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:6},l="Ein Profil l\xf6schen",a={unversionedId:"profiles/delete-profile",id:"profiles/delete-profile",title:"Ein Profil l\xf6schen",description:"Diese Funktion wird das Schl\xfcsselmaterial unwiderruflich l\xf6schen. Dies kann nicht r\xfcckg\xe4ngig gemacht werden.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/delete-profile.md",sourceDirName:"profiles",slug:"/profiles/delete-profile",permalink:"/de/docs/profiles/delete-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/delete-profile.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Verschl\xfcsselte Profile entsperren",permalink:"/de/docs/profiles/unlock-profile"},next:{title:"Sicherung oder Export eines Profils",permalink:"/de/docs/profiles/exporting-profile"}},c={},s=[],p={toc:s},u="wrapper";function f(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ein-profil-l\xf6schen"},"Ein Profil l\xf6schen"),(0,i.kt)("admonition",{title:"Warnung",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion wird das Schl\xfcsselmaterial ",(0,i.kt)("strong",{parentName:"p"},"unwiderruflich")," l\xf6schen. Dies ",(0,i.kt)("strong",{parentName:"p"},"kann nicht r\xfcckg\xe4ngig gemacht werden"),".")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke den Stift neben dem Profil, das du bearbeiten m\xf6chtest"),(0,i.kt)("li",{parentName:"ol"},"Scrolle nach unten zum Ende des Bildschirms"),(0,i.kt)("li",{parentName:"ol"},"L\xf6schen dr\xfccken"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke wirklich Profil l\xf6schen")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/41944db3.558ad49b.js b/build-staging/de/assets/js/41944db3.558ad49b.js new file mode 100644 index 00000000..927150d5 --- /dev/null +++ b/build-staging/de/assets/js/41944db3.558ad49b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7495],{9212:e=>{e.exports=JSON.parse('{"permalink":"/de/blog","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/de/blog/page/2","blogDescription":"Die neuste Aktualisierung der Cwtch Entwicklung.","blogTitle":"Entwicklungsprotokoll"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4350c8c2.23a8a705.js b/build-staging/de/assets/js/4350c8c2.23a8a705.js new file mode 100644 index 00000000..387916e7 --- /dev/null +++ b/build-staging/de/assets/js/4350c8c2.23a8a705.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9369],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),l=u(r),f=i,h=l["".concat(c,".").concat(f)]||l[f]||d[f]||o;return r?n.createElement(h,s(s({ref:t},p),{},{components:r})):n.createElement(h,s({ref:t},p))}));function h(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,s=new Array(o);s[0]=f;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[l]="string"==typeof e?e:i,s[1]=a;for(var u=2;u{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>u});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:1},s="Server Einf\xfchrung",a={unversionedId:"servers/introduction",id:"servers/introduction",title:"Server Einf\xfchrung",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/introduction.md",sourceDirName:"servers",slug:"/servers/introduction",permalink:"/de/docs/servers/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Servers",permalink:"/de/docs/category/servers"},next:{title:"Wie man einen Server erstellt",permalink:"/de/docs/servers/create-server"}},c={},u=[],p={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(l,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"server-einf\xfchrung"},"Server Einf\xfchrung"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," eingeschaltet ist.")),(0,i.kt)("p",null,"Der Cwtch Kontakt zu Kontakt Chat ist vollst\xe4ndig peer to peer, d. h. wenn ein Teilnehmer offline ist, kannst du mit ihm nicht chatten, und es gibt keinen Mechanismus um mit mehreren Personen zu chatten."),(0,i.kt)("p",null,"Um Gruppenchat (und Offline-Zustellung) zu unterst\xfctzen, haben wir nicht vertrauensw\xfcrdige Cwtch-Server erstellt, die Nachrichten f\xfcr eine Gruppe hosten k\xf6nnen. Die Nachrichten werden mit dem Gruppenschl\xfcssel verschl\xfcsselt und \xfcber fl\xfcchtige Onions abgeholt, so dass der Server keine M\xf6glichkeit hat zu wissen, welche Nachrichten f\xfcr welche Gruppen er hat oder wer darauf zugreift."),(0,i.kt)("p",null,"Derzeit werden Server in der Cwtch-App nur auf der Desktop-Version unterst\xfctzt, da die Internet-Verbindung von mobilen Ger\xe4ten zu instabil und nicht geeignet f\xfcr den Betrieb eines Servers ist."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/43b107c1.11623f77.js b/build-staging/de/assets/js/43b107c1.11623f77.js new file mode 100644 index 00000000..3ce5c18e --- /dev/null +++ b/build-staging/de/assets/js/43b107c1.11623f77.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9200],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),d=i,g=c["".concat(l,".").concat(d)]||c[d]||h[d]||r;return n?a.createElement(g,o(o({ref:t},u),{},{components:n})):a.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/de/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"3. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"support",permalink:"/de/blog/tags/support"},{label:"testing",permalink:"/de/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/de/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/de/blog/cwtch-platform-support"}},l={authorsImageUrls:[void 0]},p=[{value:"Current Limitations of Flutter Gherkin",id:"current-limitations-of-flutter-gherkin",level:2},{value:"Integrating Tests into the Pipeline",id:"integrating-tests-into-the-pipeline",level:2},{value:"Catching Bugs!",id:"catching-bugs",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},c="wrapper";function h(e){let{components:t,...r}=e;return(0,i.kt)(c,(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"We first ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,i.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})),(0,i.kt)("h2",{id:"current-limitations-of-flutter-gherkin"},"Current Limitations of Flutter Gherkin"),(0,i.kt)("p",null,"The original ",(0,i.kt)("a",{parentName:"p",href:"https://pub.dev/packages/flutter_gherkin"},"flutter_gherkin")," is under semi-active development; however, the latest published versions don't support using it with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Test")," was originally intended to run single widget/unit tests for a Flutter project."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Drive")," was originally intended to run integration tests ",(0,i.kt)("em",{parentName:"li"},"on a device or an emulator"),".")),(0,i.kt)("p",null,"However, in recent releases these lines have become blurred. The new ",(0,i.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/testing/integration-tests"},"integration_test")," package that comes built into newer Flutter releases has support for both ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),". This was a great change because it decreases the required overhead to run larger integration tests (",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," sets up a host-controller model that requires a dedicated control channel to be setup, whereas ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible)."),(0,i.kt)("p",null,"There is thankfully code in the ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter_gherkin")," repository that supports running tests with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", however this code currently has a few issues:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The test code generation produces code that doesn't compile without minor changes."),(0,i.kt)("li",{parentName:"ul"},'Certain functionality like "take a screenshot" does not work on desktop.')),(0,i.kt)("p",null,"Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test."),(0,i.kt)("li",{parentName:"ul"},"Certain Flutter widgets like ",(0,i.kt)("inlineCode",{parentName:"li"},"DropdownButton")," are not compatible with built-in steps like ",(0,i.kt)("inlineCode",{parentName:"li"},"tap")," because they internally contain multiple copies of the same widget.")),(0,i.kt)("p",null,"Because of the above issues we have chosen to ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/flutter_gherkin"},"fork flutter_gherkin")," to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing."),(0,i.kt)("h2",{id:"integrating-tests-into-the-pipeline"},"Integrating Tests into the Pipeline"),(0,i.kt)("p",null,"One of the major limitations of ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display."),(0,i.kt)("p",null,"Thankfully it is possible to use ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Xvfb"},"Xfvb")," to create a virtual framebuffer, and set ",(0,i.kt)("inlineCode",{parentName:"p"},"DISPLAY")," to render to that buffer:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"export DISPLAY=:99\nXvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\n")),(0,i.kt)("p",null,"This allows us to neutralize our main issue with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", and efficiently run tests in our pipeline."),(0,i.kt)("h2",{id:"catching-bugs"},"Catching Bugs!"),(0,i.kt)("p",null,"This small amount of integration work has already caught its first bug."),(0,i.kt)("p",null,"Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature"},"02_save_load.feature")," simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment."),(0,i.kt)("p",null,"The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory ",(0,i.kt)("inlineCode",{parentName:"p"},"$USER_HOME/Downloads")," didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available."),(0,i.kt)("p",null,"As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!"),(0,i.kt)("h2",{id:"next-steps"},"Next Steps"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More automated tests:")," We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More platforms:")," Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/getting-started/supported_platforms"},"our target platforms"),". We expect to start this work soon; expect more news in a future Cwtch Testing update!")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More steps:")," One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the ",(0,i.kt)("inlineCode",{parentName:"p"},"expect to see the message")," step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"send a file")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"set profile picture"),"."))),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/43bdde93.aca904f8.js b/build-staging/de/assets/js/43bdde93.aca904f8.js new file mode 100644 index 00000000..6106ad4b --- /dev/null +++ b/build-staging/de/assets/js/43bdde93.aca904f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1197],{5369:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/testing","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4972.486cf118.js b/build-staging/de/assets/js/4972.486cf118.js new file mode 100644 index 00000000..4e318acc --- /dev/null +++ b/build-staging/de/assets/js/4972.486cf118.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4972],{4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});var a=n(7294),o=n(5999),l=n(1944),r=n(7961);function i(){return a.createElement(a.Fragment,null,a.createElement(l.d,{title:(0,o.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4aa555c3.1751a2c9.js b/build-staging/de/assets/js/4aa555c3.1751a2c9.js new file mode 100644 index 00000000..201b2f48 --- /dev/null +++ b/build-staging/de/assets/js/4aa555c3.1751a2c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7797],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),u=n,f=h["".concat(c,".").concat(u)]||h[u]||m[u]||o;return a?r.createElement(f,i(i({ref:t},p),{},{components:a})):r.createElement(f,i({ref:t},p))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"16. Juni 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"release",permalink:"/de/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/de/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/de/blog/cwtch-nightly-v.11-74"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function m(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(159).Z,width:"1004",height:"480"})))}m.isMDXComponent=!0},159:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4d27f429.127d02e8.js b/build-staging/de/assets/js/4d27f429.127d02e8.js new file mode 100644 index 00000000..6c15254f --- /dev/null +++ b/build-staging/de/assets/js/4d27f429.127d02e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[788],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=i.createContext({}),s=function(e){var t=i.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},b=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(r),b=n,h=p["".concat(c,".").concat(b)]||p[b]||d[b]||a;return r?i.createElement(h,o(o({ref:t},u),{},{components:r})):i.createElement(h,o({ref:t},u))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=b;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"20. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/de/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"repliqate",permalink:"/de/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/de/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/de/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],u={toc:s},p="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(p,(0,i.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,n.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,n.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,n.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,n.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4dde1d77.13b5e2ec.js b/build-staging/de/assets/js/4dde1d77.13b5e2ec.js new file mode 100644 index 00000000..b18ec0da --- /dev/null +++ b/build-staging/de/assets/js/4dde1d77.13b5e2ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6153],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>g});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=r.createContext({}),u=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=u(e.components);return r.createElement(l.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,s=e.originalType,l=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),d=u(t),m=i,g=d["".concat(l,".").concat(m)]||d[m]||p[m]||s;return t?r.createElement(g,o(o({ref:n},c),{},{components:t})):r.createElement(g,o({ref:n},c))}));function g(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=t.length,o=new Array(s);o[0]=m;var a={};for(var l in n)hasOwnProperty.call(n,l)&&(a[l]=n[l]);a.originalType=e,a[d]="string"==typeof e?e:i,o[1]=a;for(var u=2;u{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const s={sidebar_position:3},o="Verbindung",a={unversionedId:"components/connectivity/intro",id:"components/connectivity/intro",title:"Verbindung",description:"Cwtch nutzt Tor Onion Services (v3) f\xfcr die Kommunikation zwischen Knoten.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/connectivity/intro.md",sourceDirName:"components/connectivity",slug:"/components/connectivity/intro",permalink:"/de/security/components/connectivity/intro",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Connectivity & Tor",permalink:"/de/security/category/connectivity--tor"},next:{title:"Tapir",permalink:"/de/security/category/tapir"}},l={},u=[{value:"Bekannte Risiken",id:"bekannte-risiken",level:2},{value:"Privater Schl\xfcssel dem Tor Prozess ausgesetzt",id:"privater-schl\xfcssel-dem-tor-prozess-ausgesetzt",level:3},{value:"Eind\xe4mmung",id:"eind\xe4mmung",level:3},{value:"Tor-Prozess-Management",id:"tor-prozess-management",level:3},{value:"Teststatus",id:"teststatus",level:2}],c={toc:u},d="wrapper";function p(e){let{components:n,...t}=e;return(0,i.kt)(d,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"verbindung"},"Verbindung"),(0,i.kt)("p",null,"Cwtch nutzt Tor Onion Services (v3) f\xfcr die Kommunikation zwischen Knoten."),(0,i.kt)("p",null,"Wir stellen das ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity")," Paket zur Verf\xfcgung, um den Tor-Daemon zu verwalten und Onion Dienste durch Tor einzurichten und abzubauen."),(0,i.kt)("h2",{id:"bekannte-risiken"},"Bekannte Risiken"),(0,i.kt)("h3",{id:"privater-schl\xfcssel-dem-tor-prozess-ausgesetzt"},"Privater Schl\xfcssel dem Tor Prozess ausgesetzt"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert")," (Erfordert physischen Zugriff oder Privilegierte Eskalation zum ausnutzen)"),(0,i.kt)("p",null,"Wir m\xfcssen den privaten Schl\xfcssel eines Onion Dienstes an die Konnektivit\xe4tsbibliothek \xfcbergeben \xfcber die ",(0,i.kt)("inlineCode",{parentName:"p"},"Listen")," Schnittstelle (und damit zum Tor Prozess). Dies ist einer der kritischsten Bereiche, der au\xdferhalb unserer Kontrolle liegt. Jede Bindung an einen Rogue-Tor-Prozess oder ein Binary f\xfchrt zur Kompromittierung des privaten Schl\xfcssels von Onion f\xfchren."),(0,i.kt)("h3",{id:"eind\xe4mmung"},"Eind\xe4mmung"),(0,i.kt)("p",null,"Verbindungsversuche als Standard an den vom System bereitgestellten Tor-Prozess zu binden, ",(0,i.kt)("em",{parentName:"p"},"nur")," wenn ihm ein Authentifizierungs-Token zur Verf\xfcgung gestellt wurde."),(0,i.kt)("p",null,"Andernfalls versucht die Konnektivit\xe4t immer einen eigenen Tor-Prozess mit einem bekannten guten Bin\xe4rpaket, das mit dem System gepackt wurde (au\xdferhalb des Geltungsbereichs des Konnektivit\xe4ts-Paketes)"),(0,i.kt)("p",null,"Langfristig hoffen wir, dass eine integrierte Bibliothek verf\xfcgbar sein wird und die direkte Verwaltung \xfcber eine In-Prozessoberfl\xe4che erm\xf6glicht, um zu verhindern, dass der private Schl\xfcssel die Prozessgrenze verl\xe4sst (oder andere alternative Pfade, die es uns erlauben, die volle Kontrolle \xfcber den privaten Schl\xfcssel im Speicher zu erhalten.)"),(0,i.kt)("h3",{id:"tor-prozess-management"},"Tor-Prozess-Management"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert")," (Erfordert physischen Zugriff oder Privilegierte Eskalation zum ausnutzen)"),(0,i.kt)("p",null,"Viele Probleme k\xf6nnen sich aus der Verwaltung eines separaten Prozesses ergeben, einschlie\xdflich der Notwendigkeit, neu zu starten, zu beenden und anderweitig eine angemessene Verwaltung zu gew\xe4hrleisten."),(0,i.kt)("p",null,"Die ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity/src/branch/master/acn.go"},"ACN")," Schnittstelle bietet ",(0,i.kt)("inlineCode",{parentName:"p"},"Restart"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Close")," und ",(0,i.kt)("inlineCode",{parentName:"p"},"GetBootstrapStatus")," Schnittstellen die es Anwendungen erlauben, den zugrunde liegenden Tor-Prozess zu verwalten. Zus\xe4tzlich kann die ",(0,i.kt)("inlineCode",{parentName:"p"},"SetStatusCallback")," Methode verwendet werden, um eine Anwendung zu benachrichtigen, wenn der Status des Tor-Prozesses sich \xe4ndert."),(0,i.kt)("p",null,"Wenn jedoch gen\xfcgend privilegierte Benutzer es w\xfcnschen, k\xf6nnen sie diesen Mechanismus st\xf6ren, und als solches ist der Tor-Prozess eine zerbrechlichere Komponente in der Interaktion als andere."),(0,i.kt)("h2",{id:"teststatus"},"Teststatus"),(0,i.kt)("p",null,"Die aktuelle Konnektivit\xe4t hat begrenzte Test M\xf6glichkeiten keine davon wird w\xe4hrend Pull-Requests oder Zusammenschl\xfcssen ausgef\xfchrt. Es gibt keine Integrationstests."),(0,i.kt)("p",null,"Es ist anzumerken, dass die Konnektivit\xe4t sowohl von Tapir als auch von Cwtch in ihren Integrationstests verwendet wird (und dies trotz fehlender Tests auf Paketebene ist systemweiten Pr\xfcfbedingungen ausgesetzt)"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4f68bcc6.d9b156bf.js b/build-staging/de/assets/js/4f68bcc6.d9b156bf.js new file mode 100644 index 00000000..e5eed984 --- /dev/null +++ b/build-staging/de/assets/js/4f68bcc6.d9b156bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3516],{4289:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-security"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/4fad3920.f7c18516.js b/build-staging/de/assets/js/4fad3920.f7c18516.js new file mode 100644 index 00000000..ad13b360 --- /dev/null +++ b/build-staging/de/assets/js/4fad3920.f7c18516.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6862],{2511:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/cwtch-stable","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/de/blog/tags/cwtch-stable/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/523378a0.36eab610.js b/build-staging/de/assets/js/523378a0.36eab610.js new file mode 100644 index 00000000..df200a46 --- /dev/null +++ b/build-staging/de/assets/js/523378a0.36eab610.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9475],{8264:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/autobindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/53cc4802.0826d515.js b/build-staging/de/assets/js/53cc4802.0826d515.js new file mode 100644 index 00000000..65643488 --- /dev/null +++ b/build-staging/de/assets/js/53cc4802.0826d515.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7594],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),d=a,m=u["".concat(s,".").concat(d)]||u[d]||g[d]||i;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/de/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"3. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"support",permalink:"/de/blog/tags/support"},{label:"testing",permalink:"/de/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/de/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/de/blog/cwtch-platform-support"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},u="wrapper";function g(e){let{components:t,...i}=e;return(0,a.kt)(u,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"We first ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,a.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/53f3dc0a.98083968.js b/build-staging/de/assets/js/53f3dc0a.98083968.js new file mode 100644 index 00000000..021462ed --- /dev/null +++ b/build-staging/de/assets/js/53f3dc0a.98083968.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4908],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),u=i,m=d["".concat(c,".").concat(u)]||d[u]||f[u]||o;return t?n.createElement(m,a(a({ref:r},p),{},{components:t})):n.createElement(m,a({ref:r},p))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=u;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[d]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:4},a="Dein Profilbild \xe4ndern",s={unversionedId:"profiles/change-profile-image",id:"profiles/change-profile-image",title:"Dein Profilbild \xe4ndern",description:"Diese Funktion erfordert, dass Experimente aktiviert sind und sowohl die Dateifreigabe als auch Bild-Vorschau und Profilbilder aktiviert sind.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/change-profile-image.md",sourceDirName:"profiles",slug:"/profiles/change-profile-image",permalink:"/de/docs/profiles/change-profile-image",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-profile-image.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Passwort \xe4ndern",permalink:"/de/docs/profiles/change-password"},next:{title:"Verschl\xfcsselte Profile entsperren",permalink:"/de/docs/profiles/unlock-profile"}},c={},l=[],p={toc:l},d="wrapper";function f(e){let{components:r,...t}=e;return(0,i.kt)(d,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"dein-profilbild-\xe4ndern"},"Dein Profilbild \xe4ndern"),(0,i.kt)("admonition",{title:"Vorsicht",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert sind")," und sowohl die ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"Dateifreigabe")," als auch ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Bild-Vorschau und Profilbilder")," aktiviert sind.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Klicke auf den Stift neben dem Profil, das du bearbeiten m\xf6chtest"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke auf den rosa Bleistift \xfcber deinem Profilfoto"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle ein Bild von Deinem Ger\xe4t"),(0,i.kt)("li",{parentName:"ol"},"Scrolle nach unten und klicke auf Profil speichern")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/549d43e9.18ffa95a.js b/build-staging/de/assets/js/549d43e9.18ffa95a.js new file mode 100644 index 00000000..7497c9ef --- /dev/null +++ b/build-staging/de/assets/js/549d43e9.18ffa95a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8959],{2103:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/cwtch-stable/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/de/blog/tags/cwtch-stable","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5549e0e2.d72ced7a.js b/build-staging/de/assets/js/5549e0e2.d72ced7a.js new file mode 100644 index 00000000..53e57881 --- /dev/null +++ b/build-staging/de/assets/js/5549e0e2.d72ced7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6452],{642:e=>{e.exports=JSON.parse('{"title":"Konversationen","slug":"/category/conversations","permalink":"/de/docs/category/conversations","navigation":{"previous":{"title":"Profilattribute einstellen","permalink":"/de/docs/profiles/profile-info"},"next":{"title":"Eine Einf\xfchrung in die Cwtch P2P Chat","permalink":"/de/docs/chat/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/55bf5a51.fe193480.js b/build-staging/de/assets/js/55bf5a51.fe193480.js new file mode 100644 index 00000000..bff6b9fa --- /dev/null +++ b/build-staging/de/assets/js/55bf5a51.fe193480.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[497],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:3},i="UI Spalten",c={unversionedId:"settings/appearance/ui-columns",id:"settings/appearance/ui-columns",title:"UI Spalten",description:"1. Dr\xfccke das Einstellungssymbol",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/ui-columns.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/ui-columns",permalink:"/de/docs/settings/appearance/ui-columns",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/ui-columns.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Helles/Dunkles Design und Theme-Aufteilung",permalink:"/de/docs/settings/appearance/light-dark-mode"},next:{title:"Streamer/Pr\xe4sentationsmodus",permalink:"/de/docs/settings/appearance/streamer-mode"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"ui-spalten"},"UI Spalten"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Dr\xfccke das Einstellungssymbol"),(0,a.kt)("li",{parentName:"ol"},"Klicke auf einzeln"),(0,a.kt)("li",{parentName:"ol"},"W\xe4hle die Konfiguration der Spalten aus, die Du verwenden m\xf6chtest")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/56c80d06.c3a1d1c2.js b/build-staging/de/assets/js/56c80d06.c3a1d1c2.js new file mode 100644 index 00000000..524a6c65 --- /dev/null +++ b/build-staging/de/assets/js/56c80d06.c3a1d1c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1032],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>d});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var u=r.createContext({}),M=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=M(e.components);return r.createElement(u.Provider,{value:t},e.children)},L="mdxType",w={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},l=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,u=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),L=M(n),l=i,d=L["".concat(u,".").concat(l)]||L[l]||w[l]||o;return n?r.createElement(d,a(a({ref:t},s),{},{components:n})):r.createElement(d,a({ref:t},s))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=l;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[L]="string"==typeof e?e:i,a[1]=c;for(var M=2;M{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>w,frontMatter:()=>o,metadata:()=>c,toc:()=>M});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:10},a="Entfernen einer Konversation",c={unversionedId:"chat/delete-contact",id:"chat/delete-contact",title:"Entfernen einer Konversation",description:"Diese Funktion wird unwiderruflich l\xf6schen. Dieses kann nicht r\xfcckg\xe4ngig gemacht werden.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/delete-contact.md",sourceDirName:"chat",slug:"/chat/delete-contact",permalink:"/de/docs/chat/delete-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/delete-contact.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Einen Kontakt entsperren",permalink:"/de/docs/chat/unblock-contact"},next:{title:"Groups",permalink:"/de/docs/category/groups"}},u={},M=[],s={toc:M},L="wrapper";function w(e){let{components:t,...o}=e;return(0,i.kt)(L,(0,r.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"entfernen-einer-konversation"},"Entfernen einer Konversation"),(0,i.kt)("admonition",{title:"Warnung",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion wird ",(0,i.kt)("strong",{parentName:"p"},"unwiderruflich")," l\xf6schen. Dieses ",(0,i.kt)("strong",{parentName:"p"},"kann nicht r\xfcckg\xe4ngig gemacht werden"),".")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"In einem Chat mit Kontakt, gehe in die Konversationseinstellungen oben rechts ",(0,i.kt)("span",{class:"icon"},(0,i.kt)("img",{src:n(5905).Z,width:"24",height:"24"}))),(0,i.kt)("li",{parentName:"ul"},"Scrolle zum ",(0,i.kt)("strong",{parentName:"li"},"Verlasse diese Konversation")," und dr\xfccken darauf."),(0,i.kt)("li",{parentName:"ul"},"Sie wirst aufgefordert zu best\xe4tigen, wenn du die Unterhaltung verlassen m\xf6chtest. Diese Aktion kann nicht r\xfcckg\xe4ngig gemacht werden.")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}w.isMDXComponent=!0},5905:(e,t,n)=>{n.d(t,{Z:()=>r});const r="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyNS4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjQgMjQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJLnN0MHtmaWxsOm5vbmU7fQ0KPC9zdHlsZT4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0wLDBoMjR2MjRIMFYweiIvPg0KPGc+DQoJPHBhdGggZD0iTTEzLjYsMTMuOGMtMS0wLjItMi0wLjMtMi44LTAuM2MtMi43LDAtOCwxLjMtOCw0djJoOS44Yy0wLjMtMC42LTAuNC0xLjMtMC40LTIuMUMxMi4yLDE1LjksMTIuNywxNC43LDEzLjYsMTMuOHoiLz4NCgk8Y2lyY2xlIGN4PSIxMC44IiBjeT0iNy40IiByPSI0Ii8+DQo8L2c+DQo8cGF0aCBkPSJNMjEuMSwxNy45YzAtMC4xLDAtMC4zLDAtMC40YzAtMC4yLDAtMC4zLDAtMC40bDEtMC43YzAuMS0wLjEsMC4xLTAuMiwwLjEtMC4zbC0wLjktMS42Yy0wLjEtMC4xLTAuMi0wLjEtMC4zLTAuMWwtMS4xLDAuNQ0KCWMtMC4yLTAuMi0wLjUtMC4zLTAuOC0wLjRsLTAuMi0xLjJjMC0wLjEtMC4xLTAuMi0wLjItMC4yaC0xLjhjLTAuMSwwLTAuMiwwLjEtMC4yLDAuMmwtMC4yLDEuMmMtMC4zLDAuMS0wLjUsMC4zLTAuOCwwLjRsLTEuMS0wLjUNCgljLTAuMSwwLTAuMiwwLTAuMywwLjFMMTMuNCwxNmMtMC4xLDAuMSwwLDAuMiwwLjEsMC4zbDEsMC43YzAsMC4xLDAsMC4zLDAsMC40YzAsMC4xLDAsMC4zLDAsMC40bC0xLDAuN2MtMC4xLDAuMS0wLjEsMC4yLTAuMSwwLjMNCglsMC45LDEuNmMwLjEsMC4xLDAuMiwwLjEsMC4zLDAuMWwxLjEtMC41YzAuMiwwLjIsMC41LDAuMywwLjgsMC40bDAuMiwxLjJjMCwwLjEsMC4xLDAuMiwwLjIsMC4yaDEuOGMwLjEsMCwwLjItMC4xLDAuMi0wLjINCglsMC4yLTEuMmMwLjMtMC4xLDAuNS0wLjMsMC44LTAuNGwxLjEsMC41YzAuMSwwLDAuMiwwLDAuMy0wLjFsMC45LTEuNmMwLjEtMC4xLDAtMC4yLTAuMS0wLjNMMjEuMSwxNy45eiBNMTcuNywxOS4yDQoJYy0wLjksMC0xLjctMC44LTEuNy0xLjdjMC0wLjksMC44LTEuNywxLjctMS43YzAuOSwwLDEuNywwLjgsMS43LDEuN0MxOS40LDE4LjQsMTguNywxOS4yLDE3LjcsMTkuMnoiLz4NCjwvc3ZnPg0K"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/57fc9be0.a0292f31.js b/build-staging/de/assets/js/57fc9be0.a0292f31.js new file mode 100644 index 00000000..d8946259 --- /dev/null +++ b/build-staging/de/assets/js/57fc9be0.a0292f31.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1091],{4902:e=>{e.exports=JSON.parse('{"title":"Plattformen","slug":"/category/platforms","permalink":"/de/docs/category/platforms","navigation":{"previous":{"title":"Aufkleber","permalink":"/de/docs/contribute/stickers"},"next":{"title":"Cwtch in Tails laufen lassen","permalink":"/de/docs/platforms/tails"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/58b7fc4c.f2d94692.js b/build-staging/de/assets/js/58b7fc4c.f2d94692.js new file mode 100644 index 00000000..1539fbad --- /dev/null +++ b/build-staging/de/assets/js/58b7fc4c.f2d94692.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6769],{3905:(e,n,r)=>{r.d(n,{Zo:()=>d,kt:()=>m});var t=r(7294);function i(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n=0||(i[r]=e[r]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var u=t.createContext({}),p=function(e){var n=t.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},d=function(e){var n=p(e.components);return t.createElement(u.Provider,{value:n},e.children)},c="mdxType",l={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},h=t.forwardRef((function(e,n){var r=e.components,i=e.mdxType,a=e.originalType,u=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),c=p(r),h=i,m=c["".concat(u,".").concat(h)]||c[h]||l[h]||a;return r?t.createElement(m,s(s({ref:n},d),{},{components:r})):t.createElement(m,s({ref:n},d))}));function m(e,n){var r=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=r.length,s=new Array(a);s[0]=h;var o={};for(var u in n)hasOwnProperty.call(n,u)&&(o[u]=n[u]);o.originalType=e,o[c]="string"==typeof e?e:i,s[1]=o;for(var p=2;p{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>p});var t=r(7462),i=(r(7294),r(3905));const a={sidebar_position:1},s="Eine Einf\xfchrung in die Cwtch Gruppen",o={unversionedId:"groups/introduction",id:"groups/introduction",title:"Eine Einf\xfchrung in die Cwtch Gruppen",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/introduction.md",sourceDirName:"groups",slug:"/groups/introduction",permalink:"/de/docs/groups/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/de/docs/category/groups"},next:{title:"Eine neue Gruppe erstellen",permalink:"/de/docs/groups/create-group"}},u={},p=[{value:"Wie Gruppen unter der Haube funktionieren",id:"wie-gruppen-unter-der-haube-funktionieren",level:2}],d={toc:p},c="wrapper";function l(e){let{components:n,...r}=e;return(0,i.kt)(c,(0,t.Z)({},d,r,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eine-einf\xfchrung-in-die-cwtch-gruppen"},"Eine Einf\xfchrung in die Cwtch Gruppen"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Hinweis: Metadaten resistente Kommunikation ist noch ein aktives Entwicklungsfeld und was hier dokumentiert ist wird sehr wahrscheinlich in der Zukunft sich \xe4ndern.")),(0,i.kt)("p",null,"Standardm\xe4\xdfig unterst\xfctzt Cwtch nur Peer-to-Peer online Chats. Um Mehrparteien-Gespr\xe4che zu unterst\xfctzen und Offline-Auslieferung zu erm\xf6glichen, ist ein (nicht vertrauensw\xfcrdiger) Dritter erforderlich. Wir nennen diese Entit\xe4ten (Dritten) ",(0,i.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},'"Server"')),(0,i.kt)("p",null,"Diese Server k\xf6nnen von jedem eingerichtet werden und sind daf\xfcr gedacht, immer online zu sein. Am wichtigsten ist, dass die Kommunikation mit einem Server so gestaltet ist, dass der Server so wenig Informationen wie m\xf6glich \xfcber den Inhalt oder die Metadaten erf\xe4hrt."),(0,i.kt)("p",null,"In vielerlei Hinsicht ist die Kommunikation mit einem Server identisch mit einer regul\xe4ren Cwtch Peer, alle Schritte werden gleich unternommen, aber der Server fungiert immer als eingehender Peer, und der ausgehende Peer verwendet immer neu generierte ",(0,i.kt)("strong",{parentName:"p"},"ephemere (fl\xfcchtige) Schl\xfcsselpaare")," - so dass jede Serversitzung getrennt wird."),(0,i.kt)("p",null,"Somit unterscheidet sich die Peer zu Server Konversation nur in der ",(0,i.kt)("em",{parentName:"p"},"Art")," der Nachrichten, die zwischen zwei Seiten gesendet werden, mit dem Server, der alle Nachrichten, die er erh\xe4lt, speichert und damit den Clients erlaubt den Server nach \xe4lteren Nachrichten abzufragen."),(0,i.kt)("p",null,"Das mit Servern verbundene Risikomodell ist komplizierter als Peer-to-Peer-Kommunikation, da wir derzeit Leute ben\xf6tigen, die Server in Cwtch mit ",(0,i.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"opt-in zum Gruppen-Chat-Experiment verwenden m\xf6chten")," um auf nicht vertrauensw\xfcrdigen Servern Gruppen hinzuzuf\xfcgen, zu verwalten und zu erstellen."),(0,i.kt)("h2",{id:"wie-gruppen-unter-der-haube-funktionieren"},"Wie Gruppen unter der Haube funktionieren"),(0,i.kt)("p",null,"Wenn eine Person eine Gruppendiskussion starten will, generiert sie einen zuf\xe4lligen geheimen ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel"),". Alle Gruppenkommunikation wird mit diesem Schl\xfcssel verschl\xfcsselt."),(0,i.kt)("p",null,"Zusammen mit dem ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel")," entscheidet der Gruppenersteller sich auch f\xfcr einen ",(0,i.kt)("strong",{parentName:"p"},"Cwtch Server")," als Host der Gruppe zu verwenden. Weitere Informationen dar\xfcber, wie Server sich selbst authentifizieren, findest du unter ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/key_bundles.html"},"Schl\xfcsselb\xfcndel"),"."),(0,i.kt)("p",null,"Ein ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppen Identifikator")," wird mit dem Gruppenschl\xfcssel und dem Gruppenserver generiert und diese drei Elemente sind in einer Einladung verpackt, die an potenzielle Gruppenmitglieder gesendet werden kann (z.B. \xfcber existierende Peer-to-Peer-Verbindungen)."),(0,i.kt)("p",null,"Um eine Nachricht an die Gruppe zu senden, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt (siehe unten), und verschl\xfcsselt deine Nachricht mit dem Gruppenschl\xfcssel `",(0,i.kt)("inlineCode",{parentName:"p"},"und erzeugt eine kryptographische Signatur \xfcber die"),"Gruppen-Id",(0,i.kt)("inlineCode",{parentName:"p"},", "),"Gruppen Server` und die entschl\xfcsselte Nachricht (siehe: ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/message_formats.html"},"Nachrichtenformate")," f\xfcr weitere Informationen)."),(0,i.kt)("p",null,"Um Nachrichten von der Gruppe zu erhalten, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt und l\xe4dt ",(0,i.kt)("em",{parentName:"p"},"alle")," Nachrichten (seit ihrer vorherigen Verbindung) herunter. Die Profile versuchen dann jede Nachricht mit dem ",(0,i.kt)("inlineCode",{parentName:"p"},"Gruppenschl\xfcssel")," und wenn dies erfolgreich war, dann die Signatur zu verifizieren (siehe ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/server.html"},"Cwtch Server")," ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/groups.html"},"Cwtch Groupen")," f\xfcr einen \xdcberblick \xfcber Attacken und Abschw\xe4chungen)."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5a2a7ed5.66520fa0.js b/build-staging/de/assets/js/5a2a7ed5.66520fa0.js new file mode 100644 index 00000000..14d7eddd --- /dev/null +++ b/build-staging/de/assets/js/5a2a7ed5.66520fa0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7432],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),l=c(r),d=i,f=l["".concat(s,".").concat(d)]||l[d]||m[d]||o;return r?n.createElement(f,p(p({ref:t},u),{},{components:r})):n.createElement(f,p({ref:t},u))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,p=new Array(o);p[0]=d;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[l]="string"==typeof e?e:i,p[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>p,default:()=>m,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:1},p="experimentelle Gruppen Funktion",a={unversionedId:"settings/experiments/group-experiment",id:"settings/experiments/group-experiment",title:"experimentelle Gruppen Funktion",description:"Erm\xf6glicht Cwtch eine Verbindung zu nicht vertrauensw\xfcrdigen Server und verwendet diese f\xfcr private, asynchrone Gruppen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/group-experiment.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/group-experiment",permalink:"/de/docs/settings/experiments/group-experiment",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/group-experiment.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Experiments",permalink:"/de/docs/category/experiments"},next:{title:"Server Hosting",permalink:"/de/docs/settings/experiments/server-hosting"}},s={},c=[{value:"Zum Einschalten",id:"zum-einschalten",level:2}],u={toc:c},l="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"experimentelle-gruppen-funktion"},"experimentelle Gruppen Funktion"),(0,i.kt)("p",null,"Erm\xf6glicht Cwtch ",(0,i.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},"eine Verbindung zu nicht vertrauensw\xfcrdigen Server")," und verwendet diese f\xfcr ",(0,i.kt)("a",{parentName:"p",href:"/docs/groups/introduction"},"private, asynchrone Gruppen"),"."),(0,i.kt)("h2",{id:"zum-einschalten"},"Zum Einschalten"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"Experimente aktivieren"),(0,i.kt)("li",{parentName:"ol"},"Gruppen-Experiment aktivieren")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5a84578f.a3429355.js b/build-staging/de/assets/js/5a84578f.a3429355.js new file mode 100644 index 00000000..b41c0100 --- /dev/null +++ b/build-staging/de/assets/js/5a84578f.a3429355.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5045],{8415:e=>{e.exports=JSON.parse('[{"label":"cwtch","permalink":"/de/blog/tags/cwtch","count":17},{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable","count":17},{"label":"planning","permalink":"/de/blog/tags/planning","count":4},{"label":"release","permalink":"/de/blog/tags/release","count":2},{"label":"developer-documentation","permalink":"/de/blog/tags/developer-documentation","count":2},{"label":"nightly","permalink":"/de/blog/tags/nightly","count":1},{"label":"documentation","permalink":"/de/blog/tags/documentation","count":1},{"label":"security-handbook","permalink":"/de/blog/tags/security-handbook","count":1},{"label":"bindings","permalink":"/de/blog/tags/bindings","count":4},{"label":"autobindings","permalink":"/de/blog/tags/autobindings","count":2},{"label":"libcwtch","permalink":"/de/blog/tags/libcwtch","count":2},{"label":"support","permalink":"/de/blog/tags/support","count":3},{"label":"testing","permalink":"/de/blog/tags/testing","count":2},{"label":"reproducible-builds","permalink":"/de/blog/tags/reproducible-builds","count":2},{"label":"repliqate","permalink":"/de/blog/tags/repliqate","count":2},{"label":"api","permalink":"/de/blog/tags/api","count":1}]')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5ab392cd.e73fd644.js b/build-staging/de/assets/js/5ab392cd.e73fd644.js new file mode 100644 index 00000000..5948473c --- /dev/null +++ b/build-staging/de/assets/js/5ab392cd.e73fd644.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6431],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>b});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=c(n),d=i,b=p["".concat(l,".").concat(d)]||p[d]||f[d]||a;return n?r.createElement(b,s(s({ref:t},u),{},{components:n})):r.createElement(b,s({ref:t},u))}));function b(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,s=new Array(a);s[0]=d;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[p]="string"==typeof e?e:i,s[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>f,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:14},s="Verf\xfcgbarkeitsstatus einstellen",o={unversionedId:"profiles/availability-status",id:"profiles/availability-status",title:"Verf\xfcgbarkeitsstatus einstellen",description:"Diese Funktionalit\xe4t ist derzeit nur verf\xfcgbar in den N\xe4chtlichen Release Builds von Cwtch.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/availability-status.md",sourceDirName:"profiles",slug:"/profiles/availability-status",permalink:"/de/docs/profiles/availability-status",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/availability-status.md",tags:[],version:"current",sidebarPosition:14,frontMatter:{sidebar_position:14},sidebar:"tutorialSidebar",previous:{title:"Profil importieren",permalink:"/de/docs/profiles/importing-a-profile"},next:{title:"Profilattribute einstellen",permalink:"/de/docs/profiles/profile-info"}},l={},c=[],u={toc:c},p="wrapper";function f(e){let{components:t,...a}=e;return(0,i.kt)(p,(0,r.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"verf\xfcgbarkeitsstatus-einstellen"},"Verf\xfcgbarkeitsstatus einstellen"),(0,i.kt)("admonition",{title:"Warnung Feature des n\xe4chtlichen Releases",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktionalit\xe4t ist derzeit ",(0,i.kt)("strong",{parentName:"p"},"nur ")," verf\xfcgbar in den ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"N\xe4chtlichen Release")," Builds von Cwtch."),(0,i.kt)("p",{parentName:"admonition"},"Diese Funktionalit\xe4t kann unvollst\xe4ndig und/oder gef\xe4hrlich sein, wenn sie falsch benutzt wird. Bitte hilf uns bei der \xdcberpr\xfcfung und dem Test.")),(0,i.kt)("p",null,"Klicke im ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/category/conversations"},"-Konversationsfenster")," auf das Status-Symbol neben deinem Profilbild."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(1476).Z},(0,i.kt)("img",{src:n(3163).Z,width:"444",height:"252"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Ein Dropdown-Men\xfc wird angezeigt mit verschiedenen Optionen wie Verf\xfcgbar, Abwesend und Besch\xe4ftigt"),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(8791).Z},(0,i.kt)("img",{src:n(3891).Z,width:"443",height:"242"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Wenn du Abwesend oder Besch\xe4ftigt als Status ausw\xe4hlst, wird sich die Grenzlinie deines Profilbildes \xe4ndern, um den Status zu reflektieren"),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(4940).Z},(0,i.kt)("img",{src:n(1859).Z,width:"442",height:"233"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Kontakte sehen diese \xc4nderung in ihrem Konversationsfenster."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(8868).Z},(0,i.kt)("img",{src:n(6792).Z,width:"443",height:"223"}))),(0,i.kt)("figcaption",null)))}f.isMDXComponent=!0},8868:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},4940:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},8791:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},1476:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"},6792:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},1859:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3891:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},3163:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5bdf583d.f74a444e.js b/build-staging/de/assets/js/5bdf583d.f74a444e.js new file mode 100644 index 00000000..969b9daf --- /dev/null +++ b/build-staging/de/assets/js/5bdf583d.f74a444e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9978],{2740:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/security-handbook","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5beee875.c7b0929b.js b/build-staging/de/assets/js/5beee875.c7b0929b.js new file mode 100644 index 00000000..d02d0531 --- /dev/null +++ b/build-staging/de/assets/js/5beee875.c7b0929b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9444],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(n),m=r,g=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return n?a.createElement(g,i(i({ref:t},s),{},{components:n})):a.createElement(g,i({ref:t},s))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"7. Juni 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/de/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/de/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/de/blog/cwtch-developer-documentation"}},c={authorsImageUrls:[void 0]},p=[{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,r.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(9964).Z,width:"1005",height:"481"})),(0,r.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,r.kt)("p",null,"There is a ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,r.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/"},"2023-06-05-17-36-v1.11.0-74-g0406"),"."),(0,r.kt)("p",null,"This version has a large number of improvements and bug fixes including:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A new Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor."),(0,r.kt)("li",{parentName:"ul"},"Updated UI font styles"),(0,r.kt)("li",{parentName:"ul"},"Dependency updates, including a new base of Flutter 3.10."),(0,r.kt)("li",{parentName:"ul"},"A fix for stuck file downloading notifications on Android"),(0,r.kt)("li",{parentName:"ul"},"A fix for missing profile images in certain edge cases on Android"),(0,r.kt)("li",{parentName:"ul"},"Japanese, Swedish, and Swahili translation options"),(0,r.kt)("li",{parentName:"ul"},"A new retry peer connection button for prompting Cwtch to prioritize specific connections"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails support"))),(0,r.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9964:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5bfc32c8.786598ab.js b/build-staging/de/assets/js/5bfc32c8.786598ab.js new file mode 100644 index 00000000..bcfe5b10 --- /dev/null +++ b/build-staging/de/assets/js/5bfc32c8.786598ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1280],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=l(n),p=i,f=d["".concat(c,".").concat(p)]||d[p]||h[p]||a;return n?r.createElement(f,s(s({ref:t},u),{},{components:n})):r.createElement(f,s({ref:t},u))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,s=new Array(a);s[0]=p;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:1},s="Was ist Cwtch?",o={unversionedId:"intro",id:"intro",title:"Was ist Cwtch?",description:"Cwtch (/k\u028at\u0283/ - ein walisisches Wort, das grob \xfcbersetzt \u201eeine Umarmung, die einen sicheren Ort schafft\u201c bedeutet) ist eine dezentralisierte, Privatsp\xe4hre bewahrende, metadatenresistente Messenger-App.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/intro.md",sourceDirName:".",slug:"/intro",permalink:"/de/docs/intro",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/de/docs/category/getting-started"}},c={},l=[],u={toc:l},d="wrapper";function h(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"was-ist-cwtch"},"Was ist Cwtch?"),(0,i.kt)("p",null,"Cwtch (/k\u028at\u0283/ - ein walisisches Wort, das grob \xfcbersetzt \u201eeine Umarmung, die einen sicheren Ort schafft\u201c bedeutet) ist eine dezentralisierte, Privatsp\xe4hre bewahrende, metadatenresistente Messenger-App."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Dezentralisiert und offen"),": Es gibt keinen \u201eCwtch-Dienst\u201c oder \u201eCwtch-Netzwerk\u201c. Die Cwtch Teilnehmer k\xf6nnen ihre eigenen sicheren R\xe4ume hosten oder ihre Infrastruktur anderen anbieten, die auf der Suche nach einem sicheren Raum sind. Das Cwtch-Protokoll ist offen und jeder kann Bots, Dienste und Benutzeroberfl\xe4chen erstellen und in Cwtch integrieren und interagieren."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Datenschutz wahrend"),": Alle Kommunikation in Cwtch ist Ende-zu-Ende verschl\xfcsselt und findet \xfcber Tor v3 onion Dienste statt."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Metadaten resistent"),": Cwtch wurde so konzipiert, dass ohne ihre ausdr\xfcckliche Zustimmung keine Informationen ausgetauscht oder zug\xe4nglich sind einschlie\xdflich On-the-wire Nachrichten und Protokoll-Metadaten.")),(0,i.kt)("h1",{id:"sicherheit-und-verschl\xfcsselung"},"Sicherheit und Verschl\xfcsselung"),(0,i.kt)("p",null,"F\xfcr einen detaillierteren Blick auf die in Cwtch verwendete Sicherheit, Privatsph\xe4re und die zugrunde liegende Verschl\xfcsselungstechnologie lesen Sie ies bitte unser ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Sicherheitshandbuch")),(0,i.kt)("h1",{id:"erste-schritte"},"Erste Schritte"),(0,i.kt)("p",null,"Du kannst die neueste Version von Cwtch von ",(0,i.kt)("a",{parentName:"p",href:"https://cwtch.im/download/"},"herunterladen https://cwtch.im/download/")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5cb298ca.2fcf1742.js b/build-staging/de/assets/js/5cb298ca.2fcf1742.js new file mode 100644 index 00000000..903ad047 --- /dev/null +++ b/build-staging/de/assets/js/5cb298ca.2fcf1742.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2909],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),d=p(r),u=n,m=d["".concat(l,".").concat(u)]||d[u]||h[u]||o;return r?a.createElement(m,i(i({ref:t},s),{},{components:r})):a.createElement(m,i({ref:t},s))}));function m(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[d]="string"==typeof e?e:n,i[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/de/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"28. April 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/de/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/de/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/de/blog/availability-status-profile-attributes"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},d="wrapper";function h(e){let{components:t,...o}=e;return(0,n.kt)(d,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(3466).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},3466:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5d8d36f7.6b89d887.js b/build-staging/de/assets/js/5d8d36f7.6b89d887.js new file mode 100644 index 00000000..f5494524 --- /dev/null +++ b/build-staging/de/assets/js/5d8d36f7.6b89d887.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1740],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=n.createContext({}),l=function(e){var r=n.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},c=function(e){var r=l(e.components);return n.createElement(p.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,v=u["".concat(p,".").concat(m)]||u[m]||d[m]||a;return t?n.createElement(v,i(i({ref:r},c),{},{components:t})):n.createElement(v,i({ref:r},c))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var s={};for(var p in r)hasOwnProperty.call(r,p)&&(s[p]=r[p]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:7},i="Server verwalten",s={unversionedId:"groups/manage-known-servers",id:"groups/manage-known-servers",title:"Server verwalten",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/manage-known-servers.md",sourceDirName:"groups",slug:"/groups/manage-known-servers",permalink:"/de/docs/groups/manage-known-servers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/manage-known-servers.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Einen Gruppennamen bearbeiten",permalink:"/de/docs/groups/edit-group-name"},next:{title:"Servers",permalink:"/de/docs/category/servers"}},p={},l=[{value:"Import lokal gehosteter Server",id:"import-lokal-gehosteter-server",level:2}],c={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"server-verwalten"},"Server verwalten"),(0,o.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,o.kt)("p",null,"Cwtch Gruppen werden von nicht vertrauensw\xfcrdigen Servern gehostet. Wenn du die Server sehen m\xf6chtest, \xfcber die du kennst, ihren Status und die auf ihnen gehosteten Gruppen:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"In deinem Kontakt-Bereich"),(0,o.kt)("li",{parentName:"ol"},"Zum Server verwalten Symbol gehen")),(0,o.kt)("h2",{id:"import-lokal-gehosteter-server"},"Import lokal gehosteter Server"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Um einen lokal gehosteten Server zu importieren klicke auf lokalen Server ausw\xe4hlen"),(0,o.kt)("li",{parentName:"ol"},"W\xe4hle den gew\xfcnschten Server aus")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Manage.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5dc151e9.84a9b26a.js b/build-staging/de/assets/js/5dc151e9.84a9b26a.js new file mode 100644 index 00000000..6ccc19d8 --- /dev/null +++ b/build-staging/de/assets/js/5dc151e9.84a9b26a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[923],{3905:(t,e,a)=>{a.d(e,{Zo:()=>s,kt:()=>g});var r=a(7294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,r)}return a}function i(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var d=r.createContext({}),p=function(t){var e=r.useContext(d),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},s=function(t){var e=p(t.components);return r.createElement(d.Provider,{value:e},t.children)},u="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},m=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,l=t.originalType,d=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(a),m=n,g=u["".concat(d,".").concat(m)]||u[m]||c[m]||l;return a?r.createElement(g,i(i({ref:e},s),{},{components:a})):r.createElement(g,i({ref:e},s))}));function g(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var d in e)hasOwnProperty.call(e,d)&&(o[d]=e[d]);o.originalType=t,o[u]="string"==typeof t?t:n,i[1]=o;for(var p=2;p{a.r(e),a.d(e,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const l={sidebar_position:1},i="Release and Packaging Process",o={unversionedId:"release",id:"release",title:"Release and Packaging Process",description:"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.",source:"@site/developing/release.md",sourceDirName:".",slug:"/release",permalink:"/de/developing/release",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Introduction to Cwtch Development",permalink:"/de/developing/intro"},next:{title:"Building a Cwtch App",permalink:"/de/developing/category/building-a-cwtch-app"}},d={},p=[{value:"Automated Testing",id:"automated-testing",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"UI Nightly Builds",id:"ui-nightly-builds",level:2},{value:"Official Releases",id:"official-releases",level:2},{value:"Reproducible Builds",id:"reproducible-builds",level:3}],s={toc:p},u="wrapper";function c(t){let{components:e,...a}=t;return(0,n.kt)(u,(0,r.Z)({},s,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member."),(0,n.kt)("h2",{id:"automated-testing"},"Automated Testing"),(0,n.kt)("p",null,"Drone carries out a suite of automated tests at various stages of the release pipeline."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Test Suite"),(0,n.kt)("th",{parentName:"tr",align:null},"Repository"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"A full exercise of peer-to-peer and group messaging")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"File Sharing Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that file sharing and image downloading work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Automated Download Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that automated image downloading (e.g. profile pictures) work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"UI Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch-ui"),(0,n.kt)("td",{parentName:"tr",align:null},"A suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings")))),(0,n.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,n.kt)("p",null,"Drone produces the following build artifacts for all Cwtch autobindings builds."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch-sources.jar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"gomobile derived source code for the Android Cwtch library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch.aar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android Cwtch library. Supports arm, arm64, and amd64.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.so"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.dll"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 bit shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.arm64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"Arm64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.x64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")))),(0,n.kt)("h2",{id:"ui-nightly-builds"},"UI Nightly Builds"),(0,n.kt)("p",null,"We make unreleased versions of Cwtch available for testing as ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"Cwtch Nightlies"),"."),(0,n.kt)("p",null,"Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.apk"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Supports arm, arm64, and amd64. Can be sideloaded.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.aab"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android App Bundle for publishing to appstores")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Cwtch-VERSION.dmg"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.tar.gz"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"Contains the code, libs, and assets in addition to install scripts for various devices")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.zip"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-installer-VERSION.exe"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"NSIS powered installation wizard")))),(0,n.kt)("p",null,"Nightly builds are regularly purged from the system"),(0,n.kt)("h2",{id:"official-releases"},"Official Releases"),(0,n.kt)("p",null,"The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps."),(0,n.kt)("p",null,"When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. ",(0,n.kt)("inlineCode",{parentName:"p"},"v.1.12.0"),". The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder."),(0,n.kt)("h3",{id:"reproducible-builds"},"Reproducible Builds"),(0,n.kt)("p",null,"We use ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate")," to provide ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"reproducible build scripts for Cwtch"),"."),(0,n.kt)("p",null,"We update the ",(0,n.kt)("inlineCode",{parentName:"p"},"repliqate-scripts")," repository with scripts for all official releases. Currently only Cwtch bindings are reproducible"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5e5faacc.463a908d.js b/build-staging/de/assets/js/5e5faacc.463a908d.js new file mode 100644 index 00000000..f9fce82b --- /dev/null +++ b/build-staging/de/assets/js/5e5faacc.463a908d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8192],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>h});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function o(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function l(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=n.createContext({}),p=function(t){var e=n.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},u=function(t){var e=p(t.components);return n.createElement(s.Provider,{value:e},t.children)},d="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,o=t.originalType,s=t.parentName,u=i(t,["components","mdxType","originalType","parentName"]),d=p(a),m=r,h=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return a?n.createElement(h,l(l({ref:e},u),{},{components:a})):n.createElement(h,l({ref:e},u))}));function h(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var o=a.length,l=new Array(o);l[0]=m;var i={};for(var s in e)hasOwnProperty.call(e,s)&&(i[s]=e[s]);i.originalType=t,i[d]="string"==typeof t?t:r,l[1]=i;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const o={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/de/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"27. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"support",permalink:"/de/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/de/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/de/blog/cwtch-bindings-reproducible"}},s={authorsImageUrls:[void 0]},p=[{value:"Constraints on support",id:"constraints-on-support",level:2},{value:"Limitations on general-purpose computing",id:"limitations-on-general-purpose-computing",level:3},{value:"Constraints introduced by the Flutter SDK",id:"constraints-introduced-by-the-flutter-sdk",level:3},{value:"Constraints introduced by Appstore Policy",id:"constraints-introduced-by-appstore-policy",level:3},{value:"CPU Architecture and Cwtch Bindings",id:"cpu-architecture-and-cwtch-bindings",level:3},{value:"Testing and official support",id:"testing-and-official-support",level:3},{value:"End-of-life platforms",id:"end-of-life-platforms",level:3},{value:"How we decide to officially support a platform",id:"how-we-decide-to-officially-support-a-platform",level:2},{value:"Summary of official support",id:"summary-of-official-support",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},d="wrapper";function c(t){let{components:e,...o}=t;return(0,r.kt)(d,(0,n.Z)({},u,o,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"One of the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,r.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,r.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,r.kt)("p",null,"The questions we aim to answer in this post are: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,r.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,r.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,r.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,r.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6149).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraints-on-support"},"Constraints on support"),(0,r.kt)("p",null,"From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. "),(0,r.kt)("p",null,"In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms."),(0,r.kt)("h3",{id:"limitations-on-general-purpose-computing"},"Limitations on general-purpose computing"),(0,r.kt)("p",null,"In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to ",(0,r.kt)("em",{parentName:"p"},"other")," onion services). "),(0,r.kt)("p",null,"On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, ",(0,r.kt)("strong",{parentName:"p"},"blocked entirely"),". "),(0,r.kt)("p",null,"This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind."),(0,r.kt)("p",null,"While we expect that ",(0,r.kt)("a",{parentName:"p",href:"https://gitlab.torproject.org/tpo/core/arti"},"Arti")," will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. "),(0,r.kt)("p",null,"As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable."),(0,r.kt)("p",null,"We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device."),(0,r.kt)("h3",{id:"constraints-introduced-by-the-flutter-sdk"},"Constraints introduced by the Flutter SDK"),(0,r.kt)("p",null,"The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms"},"platforms that are supported by the Flutter SDK"),"."),(0,r.kt)("p",null,"To summarize, as of writing this document those platforms are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Android API 16 and above (arm, arm64, and amd64)"),(0,r.kt)("li",{parentName:"ul"},"Debian-based Linux Distributions (64-bit only)"),(0,r.kt)("li",{parentName:"ul"},"macOS El Capitan (10.11) and above"),(0,r.kt)("li",{parentName:"ul"},"Windows 7 & above (64-bit only)")),(0,r.kt)("p",null,"To put it plainly, without porting Cwtch UI to a different UI platform ",(0,r.kt)("strong",{parentName:"p"},"we cannot support a 32-bit desktop version"),"."),(0,r.kt)("h3",{id:"constraints-introduced-by-appstore-policy"},"Constraints introduced by Appstore Policy"),(0,r.kt)("p",null,"As of writing, ",(0,r.kt)("a",{parentName:"p",href:"https://developer.android.com/google/play/requirements/target-sdk"},"Google is pushing applications to target API 31 or above"),". This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality."),(0,r.kt)("h3",{id:"cpu-architecture-and-cwtch-bindings"},"CPU Architecture and Cwtch Bindings"),(0,r.kt)("p",null,"We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for."),(0,r.kt)("p",null,"It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Architecture / Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Windows"),(0,r.kt)("th",{parentName:"tr",align:null},"Linux"),(0,r.kt)("th",{parentName:"tr",align:null},"macOS"),(0,r.kt)("th",{parentName:"tr",align:null},"Android"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"x86-64 / amd64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")))),(0,r.kt)("p",null,'"\ud83d\udfe1" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).'),(0,r.kt)("h3",{id:"testing-and-official-support"},"Testing and official support"),(0,r.kt)("p",null,"As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers")," to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues."),(0,r.kt)("p",null,"We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances."),(0,r.kt)("h3",{id:"end-of-life-platforms"},"End-of-life platforms"),(0,r.kt)("p",null,"Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. ",(0,r.kt)("a",{parentName:"p",href:"https://www.microsoft.com/en-us/windows/end-of-support"},"Windows 7 fell out of support on January 14, 2020"),", Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025."),(0,r.kt)("p",null,"Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also."),(0,r.kt)("p",null,"The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations"},"Cwtch currently requires libc 2.31+"),"."),(0,r.kt)("p",null,"Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers groups")," to help us understand the limitations of Android support across different API versions."),(0,r.kt)("h2",{id:"how-we-decide-to-officially-support-a-platform"},"How we decide to officially support a platform"),(0,r.kt)("p",null,"To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform needs to be officially supported by our development tools")," - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target operating system needs to be supported by the Vendor")," - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform must be backwards compatible with the most recent version in general use")," - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch ",(0,r.kt)("em",{parentName:"li"},"may")," run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"People want to use Cwtch on that platform")," - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!")),(0,r.kt)("h2",{id:"summary-of-official-support"},"Summary of official support"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). "),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. A version of this table will be ",(0,r.kt)("a",{parentName:"p",href:"/docs/getting-started/supported_platforms"},"maintained as part of the Cwtch Handbook"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607"},"Known Issues. Specific changes to Cwtch are required for support."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}c.isMDXComponent=!0},6149:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5f9a9669.b039c6fb.js b/build-staging/de/assets/js/5f9a9669.b039c6fb.js new file mode 100644 index 00000000..a6919f47 --- /dev/null +++ b/build-staging/de/assets/js/5f9a9669.b039c6fb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3278],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=s(n),d=o,f=u["".concat(l,".").concat(d)]||u[d]||m[d]||a;return n?r.createElement(f,c(c({ref:t},p),{},{components:n})):r.createElement(f,c({ref:t},p))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,c[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>m,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:7},c="Einen Kontakt blockieren",i={unversionedId:"chat/block-contact",id:"chat/block-contact",title:"Einen Kontakt blockieren",description:"1. In einem Konversationsfenster",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/block-contact.md",sourceDirName:"chat",slug:"/chat/block-contact",permalink:"/de/docs/chat/block-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/block-contact.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Eine Datei teilen",permalink:"/de/docs/chat/share-file"},next:{title:"Einen Kontakt entsperren",permalink:"/de/docs/chat/unblock-contact"}},l={},s=[],p={toc:s},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"einen-kontakt-blockieren"},"Einen Kontakt blockieren"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"In einem Konversationsfenster"),(0,o.kt)("li",{parentName:"ol"},"Zu Einstellungen gehen"),(0,o.kt)("li",{parentName:"ol"},"Scrolle nach unten zum Kontakt blockieren"),(0,o.kt)("li",{parentName:"ol"},"Verschiebe den Schalter auf Kontakt blockieren")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/5fdc7b06.83b3ba22.js b/build-staging/de/assets/js/5fdc7b06.83b3ba22.js new file mode 100644 index 00000000..010a0cf7 --- /dev/null +++ b/build-staging/de/assets/js/5fdc7b06.83b3ba22.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2619],{2401:e=>{e.exports=JSON.parse('{"title":"Gruppen","slug":"/category/groups","permalink":"/de/docs/category/groups","navigation":{"previous":{"title":"Entfernen einer Konversation","permalink":"/de/docs/chat/delete-contact"},"next":{"title":"Eine Einf\xfchrung in die Cwtch Gruppen","permalink":"/de/docs/groups/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6036bdcc.00b31633.js b/build-staging/de/assets/js/6036bdcc.00b31633.js new file mode 100644 index 00000000..a8595607 --- /dev/null +++ b/build-staging/de/assets/js/6036bdcc.00b31633.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1745],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(7294);function A(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(A[t]=e[t]);return A}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(A[t]=e[t])}return A}var s=r.createContext({}),o=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},p=function(e){var n=o(e.components);return r.createElement(s.Provider,{value:n},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,A=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=o(t),d=A,m=c["".concat(s,".").concat(d)]||c[d]||u[d]||i;return t?r.createElement(m,a(a({ref:n},p),{},{components:t})):r.createElement(m,a({ref:n},p))}));function m(e,n){var t=arguments,A=n&&n.mdxType;if("string"==typeof e||A){var i=t.length,a=new Array(i);a[0]=d;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l[c]="string"==typeof e?e:A,a[1]=l;for(var o=2;o{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var r=t(7462),A=(t(7294),t(3905));const i={sidebar_position:5},a="Experiment klickbarer Links",l={unversionedId:"settings/experiments/clickable-links",id:"settings/experiments/clickable-links",title:"Experiment klickbarer Links",description:"Wenn aktiviert, stellt diese Funktion ein Entanonymisierung Risiko dar.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/clickable-links.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/clickable-links",permalink:"/de/docs/settings/experiments/clickable-links",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/clickable-links.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Bildvorschau und Profilbilder",permalink:"/de/docs/settings/experiments/image-previews-and-profile-pictures"},next:{title:"Nachrichtenformatierung",permalink:"/de/docs/settings/experiments/message-formatting"}},s={},o=[{value:"Risiko",id:"risiko",level:2}],p={toc:o},c="wrapper";function u(e){let{components:n,...i}=e;return(0,A.kt)(c,(0,r.Z)({},p,i,{components:n,mdxType:"MDXLayout"}),(0,A.kt)("h1",{id:"experiment-klickbarer-links"},"Experiment klickbarer Links"),(0,A.kt)("admonition",{title:"Gefahr",type:"danger"},(0,A.kt)("p",{parentName:"admonition"},"Wenn aktiviert, stellt diese Funktion ein ",(0,A.kt)("strong",{parentName:"p"},"Entanonymisierung")," Risiko dar."),(0,A.kt)("p",{parentName:"admonition"},(0,A.kt)("strong",{parentName:"p"},"keine")," URLs von Personen \xf6ffnen, denen Du nicht vertraust. Links, die \xfcber Cwtch gesendet werden, werden \xfcber den ",(0,A.kt)("strong",{parentName:"p"},"Standard")," Browser auf dem System ge\xf6ffnet. Die meisten Webbrowser k\xf6nnen keine Anonymit\xe4t anbieten.")),(0,A.kt)("h1",{id:"aktiviere-das-experiment-mit-klickbaren-links"},"Aktiviere das Experiment mit klickbaren Links"),(0,A.kt)("p",null,"Anklickbare Links sind standardm\xe4\xdfig ",(0,A.kt)("strong",{parentName:"p"},"nicht")," aktiviert. Um Cwtch das \xd6ffnen von Links in Nachrichten zu erm\xf6glichen:"),(0,A.kt)("ol",null,(0,A.kt)("li",{parentName:"ol"},"Zu den Einstellungen"),(0,A.kt)("li",{parentName:"ol"},"Experimente aktivieren"),(0,A.kt)("li",{parentName:"ol"},"Aktiviere das ",(0,A.kt)("inlineCode",{parentName:"li"},"Klickbare Links")," Experiment")),(0,A.kt)("p",null,(0,A.kt)("img",{src:t(1302).Z,width:"1243",height:"58"})),(0,A.kt)("h2",{id:"risiko"},"Risiko"),(0,A.kt)("p",null,"Klickbare Links in Nachrichten sind ein sehr n\xfctzliches Feature, aber es gibt Risiken, die Du beachten solltest, wenn Du diese Funktion aktivierst."),(0,A.kt)("p",null,"Um eine versehentliche Ausl\xf6sung zu verhindern, \xf6ffnet Cwtch nach einem Klick auf einen Link in einer Nachricht zuerst eine zus\xe4tzliche Aufforderung mit zwei Optionen:"),(0,A.kt)("p",null,(0,A.kt)("img",{src:t(6004).Z,width:"1274",height:"192"})),(0,A.kt)("ol",null,(0,A.kt)("li",{parentName:"ol"},"Die URL in die Zwischenablage kopieren"),(0,A.kt)("li",{parentName:"ol"},"\xd6ffne die URL im ",(0,A.kt)("strong",{parentName:"li"},"-Standard-Browser"))),(0,A.kt)("p",null,"Du kannst die Zur\xfcck-Taste auf DeinemGer\xe4t verwenden oder von dieser Eingabeaufforderung wegklicken, um die Auswahl einer der beiden Optionen zu vermeiden."),(0,A.kt)("p",null,(0,A.kt)("strong",{parentName:"p"},"Cwtch kann Dich nicht sch\xfctzen, wenn Du b\xf6swillige Links \xf6ffnest"),"."),(0,A.kt)("p",null,"Die URL wird im ",(0,A.kt)("strong",{parentName:"p"},"-Standard-Browser")," ge\xf6ffnet, was wahrscheinlich mindestens Deine IP-Adresse dem Server bekanntgeben wird, der die URL hostet. Webseiten k\xf6nnen auch andere Browser-Verwundbarkeiten nutzen, um zus\xe4tzliche Informationen zu sammeln oder Deinen Computer weiter auszunutzen."))}u.isMDXComponent=!0},6004:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png"},1302:(e,n,t)=>{t.d(n,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABNsAAAA6CAIAAAAGIMiyAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO3de1yM6f8/8GumdFCrViRZpbZVSbRbNklYpSSklmgplXNC+aLNSiJMRC1bDkmxkkOlROkcHWw1HTQdhlqsY6VaNoNQ8/vj/n3uzzw6TBmSz3o9/5q57muu08w1j3nPdd/XzRg2bBgRSlpaWngGAAAAAAAAABEw+7oBAAAAAAAA8JlCRAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfQMRKQAAAAAAAPQNRKQAAAAAAADQNxCRAgAAAAAAQN/47CJSFotV3UFCQoLIBXI4HBaL1emhzMzMqKiody1w+PDhoaGhmZmZHA6noqIiLy8vNDSUOnTz5k0fHx/q8YkTJ86ePSukHBcXl+rqaktLy55XLaQvglX3BIvFunnzZsd0BQWF5OTkgICA92kMAAAAAAD8O4j3dQP6AJ/P9/PzE0xpamrqq8a0Y2tru2HDBgkJifz8/Dt37rS1tamoqMjJyXXMOXjw4P79+3/8Fr4nJSWlQYMGDR48uK8bAgAAAAAAPcLn89ulMBiMD1X4R4pIlZSU6Me1tbWdpnw0fD7/5MmTH7PGnnN1dX3x4sXKlSvLysqE55wxY8bHadKHVVFRoa+v39etAAAAAACAblCB6I8//jh16lRdXd0hQ4YQQurq6jgcTkZGRkxMDPkQoWnvRqSenp7Tpk0bMmSIlJQUnWhiYkIIyc7OplNevXpVV1eXkpKyZ8+eXm3PJ27z5s1fffXVli1bug1HAQAAAAAAeg+fz//xxx/XrVunrKwsmK6srKysrGxhYbFu3bpff/01JibmPYPSXryONCIiYunSpaqqqhISEi8FUEcFUyQkJFRVVZctWxYeHt577emWi4tLSUnJgQMH8vPzq6qqrl+/7unpSR0yMzM7d+4cm83mcrklJSW///674BrvqFGj/vjjD+ol7c4HFrRp06bs7OzKyko2m33o0KGOGbS1tRsaGqKjo3vS2ri4uCtXrtBPvb29c3JyqqqqSktLO64Am5ubs9ls6m+M5cuXJyYmlpaWcrncgoICf39/wZwfqi9CsNns4OBg6jGHwwkMDMzKyqqsrCwuLqbTBSkoKFy5ciUvL8/AwIAQsmPHjry8vKqqqpKSkpSUFC0trXeqHQAAAAAAhOPz+T4+Pv7+/u3CUUHKysr+/v4+Pj4dz+l9J721Rvp///d/xsbGr1+/TkxMDAsL43K57TKMGTOGfqylpbVkyRIrKytjY+P169fv37+/l1pFYTKZ1dXVgimBgYEhISGEEFlZWXV19XPnzjU3N8+ZM2fx4sVU2PPy5cs3b94kJyffv39fQ0NjxowZPj4+q1atol4+ZMiQhISExsbGyZMnz58//+3bt9u2bWtXqYeHh4uLS3x8fElJiba2to2NzYEDB9auXSuYR1FR8e+//xahR35+fjY2Nunp6WVlZSNGjGj3L4WRkZGvr299ff3y5csJIZKSknV1ddevX29sbDQ0NLSxsbl79y4dVX6ovvScoaFhSkrKvXv3JkyYYG5uvmXLlnaRcFhYmIKCgqenJ5vNXrZsmZ2dXVpaWmFhoby8/NChQzt+tAAAAAAAoB1lMmBRm95kvpo6f6B4ZwuTfMLnE8In/FZ+G/E1kXAY25NiHRwc+Hz+9u3bRV4p7a2I1MLCghBy6dIleplRCC6Xu3Hjxra2NltbWwsLi96OSDvubFRUVEQ/Dg4OTkpKIoQ0NTXt3r174sSJKSkpubm5ubm5dB41NbWvv/6afpqZmUkVeOjQocuXL0+bNq1jFDdz5szq6mp6NIYNG6anp9cuT79+/UTr0fTp069du9ZpTCgrK+vl5fXy5cvVq1c3NjYSQg4ePEgfDQkJYbPZgi35UH3puWvXrlFVHD9+vKioSFdXV/BoVFSUqqqqr69vRkYGIURDQ4PP58fHx6ekpIhcIwAAAADAZ8WOr+vbatZpICqICkf5czUlF/coHKU4OjqWl5fHxsaKFpT2VkSqqKjY2tp6+PBhOoXL5XZsIp/Pp8+6PHz4sLW1taKiYi81SbDSnuxsFB0dvXXrVhkZGeqpvb399OnTVVRUpKSkBgwYUF9f3+mrOBzOnDlzZGRkeDyeYLqCgsKwYcOqqqqopwwGo+NyaENDg5qa2rt2Z8qUKXJyciUlJZ0edXNzk5eXd3R0vHPnDp24fv36CRMmDBo0SFpaWlZWVkJC4oP3RTR1dXXS0tL0UyMjI2Vl5X379sXFxVEpSUlJU6ZMCQwM/Ouvv0pKSg4fPnz//v0PUjUAAAAAwL+SHV93Z6u58Dz/f4GUT96SNqn1hu9ahbu7e2xsLJ/PFyEo/ezuRyoaBweHX375hRBy6tSpDRs2cDicrnK+fv26tbW1XQhHCGlpaSksLNT+Dy0tLSMjo3Z5/vrrL3l5+U2bNr1T24YOHUoIYTI7fytv3LghJSW1cuVKOoXFYjk7O9+/f//QoUOurq5C7nzzPn35IGpqal6+fGlra0v/L5CVlWVoaHjixImXL1/OmjUrPj7e2tq6N6oGAAAAAPgXUCYDfFvNepKTT/htpI0xV4upPOCda1FWtrW1fffWEdJ7EWl9fb2YmJhgIKSlpaXZgeC2NCtXrhQTE+tq7bFvGRkZvXnzZvHixWFhYbm5ue0u3hX8J0BbW/vJkycdS6itrdXW1tbQ0BBSy759+xobG+fOnTtr1qyety0nJ6e1tbWr82aTkpIyMjKmTp3q4+NDpXz77bd379718PA4e/as4OnKH7YvH8STJ0/CwsJUVFSOHTsmmL5nz54ff/zR2dm5X79+5ubd/N8DAAAAAPDZWtSm1+3JurRWwmeavfM5mxRTU1PRXthbZ+2mpKSsWLFi5syZDAbj+PHjwref0dLScnFxsbKy4vP5H+H6QAaDYW9vL5jy9OlT6trRrjQ2NsrKyh47diwvL09bW1tHR4e6JpMybdq0lpaW27dvT5gwQVdX9+jRo1T6s2fPhg4dam5unpKScurUqR07doSEhJw5c+bu3buGhoYNDQ2hoaGCtdTW1oaHh69cuXLXrl2zZ8+urq5+8eKFqqqqvLz8smXLCCHPnz/X0NAwNDTMz8+nX3X//v3S0lITExN/f//s7GwdHZ3+/fvT8SchZOXKlTExMQsWLHj8+PHRo0efPXumo6Ozc+fOO3fuGBsbDxw4ULANXfVFsOqe9IUaZxcXF/opn88XYS/lX3/9VUlJae7cuYGBgR4eHqtWrdLV1S0rK6uvrzcyMpKUlHzw4MG7lgkAAAAA8JmYzO8+wqRP2W3lt0noDhGtIl1dXWrd7l1P3O2tiDQgIEBXV3fChAk2NjbW1tYtLS30IWpRSzDylJSUpE46zc3N3bdvXy81icZgMLZv3y6YwuVyhUek3t7eX3/99ffffz9+/PjHjx8XFRWNGDGCPlpeXm5lZdW/f//Gxsbw8HB6Z6bExEQnJ6eAgABPT8/z589LS0s7ODi4u7v369fv77//vnTpUseKjhw5UlZWtm7dulGjRk2cOPHNmzdPnz69ceMGdTQtLc3c3Nzf33/KlCmCr9qyZcvWrVtNTU2tra2fP3/e8ZrS1atXR0ZGurq6PnjwIDg4ePPmzTY2Nm/evKmpqampqRHM2VVfBKvuYV8YDIaXlxf9tLW1VbS7+3h5eSkqKs6YMePx48ctLS2ampoTJ06UkJB4/vx5amrq7t27RSgTAAAAAOBzoM4f2H0mQgghbaStlbSJKX0hWkVDhogYyjKGDRsmPIfgTjPvytPT09zcXFFRUUpKik40MTEhhGRnZ9Mpr169qq+vT0lJaXdvTAAAAAAAABBZ1VuPnmyxyyfkLb/1Bf+1/G0PIibKlrmtra0jR45kMBjvukbauxEpTUlJiX5cW1vbaQoAAAAAAAB8QJdbF4/kDxKeRzAilc1bIj5MToSKHj16ZGJiIkJE2ltn7bbTMeZEFAoAAAAAANCrrjLudBuR0hiE8arskaxIEWlZWZkIryK4+wsAAAAAAMC/1Slm6VvS1pOcTMJkEsar1D9Fqyg9PV20FyIiBQAAAAAA+Hd6RP7xEUsTnodBGAxCGAwixmC+ja58/fDpu9by8OHDmJgYEU7ZJYhIAQAAAAAA/sXOMTi/iKX0ZKVUnDAlGGKNAVfftYrAwECRmkYIIlJaTExMZGTkBykqISGhh7c5YbPZW7Zs6UnOrprX87oCAwMzMzN7kpMQYmlpWV1draWl1cP8nyfBIe35G/HvYG9vf/PmzZ7kZLFYubm5vd2ej6/nk1c0Z8+ePXv2bO+VDwAAAJ+VcwyOqXhYKLPwFqOhq9CUQRhMwpRkiPNjuPXh13teeEREBLVAKlrbPtLORp+IK1eufP311+0SW1tbey/0KigoKCgocHNz66XyRRMTEyMlJWVlZdXXDRHFpzmknzN/f/9p06ZZW1vfv3//o1W6du3aFStW6OjoCCZyudxdu3adPHlSX1//zJkzVOLbt28bGhri4+MDAgIIIdShDRs2xMfHf7TWfij48AMAAIDIHpF/9jCv7SHXhGfj8/l8Pr/V99A2xjYnJ6dui42IiNi2bZuYmJhop+ySzy0iXbhwYb9+/Qghvr6+mpqaCxYs6O0aS0pKKisre7uWd1VeXi54h9j/Lb06pAcPHtTQ0LC0tOyl8j8Rly9fvnv37urVqz9IaVwuV1FR8WOGoz3k5eWVk5MzduzYRYsWLVmypKamJi4urq8b9V4+ze8TAAAA+Dehokomk7lt2zYOh7N+/fqubhf68OHD/fv3x8TEMJlMkcNR8rlFpI2NjdSDtrY2Pp//Ee5As2LFit6uQgQ+Pj593QTR9eqQMplMMTGx3iv/EyEmJsZkfrAz9sPDwz/NM5bfvHlTW1tbW1ubnJxcXFxsZGT0vx6RfprfJwAAAPAvw2AwqCAzNjb2/Pnzc+fONTMzGzt2rJKSEiGktrb2xo0baWlp0dHRYmJi77M6SsF1pP81dOjQa9euVVVV5efnb9iwgUpUUFAIDw8vLi7mcDgXLlzQ09Nr96p58+alpqaWl5cXFhaGhIS0O5qXl7dz507qsaenZ25ubmVlZU5Ojqenp2A2Dw+PsrIyV1dXfX39CxculJSUcLncvLw8d3d3Os9XX32Vn59fVVV17dq1Tn+YmpiYJCQklJWVlZSUHDlyREhPo6KioqOjCSGWlpZsNjsqKqq0tLS8vDw2Nnb48OHtMh85cqSgoGDy5MkKCgqRkZGlpaUVFRW5ubmOjo6C2ToOlIyMTGZmZlRUFJXh6NGjOTk5w4cPj4mJiYqKysrKqqysvH79+vr164UMNYvFSkxMPH/+PIfDOXnypOCQslis1NTUK1eulJeXs9lsf3//gIAAaogyMjJmzpxJFevs7JyVlVVRUZGfn+/l5UUlxsTEnDt3rt3bvXPnTlNT0xEjRlRVVZ06dUqwd6GhoYWFhVwut6ioqNvrto2MjGJjY2/cuFFWVhYXF2dsbEwISUhIoE8TXbNmDZfL9fPzo54eO3YsISGBELJ3797CwsKqqqqCgoJdu3bRBTo6Ot66dcvCwoJ66u7uXlJSIiMjIyMjc+TIETabXVlZmZGRQb8j6enpBw4coB57eHgUFxcLNu/cuXPq6uo//PBDVVWVt7c3IaSrcgQFBwez2ezy8vL09HR6bCk+Pj4FBQXUYz09vejo6NLS0hs3brQ7LVZJSSk5OTkhIUFGRkYwfcuWLXl5eVVVVX/88cfWrVupROrNTUpKKi8vLy0t/e2334SPebfa2tpev34tJENXg08IMTc3T0pK4nA4HA4nPT1dQUGBSh83bhz1koyMjDlz5hBCupq/MTExx48fT01Nrays/OWXXwgh27dvz8/Pr6ioyMjIoE/WcHJyouZFQUFBx5lIOnz4hYzP+8wONze3a9euVVZWlpSUUJevdzr3u5oUO3bsyM/Pr6yszMrKyszM3L59O5XescvCv1IAAACgD1FBJpPJFBcXv3DhwqpVq4yMjNTU1NTU1IyMjFatWnXhwgVxcfH3XB2lICL9L0lJyfDw8DVr1vz111+Ojo7U72YWi6Wuru7h4bFy5Up5efl2kaSOjo6Xl9etW7cWL14cGBhYWFjYVeFLlixZtGhRQkLCggULIiMjORwOfWjp0qXOzs6nTp0KCQnhcrl37tw5ePDg5s2bHz58KHjqdr9+/YKCgpYvX/7gwYPVq1cbGRm1q8LHx4fH49na2u7Zs2f8+PFUsNEtOTm5R48eLV26NCwsTENDo10HAwICDAwMtm/ffvXq1c2bN2tqavr5+c2cOTMiIoIOQigdB4rH4wUFBY0ePdrd3d3JyWn8+PFBQUHUuZ0jRoyIjIx0dHTkcDhLly41MzMTMtQaGhrPnj3bvXv38ePH2zV+yJAhqampS5Ysyc/Pt7W1VVNT8/X19fPzExcXp4J2Q0NDDw+P7OzsSZMmXbp0ycHBgY7rhg4deuzYMcG3+5dffklPT7979662tvaiRYsEK3r48GFkZOTatWuzsrKsrKwWLlwoZEh9fX2ZTObatWt37do1cOBAKgIpKChQU1Ojgplx48bxeLyxY8dS+TU1Ndls9vz582fNmnXmzJkffvhh//792dnZdIEnT55sbGycPn069dTQ0JDL5fJ4vH379unq6gYEBLi6ujY1Nbm7u7e7rrJTdnZ2t2/fzszM1NbW3rFjByGk23IOHDjw3XffHThwwMnJKTk5mc1md1X4rl27JCUlN23atGnTpnY7aR0+fJjJZLq6uvJ4PDrR1dXVzs4uNjbW3t4+Ly/vp59+WrJkCXVoyJAhGRkZTk5OqampFhYWLi4u3XatUwYGBocPH2YwGOfPn+8qj5DBJ4S4ubm1tbWtWbPG2dn5zJkz9KkWfD5/69atfn5+TCaT+rwJmb9U+Orj4xMXF7dmzZo5c+YEBwfPnDnz4cOHa9euJYTo6+uvX7++vLzcwcEhPDxcQkJCeL+6HR+RZ4eLi0tlZeW8efN+/vnny5cvE0I6nfudTgqqa7GxsT/99FN2djb1Tyqd3q7Lwr9SAAAAoG/RQSkVl7ZDpb9/OEo+t7N2hbt79y598uGhQ4csLCxiY2MNDAwuXrx49epVQkhOTo65ubngSxwdHV+8eEFdj1dUVCSkcCsrqxs3brBYLEJIWVkZna6kpDR37ty4uLg9e/YQQng8Hr1mWFdXFxERYW5unpKSQgi5c+cOtd5YXFx89erVOXPmXL/+3y2w5s2bN3z4cBaLVVNTU1NTY2NjM2bMmB52PDQ0lMvlstlsY2NjwZUZBwcHMzMzf3//S5cuEUL69evHZDJVVVUzMzNDQ0PbFdLpQMXHx0+YMGHRokWvX7++ePEitTBLCLl9+zZVApvNzsvLmzFjRlpaWldD/eTJk6VLl3ba8ubm5n379hFCysvLJ06cWFZWlpiYSAgZO3bsDz/8QAiZP38+j8ejgvMdO3ZYWVmZmJgkJycTQu7du0ctuhKBt7urIdq2bRv1ICUlxdjYWEjgZ2trq6KiYmdnR73LYmJi27Zt09fXj4iIsLOzc3BwCAoK0tDQiImJsbe3V1BQ0NfXl5eXj4yMnDBhAoPBUFRUVFJSonfloZWXl48ePZp6PHLkyKNHjxJCvv/++9OnT1OZuVxuUlKSra1tRUVFV23rSrflTJgwITY2lhouIeHorFmz1NXVFy5cSM0Fapwpp0+fHjhwoJubW7vLTS0sLEpKSqg9h0pLS0eOHGlmZhYWFkYIaW5u3rt3L1Xj5MmTR40a9a792rt37549exgMRkNDw/r16wXnXTuSkpJCBl9MTExKSkpFReXkyZOC3Wez2UlJSYSQUaNGUdceC5m/HA5n8+bN1CEWi1VVVUWN54kTJ0JCQqZMmTJjxoynT59SuxYVFRVNmTJFeO+6HR+RZ4e4uPiAAQO++uor+h3sdO53OinMzMxKSkr8/f0JIaWlpdOmTaPymJubd+yy8K8UAAAA6HNUtMlgMPh8frvI8/0DURoi0k6kpaW1tbVJSkoqKSnJysrOmjWL3pa2ublZMKeSktLTpz26gayCgsK9e/c6po8dO5bBYFy79t89r7y9vSdNmiQlJUW9zdLS0u1ewuPxnjx5MnDgQMFEdXV1BoNBRbyUqqqqnjRMUHNz86BBg+inkyZNamxspH5PE0L27t0rLS1tb2/v5ORUVla2f/9+OggXMlCenp7Z2dl8Pr+rW2U0NTXJycl1O9TC8Xi8ly9f0peANjU1UaM3aNAgOTk5wSiitbW13Wvpt1tI+Y6OjvPmzRs4cGBbW9uAAQPExbucON988w2Px6ODn8jISG9vb01NzaKiops3b44bN446YXLXrl02NjaOjo7Dhw+/ffs29T/CyJEjJ02aZG1tXV1dffr0afqEZ0LI5cuXWSyWvr7+d999x+fzjxw5Qo3Y7du3qQy1tbVNTU30CaU91205SkpKAwYMuHv3brdFaWtrt7S0dPxrRlJSUldXt6CgoGNM+OWXX1ZXV9NPHz9+PHTo0I4l83i8dtf3trS0iImJycjI0CuuMjIyDAbj+fPndJ6NGzfGx8fv3bvXwsJC+Cm7J0+eFDL4v/32m7Oz88aNG9esWXP9+nVqfU9QQ0MDfV1uV/OXz+fT+eXk5FRVVemP5T///NO/f39FRcVnz54JaaQQHcen3dF3mh0hISHW1ta//vprbW1tUlKSv79/p3O/00khJyf3559/dmxDp10W8pUCAAAAn5QPGH92hLN2hamtrX3x4kViYqLBf1BrCzQej/fll1/2pKhXr14NHjy4Y3pqampdXZ2Pj4+GhgYhxNnZed68eUePHjUxMZk4cWJXpcnJydXV1QmmUEtPmzdvppvq4ODQk4YJERgY+OWXX9KXqN2/f3/ZsmUGBgb79u1TV1cXvMZVyEBt2LBBWlp6wIAB1MmrFMFtdeTl5evr67sdatE0NTU1NzcbCBBhVycZGZkNGzYUFBQYGxubmJjU19cLyfzo0SMZGRnq2lFCiKWlJYPBoE5HzMnJGTlypKmp6a1btwghXC7XwMBAR0cnPz+fyrxly5ZJkyZ5eHjw+XxXV1fBYuPi4urr621sbCZOnEitXtbW1r569UpwtVZOTu7x48eEECpCEN4p+mtFSDl0htevX6urqwsvkBDS1NQkJSVlYGDQLr2lpeX48ePGxsb0qhqtublZWVmZfjpw4MCmpqZuKyKE5OfnM5lMwQ/5/PnzW1tbBRdmKdu2bXv+/HnHMLIdIYOflJRkZ2c3bdq0mJgYU1NT+nrLjno4f//555+bN28KfiwTExOfPn0qwh8K76Or2XH48GFLS8sFCxZUVFQ4Ozvr6+t3nPtdTYrm5uZO/1PotMtCvlIAAADg84GItBvFxcXTp0+nrtGaOXMmtX8J7erVqwoKCkFBQUpKSpaWltTv41evXnWMB0pLS8eOHUv95Fq4cCF9f5G2tjYvLy9xcXFqaxBFRUUJCYnBgwfr6OjQO99QvvnmG2dnZx0dnZCQECkpKWoNh67r9OnTDx8+3Lhxo5mZmYyMjKOjo6GhoeDLeTyejIzMO/3kraysPHDgwJgxY6i2OTs7r1ixQklJ6ebNmy0tLT0ZqKlTpy5cuPDs2bPnz5+3s7ObOnUqlVlXV9fLy0tHRycwMFBWVvbs2bPdDrVo4uLipKWlT548qaGhoaam1u1Wpc3NzYqKitQ2TnTiiBEjJCUlFRQUtLS03Nzc5OXlqXTBIaXfiNjY2IaGhi1btpiZmU2dOtXd3b2srKympoYQEhQUJCYmZmRklJubSwjJycnR1NQcPHjw77//TgiZMmWKp6enjo5OdXV1p2tl1EdIS0srLS2NSuFwOLNnz3Z2dh4zZkxYWNjbt29PnDhBCHn8+PHo0aNdXFyMjIz09fU7FsXj8dTV1enrWrsqh1ZdXT1jxow5c+YMHz589erVw4cPf/LkCYPBaHebnOTk5H/++cfb21tPT09fX3/VqlX0ocDAwPj4eDs7u+XLlwu+5Pr163p6et7e3hoaGt7e3iNHjuzhdrilpaVlZWUuLi4eHh5GRkaurq5Lly7Nzc0VvEiV7mxsbOy33377008/0Yn9+/fX+g8lJSXhg79hw4a5c+fW1tbW1NRQ23R31Soh81dQVlaWrq6ur6+vjIyMoaEhtaNPUlKSvLz8sWPH9PT07O3tVVRUejIO76Or2eHj4zN58uTq6mpqN/LW1taOc7+rSZGXl6enp0f9xbZx48YvvvhCSJeFf6UAAADAZwIRaTe8vLxKSkpcXV3Lyso2bdo0btw4waNnz549derU+PHj09PTd+3aRe02lJaWpqqqmpqaKpjT09MzLy/PwcGhoqJi3bp19DWBhJCioiIWi6WiohIeHv7bb79xOJzVq1dHRUVpamoK/jiur693c3M7d+6cpqZmQEAAtVAmWJevr+/z588DAgJycnIcHBwEqyCEREdHv3jxIi0tbfLkyT3vfkRERGRkpKWl5aZNm9TV1Z2cnNLT048ePfrixYt223t2OlA///zzrVu39u7du3PnzpqaGnqzooaGhjlz5pw/f/7bb7/dv39/aWlpt0MtmqysrKCgoGHDhlFbV8+aNUv43j8RERF1dXXBwcGCtzOpqKhITEycMmVKTEzM7Nmz6eUgwSGl3wgej8disRgMRlBQ0L59+5qamgS3mKqsrJSQkKAumTty5AiDwbhz5w61vq2iomJpaXnmzJn4+HhVVdWO91OJi4tTV1dvbW2lIlhCyI4dO2pqatatWxcZGamsrOzn50eFEMHBwU+ePNm4cePBgwdbW1s7RlDR0dGysrIXL16kFi27KofGYrHq6uq2b9+emJhoZ2enq6ublpZWWlrKYrHoayMJIffv3w8KCvriiy9OnToVHh4+Y8YMwUI8PT0LCwtdXfZp1doAAAHqSURBVF0F0/38/JKSkqytrS9evGhubh4aGirkat52fv7556qqqoULF4aHhy9evJjNZne1yBYQEHDv3j3BfYa2b9+e8B9+fn7CB3/06NFeXl6VlZXe3t7FxcWC58a3I2T+tmvPmTNnpk2bdv369aCgIFNTU0JIcnLy0aNHR40aFRUV5ebm9uDBgx6Og8g6nR1qamrjx48/ePBgYWHh7Nmzz58/X1pa2nHudzUpdu/efeXKlVmzZsXHx5uamra0tFAfv067LPwrBQAAAD4TjK5ueErreB0jwPuIiYl59eqV8O1qoVPZ2dlcLnfZsmV93RCAHikuLg4LCwsODu7rhgAAAMCnC2ukAP8b9PT0Bg0aRG80BfCJmzx5cv/+/cvLy/u6IQAAAPBJw167AP8b7O3t//77byE31QT4FPj7+ycnJz979szd3f3mzZvU/ZwAAAAAuoKIFOB/g4GBgQh39AH4yEaPHm1lZdXW1vbnn38KXkQNAAAA0ClcRwoAAAAAAAB9A9eRAgAAAAAAQN9ARAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfeP/AQclJUZgqx9hAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6048.e7c7c18a.js b/build-staging/de/assets/js/6048.e7c7c18a.js new file mode 100644 index 00000000..bac03d84 --- /dev/null +++ b/build-staging/de/assets/js/6048.e7c7c18a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6048],{9058:(e,t,a)=>{a.d(t,{Z:()=>p});var l=a(7294),r=a(6010),n=a(7961),o=a(7524),s=a(9960),i=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function c(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,i.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function d(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function g(e){return l.createElement(u.Zo,{component:d,props:e})}function h(e){let{sidebar:t}=e;const a=(0,o.i)();return t?.items.length?"mobile"===a?l.createElement(g,{sidebar:t}):l.createElement(c,{sidebar:t}):null}function p(e){const{sidebar:t,toc:a,children:o,...s}=e,i=t&&t.items.length>0;return l.createElement(n.Z,s,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(h,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":i,"col--9 col--offset-1":!i}),itemScope:!0,itemType:"http://schema.org/Blog"},o),a&&l.createElement("div",{className:"col col--2"},a))))}},390:(e,t,a)=>{a.d(t,{Z:()=>A});var l=a(7294),r=a(6010),n=a(9460),o=a(4996);function s(e){let{children:t,className:a}=e;const{frontMatter:r,assets:s}=(0,n.C)(),{withBaseUrl:i}=(0,o.C)(),m=s.image??r.image;return l.createElement("article",{className:a,itemProp:"blogPost",itemScope:!0,itemType:"http://schema.org/BlogPosting"},m&&l.createElement("meta",{itemProp:"image",content:i(m,{absolute:!0})}),t)}var i=a(9960);const m={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,n.C)(),{permalink:s,title:c}=a,u=o?"h1":"h2";return l.createElement(u,{className:(0,r.Z)(m.title,t),itemProp:"headline"},o?c:l.createElement(i.Z,{itemProp:"url",to:s},c))}var u=a(5999),d=a(8824);const g={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,d.c)();return t=>{const a=Math.ceil(t);return e(a,(0,u.I)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return l.createElement(l.Fragment,null,a(t))}function p(e){let{date:t,formattedDate:a}=e;return l.createElement("time",{dateTime:t,itemProp:"datePublished"},a)}function b(){return l.createElement(l.Fragment,null," \xb7 ")}function E(e){let{className:t}=e;const{metadata:a}=(0,n.C)(),{date:o,formattedDate:s,readingTime:i}=a;return l.createElement("div",{className:(0,r.Z)(g.container,"margin-vert--md",t)},l.createElement(p,{date:o,formattedDate:s}),void 0!==i&&l.createElement(l.Fragment,null,l.createElement(b,null),l.createElement(h,{readingTime:i})))}function f(e){return e.href?l.createElement(i.Z,e):l.createElement(l.Fragment,null,e.children)}function v(e){let{author:t,className:a}=e;const{name:n,title:o,url:s,imageURL:i,email:m}=t,c=s||m&&`mailto:${m}`||void 0;return l.createElement("div",{className:(0,r.Z)("avatar margin-bottom--sm",a)},i&&l.createElement(f,{href:c,className:"avatar__photo-link"},l.createElement("img",{className:"avatar__photo",src:i,alt:n})),n&&l.createElement("div",{className:"avatar__intro",itemProp:"author",itemScope:!0,itemType:"https://schema.org/Person"},l.createElement("div",{className:"avatar__name"},l.createElement(f,{href:c,itemProp:"url"},l.createElement("span",{itemProp:"name"},n))),o&&l.createElement("small",{className:"avatar__subtitle",itemProp:"description"},o)))}const P={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function N(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,n.C)();if(0===a.length)return null;const s=a.every((e=>{let{name:t}=e;return!t}));return l.createElement("div",{className:(0,r.Z)("margin-top--md margin-bottom--sm",s?P.imageOnlyAuthorRow:"row",t)},a.map(((e,t)=>l.createElement("div",{className:(0,r.Z)(!s&&"col col--6",s?P.imageOnlyAuthorCol:P.authorCol),key:t},l.createElement(v,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})))))}function _(){return l.createElement("header",null,l.createElement(c,null),l.createElement(E,null),l.createElement(N,null))}var k=a(8780),Z=a(1506);function I(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,n.C)();return l.createElement("div",{id:o?k.blogPostContainerID:void 0,className:(0,r.Z)("markdown",a),itemProp:"articleBody"},l.createElement(Z.Z,null,t))}var C=a(4881),w=a(1526),T=a(7462);function y(){return l.createElement("b",null,l.createElement(u.Z,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts"},"Read More"))}function F(e){const{blogPostTitle:t,...a}=e;return l.createElement(i.Z,(0,T.Z)({"aria-label":(0,u.I)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t})},a),l.createElement(y,null))}const L={blogPostFooterDetailsFull:"blogPostFooterDetailsFull_mRVl"};function B(){const{metadata:e,isBlogPostPage:t}=(0,n.C)(),{tags:a,title:o,editUrl:s,hasTruncateMarker:i}=e,m=!t&&i,c=a.length>0;return c||m||s?l.createElement("footer",{className:(0,r.Z)("row docusaurus-mt-lg",t&&L.blogPostFooterDetailsFull)},c&&l.createElement("div",{className:(0,r.Z)("col",{"col--9":m})},l.createElement(w.Z,{tags:a})),t&&s&&l.createElement("div",{className:"col margin-top--sm"},l.createElement(C.Z,{editUrl:s})),m&&l.createElement("div",{className:(0,r.Z)("col text--right",{"col--3":c})},l.createElement(F,{blogPostTitle:o,to:e.permalink}))):null}function A(e){let{children:t,className:a}=e;const o=function(){const{isBlogPostPage:e}=(0,n.C)();return e?void 0:"margin-bottom--xl"}();return l.createElement(s,{className:(0,r.Z)(o,a)},l.createElement(_,null),l.createElement(I,null,t),l.createElement(B,null))}},9460:(e,t,a)=>{a.d(t,{C:()=>s,n:()=>o});var l=a(7294),r=a(902);const n=l.createContext(null);function o(e){let{children:t,content:a,isBlogPostPage:r=!1}=e;const o=function(e){let{content:t,isBlogPostPage:a}=e;return(0,l.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:r});return l.createElement(n.Provider,{value:o},t)}function s(){const e=(0,l.useContext)(n);if(null===e)throw new r.i6("BlogPostProvider");return e}},8824:(e,t,a)=>{a.d(t,{c:()=>m});var l=a(7294),r=a(2263);const n=["zero","one","two","few","many","other"];function o(e){return n.filter((t=>e.includes(t)))}const s={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function i(){const{i18n:{currentLocale:e}}=(0,r.Z)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:o(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),s}}),[e])}function m(){const e=i();return{selectMessage:(t,a)=>function(e,t,a){const l=e.split("|");if(1===l.length)return l[0];l.length>a.pluralForms.length&&console.error(`For locale=${a.locale}, a maximum of ${a.pluralForms.length} plural forms are expected (${a.pluralForms.join(",")}), but the message contains ${l.length}: ${e}`);const r=a.select(t),n=a.pluralForms.indexOf(r);return l[Math.min(n,l.length-1)]}(a,t,e)}}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/61794344.e3775f5b.js b/build-staging/de/assets/js/61794344.e3775f5b.js new file mode 100644 index 00000000..a100b1dd --- /dev/null +++ b/build-staging/de/assets/js/61794344.e3775f5b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6232],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(a),u=o,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||r;return a?n.createElement(m,i(i({ref:t},p),{},{components:a})):n.createElement(m,i({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"30. Juni 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/de/blog/cwtch-nightly-1-12"}},s={authorsImageUrls:[void 0]},c=[{value:"Update on the Cwtch Stable Roadmap",id:"update-on-the-cwtch-stable-roadmap",level:2},{value:"Next Steps, Refinements, Additional Work",id:"next-steps-refinements-additional-work",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(h,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,o.kt)("p",null,"This post ",(0,o.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h2",{id:"update-on-the-cwtch-stable-roadmap"},"Update on the Cwtch Stable Roadmap"),(0,o.kt)("p",null,"Back in March we extended and updated several goals from ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"our January roadmap")," that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing."),(0,o.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/#official-releases"},"Release Process")),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/"},"Packaging Documentation")),(0,o.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new ",(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"documentation style guide"),", and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/category/building-a-cwtch-app"},"Building a Cwtch App")),(0,o.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. "))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"An implementation of ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")," \ud83d\udfe1 - currently in ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518"},"active development")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information \u2705 - released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")),(0,o.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")," \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12"),". We now believe these changes will be complete in Cwtch Beta 1.13."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks."),(0,o.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below)."),(0,o.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,o.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")," \ud83d\udfe1 - we have already launched an environment for testing ",(0,o.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails"),". Other platforms are underway."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable."),(0,o.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,o.kt)("h2",{id:"next-steps-refinements-additional-work"},"Next Steps, Refinements, Additional Work"),(0,o.kt)("p",null,"As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. "),(0,o.kt)("p",null,"Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like."),(0,o.kt)("p",null,"However, ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")," featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing."),(0,o.kt)("p",null,"The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup."),(0,o.kt)("p",null,"We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards."),(0,o.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,o.kt)("h2",{id:"get-involved"},"Get Involved"),(0,o.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,o.kt)("p",null,"We also also updated our guides on ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,o.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,o.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,o.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6275ceb4.81dd6f1a.js b/build-staging/de/assets/js/6275ceb4.81dd6f1a.js new file mode 100644 index 00000000..33eb0547 --- /dev/null +++ b/build-staging/de/assets/js/6275ceb4.81dd6f1a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6555],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(n),u=a,m=d["".concat(s,".").concat(u)]||d[u]||h[u]||r;return n?o.createElement(m,i(i({ref:t},p),{},{components:n})):o.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:a,i[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const r={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"10. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/de/blog/tags/documentation"},{label:"security-handbook",permalink:"/de/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/de/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/de/blog/autobindings-ii"}},s={authorsImageUrls:[void 0]},c=[{value:"Cwtch Secure Development Handbook",id:"cwtch-secure-development-handbook",level:2},{value:"Volunteer Development",id:"volunteer-development",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},d="wrapper";function h(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"cwtch-secure-development-handbook"},"Cwtch Secure Development Handbook"),(0,a.kt)("p",null,"One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions."),(0,a.kt)("p",null,"We have ",(0,a.kt)("a",{parentName:"p",href:"/security/intro"},"now ported the the handbook to this documentation site"),", along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. "),(0,a.kt)("h2",{id:"volunteer-development"},"Volunteer Development"),(0,a.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,a.kt)("p",null,"We also also updated our guides on ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,a.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,a.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"We still have more work to do on the documentation front:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Ensuring all pages ",(0,a.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"implement the new documentation style guide"),", and include appropriate screenshots and descriptions."),(0,a.kt)("li",{parentName:"ul"},"Expanding the security handbook to provide information on ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"reproducible builds"),", ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"the new Cwtch Stable API")," and upcoming improvements around fuzz testing."),(0,a.kt)("li",{parentName:"ul"},"Creating new documentation sections on the ",(0,a.kt)("a",{parentName:"li",href:"/blog/autobindings"},"libCwtch autobindings API")," and building applications on top of Cwtch.")),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/63475243.07180f7a.js b/build-staging/de/assets/js/63475243.07180f7a.js new file mode 100644 index 00000000..17c3868a --- /dev/null +++ b/build-staging/de/assets/js/63475243.07180f7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6275],{3905:(a,e,t)=>{t.d(e,{Zo:()=>N,kt:()=>h});var m=t(7294);function s(a,e,t){return e in a?Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[e]=t,a}function n(a,e){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var m=Object.getOwnPropertySymbols(a);e&&(m=m.filter((function(e){return Object.getOwnPropertyDescriptor(a,e).enumerable}))),t.push.apply(t,m)}return t}function r(a){for(var e=1;e=0||(s[t]=a[t]);return s}(a,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(a);for(m=0;m=0||Object.prototype.propertyIsEnumerable.call(a,t)&&(s[t]=a[t])}return s}var i=m.createContext({}),l=function(a){var e=m.useContext(i),t=e;return a&&(t="function"==typeof a?a(e):r(r({},e),a)),t},N=function(a){var e=l(a.components);return m.createElement(i.Provider,{value:e},a.children)},o="mdxType",k={inlineCode:"code",wrapper:function(a){var e=a.children;return m.createElement(m.Fragment,{},e)}},c=m.forwardRef((function(a,e){var t=a.components,s=a.mdxType,n=a.originalType,i=a.parentName,N=p(a,["components","mdxType","originalType","parentName"]),o=l(t),c=s,h=o["".concat(i,".").concat(c)]||o[c]||k[c]||n;return t?m.createElement(h,r(r({ref:e},N),{},{components:t})):m.createElement(h,r({ref:e},N))}));function h(a,e){var t=arguments,s=e&&e.mdxType;if("string"==typeof a||s){var n=t.length,r=new Array(n);r[0]=c;var p={};for(var i in e)hasOwnProperty.call(e,i)&&(p[i]=e[i]);p.originalType=a,p[o]="string"==typeof a?a:s,r[1]=p;for(var l=2;l{t.r(e),t.d(e,{assets:()=>i,contentTitle:()=>r,default:()=>k,frontMatter:()=>n,metadata:()=>p,toc:()=>l});var m=t(7462),s=(t(7294),t(3905));const n={sidebar_position:2},r="Authentifizierungsprotokoll",p={unversionedId:"components/tapir/authentication_protocol",id:"components/tapir/authentication_protocol",title:"Authentifizierungsprotokoll",description:"Jeder Peer erh\xe4lt eine offene Verbindung $C$:",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/tapir/authentication_protocol.md",sourceDirName:"components/tapir",slug:"/components/tapir/authentication_protocol",permalink:"/de/security/components/tapir/authentication_protocol",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Paketformat",permalink:"/de/security/components/tapir/packet_format"},next:{title:"Cwtch",permalink:"/de/security/category/cwtch"}},i={},l=[{value:"Kryptographische Eigenschaften",id:"kryptographische-eigenschaften",level:3}],N={toc:l},o="wrapper";function k(a){let{components:e,...t}=a;return(0,s.kt)(o,(0,m.Z)({},N,t,{components:e,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"authentifizierungsprotokoll"},"Authentifizierungsprotokoll"),(0,s.kt)("p",null,"Jeder Peer erh\xe4lt eine offene Verbindung ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"C")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"C")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"))))),":"),(0,s.kt)("div",{className:"math math-display"},(0,s.kt)("span",{parentName:"div",className:"katex-display"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"p"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"h"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"m"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"r"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"P"),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mo",{parentName:"msub",separator:"true"},","),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mi",{parentName:"msup"},"i")),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msup"},"P"),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow"},(0,s.kt)("mover",{parentName:"mo"},(0,s.kt)("mo",{parentName:"mover"},(0,s.kt)("mo",{parentName:"mo"},"=")),(0,s.kt)("mo",{parentName:"mover",stretchy:"false",lspace:"0em",rspace:"0em"},"?"))),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"L"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"e"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"I = \\mathrm{InitializeIdentity()} \\\\ I_e = \\mathrm{InitializeEphemeralIdentity()} \\\\ I,I_e \\rightarrow C \\\\ P, _e \\leftarrow C \\\\ k = \\mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\\\ c = \\mathrm{E}(k, transkript. ommit()) \\\\ c \\rightarrow C \\\\ c_p \\leftarrow C\\\\ \\mathrm{D}(k, c_p) \\stackrel{?}{=} transcript.LatestCommit()")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeEphemeralIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.958em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P")),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8747em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"E"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"s"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},"))")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7167em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.4391em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"D"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},(0,s.kt)("span",{parentName:"span",className:"mop op-limits"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"1.153em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span"},(0,s.kt)("span",{parentName:"span",className:"mop"},"="))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.5669em",marginLeft:"0em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mclose mtight"},"?"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"L"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"a"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"es"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"tC"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")))))),(0,s.kt)("p",null,"Das obige stellt ein Skizzenprotokoll dar, in Wirklichkeit gibt es ein paar Implementierungsdetails die es zu erw\xe4hnen gilt:"),(0,s.kt)("p",null,"Einmal von der Schl\xfcssel-Ableitungsfunktion (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\mathrm{KDF}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")))))),") abgeleitet, wird der Schl\xfcssel (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"k")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"k")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"))))),") auf ",(0,s.kt)("em",{parentName:"p"},"an")," gesetzt. Dies bedeutet, dass die Authentifizierungs-App die Verschl\xfcsselung oder Entschl\xfcsselung nicht explizit durchf\xfchrt."),(0,s.kt)("p",null,"Die Verkettung von Teilen des 3DH Austauschs ist streng geregelt:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"DH der langfristigen Identit\xe4t der ausgehenden Verbindung durch den fl\xfcchtigen Schl\xfcssel der eingehenden Verbindung."),(0,s.kt)("li",{parentName:"ul"},"DH der langfristigen Identit\xe4t der eingehenden Verbindung durch den fl\xfcchtigen Schl\xfcssel der ausgehenden Verbindung."),(0,s.kt)("li",{parentName:"ul"},"DH der beiden ephemeren Identit\xe4ten der eingehenden und ausgehenden Verbindungen.")),(0,s.kt)("p",null,"Diese strikte Reihenfolge stellt sicher, dass beide Seiten der Verbindung den ",(0,s.kt)("em",{parentName:"p"},"gleichen")," Sitzungsschl\xfcssel ableiten."),(0,s.kt)("h3",{id:"kryptographische-eigenschaften"},"Kryptographische Eigenschaften"),(0,s.kt)("p",null,"W\xe4hrend einer Online-Sitzung k\xf6nnen alle mit dem Sitzungsschl\xfcssel verschl\xfcsselten Nachrichten von den Peers als von ihrem Peers kommend authentifiziert werden (oder zumindest jemand, der \xfcber einen geheimen Schl\xfcssel der Peers verf\xfcgt, da dies mit der Onion Adresse in Verbindung steht)."),(0,s.kt)("p",null,"Sobald die Sitzung beendet ist, ein Transkript mit den langfristigen und kurzlebigen \xf6ffentlichen Schl\xfcsseln, ein abgeleiteter Session-Schl\xfcssel und alle verschl\xfcsselten Nachrichten in der Sitzung k\xf6nnen nicht als authentisch bewiesen werden. dieses Protokoll bietet die Nachricht & Teilnehmer Zur\xfcckweisung (offline verweigerbar) zus\xe4tzlich zur Nachrichtenunverlinkbarkeit (offline verweigerbar) f\xfcr den Fall, dass jemand damit zufrieden ist, dass eine einzelne Nachricht im Transkript von einem Peer stammt, es gibt keine M\xf6glichkeit, eine andere Nachricht mit zu verkn\xfcpfen."),(0,s.kt)("p",null,"Intuition f\xfcr die obigen Ausf\xfchrungen: Das einzige kryptographische Material, das mit dem Transkript zusammenh\xe4ngt, ist der abgeleitete Sitzungsschl\xfcssel - wenn der Sitzungsschl\xfcssel ver\xf6ffentlicht wird, kann er verwendet werden, um neue Nachrichten im Transkript zu schmieden - und als solche unterliegt jede eigenst\xe4ndige Transkription der M\xf6glichkeit einer F\xe4lschung und kann daher nicht verwendet werden, um einen Peer kryptographisch an eine Unterhaltung zu binden."))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6875c492.a3d95c11.js b/build-staging/de/assets/js/6875c492.a3d95c11.js new file mode 100644 index 00000000..3a83b038 --- /dev/null +++ b/build-staging/de/assets/js/6875c492.a3d95c11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8610],{9703:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(5999),r=a(2244);function s(e){const{metadata:t}=e,{previousPage:a,nextPage:s}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,l.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(r.Z,{permalink:a,title:n.createElement(l.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),s&&n.createElement(r.Z,{permalink:s,title:n.createElement(l.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(9460),r=a(390);function s(e){let{items:t,component:a=r.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(l.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}},1714:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var n=a(7294),l=a(6010),r=a(5999),s=a(8824),o=a(1944),i=a(5281),g=a(9960),c=a(9058),m=a(9703),u=a(197),p=a(9985);function d(e){const t=function(){const{selectMessage:e}=(0,s.c)();return t=>e(t,(0,r.I)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,r.I)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function h(e){let{tag:t}=e;const a=d(t);return n.createElement(n.Fragment,null,n.createElement(o.d,{title:a}),n.createElement(u.Z,{tag:"blog_tags_posts"}))}function b(e){let{tag:t,items:a,sidebar:l,listMetadata:s}=e;const o=d(t);return n.createElement(c.Z,{sidebar:l},n.createElement("header",{className:"margin-bottom--xl"},n.createElement("h1",null,o),n.createElement(g.Z,{href:t.allTagsPath},n.createElement(r.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page"},"View All Tags"))),n.createElement(p.Z,{items:a}),n.createElement(m.Z,{metadata:s}))}function E(e){return n.createElement(o.FG,{className:(0,l.Z)(i.k.wrapper.blogPages,i.k.page.blogTagPostListPage)},n.createElement(h,e),n.createElement(b,e))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6937af2a.a156a2a0.js b/build-staging/de/assets/js/6937af2a.a156a2a0.js new file mode 100644 index 00000000..3107d2b0 --- /dev/null +++ b/build-staging/de/assets/js/6937af2a.a156a2a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4814],{3986:e=>{e.exports=JSON.parse('{"label":"cwtch","permalink":"/de/blog/tags/cwtch","allTagsPath":"/de/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/69baf694.b646c8ee.js b/build-staging/de/assets/js/69baf694.b646c8ee.js new file mode 100644 index 00000000..b7243815 --- /dev/null +++ b/build-staging/de/assets/js/69baf694.b646c8ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6204],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=s(n),m=i,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||o;return n?r.createElement(f,a(a({ref:t},u),{},{components:n})):r.createElement(f,a({ref:t},u))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:i,a[1]=p;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>s});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:5},a="Eine Gruppeneinladung annehmen",p={unversionedId:"groups/accept-group-invite",id:"groups/accept-group-invite",title:"Eine Gruppeneinladung annehmen",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/accept-group-invite.md",sourceDirName:"groups",slug:"/groups/accept-group-invite",permalink:"/de/docs/groups/accept-group-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/accept-group-invite.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Einladungen an eine Gruppe senden",permalink:"/de/docs/groups/send-invite"},next:{title:"Wie man eine Gruppe verl\xe4sst?",permalink:"/de/docs/groups/leave-group"}},c={},s=[],u={toc:s},l="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(l,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eine-gruppeneinladung-annehmen"},"Eine Gruppeneinladung annehmen"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Wenn ein Freund dir eine Gruppenanfrage sendet"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle ob du dieser Gruppe beitreten m\xf6chtest oder nicht"),(0,i.kt)("li",{parentName:"ol"},"Die Gruppe ist jetzt in deiner Kontaktliste")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Group_acceptinvite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6a78f460.b626ebee.js b/build-staging/de/assets/js/6a78f460.b626ebee.js new file mode 100644 index 00000000..2d00524d --- /dev/null +++ b/build-staging/de/assets/js/6a78f460.b626ebee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[439],{3905:(t,e,a)=>{a.d(e,{Zo:()=>c,kt:()=>d});var i=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function o(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=i.createContext({}),p=function(t){var e=i.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},c=function(t){var e=p(t.components);return i.createElement(s.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},h=i.forwardRef((function(t,e){var a=t.components,r=t.mdxType,n=t.originalType,s=t.parentName,c=l(t,["components","mdxType","originalType","parentName"]),u=p(a),h=r,d=u["".concat(s,".").concat(h)]||u[h]||f[h]||n;return a?i.createElement(d,o(o({ref:e},c),{},{components:a})):i.createElement(d,o({ref:e},c))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var n=a.length,o=new Array(n);o[0]=h;var l={};for(var s in e)hasOwnProperty.call(e,s)&&(l[s]=e[s]);l.originalType=t,l[u]="string"==typeof t?t:r,o[1]=l;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>o,default:()=>f,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var i=a(7462),r=(a(7294),a(3905));const n={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"6. April 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/de/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/de/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/de/blog/cwtch-stable-roadmap-update"}},s={authorsImageUrls:[void 0]},p=[{value:"Availability Status",id:"availability-status",level:2},{value:"Profile Attributes",id:"profile-attributes",level:2},{value:"Downloading the Nightly",id:"downloading-the-nightly",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},u="wrapper";function f(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,i.Z)({},c,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,r.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,r.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,r.kt)("p",null,"The Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("h2",{id:"availability-status"},"Availability Status"),(0,r.kt)("p",null,'New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".'),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(4940).Z},(0,r.kt)("img",{src:a(1859).Z,width:"442",height:"233"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")),(0,r.kt)("h2",{id:"profile-attributes"},"Profile Attributes"),(0,r.kt)("p",null,"Also new is the ability to augment your profile with a few small pieces of ",(0,r.kt)("strong",{parentName:"p"},"public")," information."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(2243).Z},(0,r.kt)("img",{src:a(3506).Z,width:"730",height:"342"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information")),(0,r.kt)("h2",{id:"downloading-the-nightly"},"Downloading the Nightly"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly builds")," are available from our build server. Download links for ",(0,r.kt)("strong",{parentName:"p"},"2023-04-05-18-28-v1.11.0-7-g0290")," are available below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Windows: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Linux: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Mac: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Android: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"))),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}f.isMDXComponent=!0},2243:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},4940:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3506:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},1859:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6e606510.764571cd.js b/build-staging/de/assets/js/6e606510.764571cd.js new file mode 100644 index 00000000..a6bbc757 --- /dev/null +++ b/build-staging/de/assets/js/6e606510.764571cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[764],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>g});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function i(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var d=r.createContext({}),m=function(t){var e=r.useContext(d),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},p=function(t){var e=m(t.components);return r.createElement(d.Provider,{value:e},t.children)},o="mdxType",s={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},k=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,l=t.originalType,d=t.parentName,p=u(t,["components","mdxType","originalType","parentName"]),o=m(n),k=a,g=o["".concat(d,".").concat(k)]||o[k]||s[k]||l;return n?r.createElement(g,i(i({ref:e},p),{},{components:n})):r.createElement(g,i({ref:e},p))}));function g(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var l=n.length,i=new Array(l);i[0]=k;var u={};for(var d in e)hasOwnProperty.call(e,d)&&(u[d]=e[d]);u.originalType=t,u[o]="string"==typeof t?t:a,i[1]=u;for(var m=2;m{n.r(e),n.d(e,{assets:()=>d,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>u,toc:()=>m});var r=n(7462),a=(n(7294),n(3905));const l={},i="Unterst\xfctzte Platformen",u={unversionedId:"getting-started/supported_platforms",id:"getting-started/supported_platforms",title:"Unterst\xfctzte Platformen",description:"Die folgende Tabelle stellt unser aktuelles Verst\xe4ndnis von Cwtch-Unterst\xfctzung auf verschiedenen Betriebssystemen und Architekturen dar (Stand Cwtch 1.10 und Januar 2023).",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/getting-started/supported_platforms.md",sourceDirName:"getting-started",slug:"/getting-started/supported_platforms",permalink:"/de/docs/getting-started/supported_platforms",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/getting-started/supported_platforms.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/de/docs/category/getting-started"},next:{title:"Profiles",permalink:"/de/docs/category/profiles"}},d={},m=[],p={toc:m},o="wrapper";function s(t){let{components:e,...n}=t;return(0,a.kt)(o,(0,r.Z)({},p,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"unterst\xfctzte-platformen"},"Unterst\xfctzte Platformen"),(0,a.kt)("p",null,"Die folgende Tabelle stellt unser aktuelles Verst\xe4ndnis von Cwtch-Unterst\xfctzung auf verschiedenen Betriebssystemen und Architekturen dar (Stand Cwtch 1.10 und Januar 2023)."),(0,a.kt)("p",null,"In vielen F\xe4llen suchen wir nach Testern, die best\xe4tigen, dass verschiedene Funktionen funktionieren. Wenn du daran interessiert bist, Cwtch auf einer bestimmten Plattform zu testen oder als freiwilliger Helfer bei der offiziellen Unterst\xfctzung einer hier nicht aufgelisteten Plattform helfen m\xf6chtest, dann schaue dir ",(0,a.kt)("a",{parentName:"p",href:"/docs/category/contribute"},"Beitragen zu Cwtch")," an."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Legende:")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\u2705: ",(0,a.kt)("strong",{parentName:"li"},"Offiziell unterst\xfctzt"),". Cwtch sollte auf diesen Plattformen ohne Probleme funktionieren. Regressionen werden als hohe Priorit\xe4t behandelt."),(0,a.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,a.kt)("strong",{parentName:"li"},"Beste Anstrengung zur Unterst\xfctzung"),". Cwtch sollte auf diesen Plattformen funktionieren, aber es kann dokumentierte oder unbekannte Probleme geben. Es kann notwendig sein, Tests durchzuf\xfchren. Einige Funktionen erfordern m\xf6glicherweise zus\xe4tzliche Arbeit. Freiwilligenarbeit wird gew\xfcrdigt."),(0,a.kt)("li",{parentName:"ul"},"\u274c: ",(0,a.kt)("strong",{parentName:"li"},"Nicht unterst\xfctzt"),". Cwtch wird wahrscheinlich nicht auf diesen Systemen funktionieren. Wir werden vermutlich keine Fehlerberichte f\xfcr diese Systeme akzeptieren.")),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Plattform"),(0,a.kt)("th",{parentName:"tr",align:null},"Offizielle Cwtch Builds"),(0,a.kt)("th",{parentName:"tr",align:null},"Quellencode-Unterst\xfctzung"),(0,a.kt)("th",{parentName:"tr",align:null},"Anmerkungen"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit amd64.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit amd64. Nicht offiziell unterst\xfctzt, aber offizielle Builds k\xf6nnten funktionieren.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Windows 8 und darunter"),(0,a.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Nicht unterst\xfctzt. Dedizierte Builds aus dem Quellcode k\xf6nnten funktionieren. Testen erforderlich.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"OSX 10 und darunter"),(0,a.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit. Offizielle Builds sollen auf Catalina funktionieren, aber nicht auf High Sierra")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit. Offizielle Builds unterst\xfctzen sowohl arm64 als auch x86 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit. Offizielle Builds unterst\xfctzen sowohl arm64 als auch x86 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit. Offizielle Builds unterst\xfctzen sowohl arm64 als auch x86 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit amd64.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit amd64.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Debian 9 und darunter"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit amd64. Builds aus dem Quellcode sollten funktionieren, aber offizielle Builds k\xf6nnten mit installierten Abh\xe4ngigkeiten inkompatibel sein.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit amd64.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Andere Ubuntu"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Nur 64-Bit. Testen erforderlich. Builds aus dem Quellcode sollten funktionieren, aber offizielle Builds k\xf6nnten mit installierten Abh\xe4ngigkeiten inkompatibel sein.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Testen erforderlich.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Testen erforderlich.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Arch"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Testen erforderlich.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},(0,a.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Bekannte Probleme. F\xfcr die Unterst\xfctzung sind spezielle \xc4nderungen an Cwtch erforderlich. "))),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Builds aus dem Quellcode erstellt, funktionieren.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Andere Linux-Distributionen"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Testen erforderlich.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Android 9 und darunter"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Offizielle Builds k\xf6nnten funktionieren.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Offizielle SDK unterst\xfctzen arm, arm64 und amd64 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Offizielle SDK unterst\xfctzen arm, arm64 und amd64 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Offizielle SDK unterst\xfctzen arm, arm64 und amd64 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Offizielle SDK unterst\xfctzen arm, arm64 und amd64 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,a.kt)("td",{parentName:"tr",align:null},"Offizielle SDK unterst\xfctzen arm, arm64 und amd64 Architekturen.")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Andere Android Distributionen"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,a.kt)("td",{parentName:"tr",align:null},"Testen erforderlich.")))))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6e61466c.7c750783.js b/build-staging/de/assets/js/6e61466c.7c750783.js new file mode 100644 index 00000000..ea1d7b45 --- /dev/null +++ b/build-staging/de/assets/js/6e61466c.7c750783.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1756],{658:e=>{e.exports=JSON.parse('{"title":"Verhalten","slug":"/category/behaviour","permalink":"/de/docs/category/behaviour","navigation":{"previous":{"title":"Streamer/Pr\xe4sentationsmodus","permalink":"/de/docs/settings/appearance/streamer-mode"},"next":{"title":"Unbekannte Verbindungen blockieren","permalink":"/de/docs/settings/behaviour/block-unknown-connections"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/6f232d8e.57c8d8fd.js b/build-staging/de/assets/js/6f232d8e.57c8d8fd.js new file mode 100644 index 00000000..5d10e92d --- /dev/null +++ b/build-staging/de/assets/js/6f232d8e.57c8d8fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2738],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>m});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var o=r.createContext({}),u=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},c=function(e){var n=u(e.components);return r.createElement(o.Provider,{value:n},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,o=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(t),p=i,m=d["".concat(o,".").concat(p)]||d[p]||h[p]||a;return t?r.createElement(m,l(l({ref:n},c),{},{components:t})):r.createElement(m,l({ref:n},c))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,l=new Array(a);l[0]=p;var s={};for(var o in n)hasOwnProperty.call(n,o)&&(s[o]=n[o]);s.originalType=e,s[d]="string"==typeof e?e:i,l[1]=s;for(var u=2;u{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const a={},l="Nachrichten Overlays",s={unversionedId:"components/ui/overlays",id:"components/ui/overlays",title:"Nachrichten Overlays",description:"Angepasst von Anmerkungen zur Cwtch Chat API",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/overlays.md",sourceDirName:"components/ui",slug:"/components/ui/overlays",permalink:"/de/security/components/ui/overlays",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Eingabe",permalink:"/de/security/components/ui/input"},next:{title:"Ver\xf6ffentlichung",permalink:"/de/security/deployment"}},o={},u=[{value:"Chat-Overlays, Listen und Bulletins",id:"chat-overlays-listen-und-bulletins",level:2},{value:"Datenstruktur",id:"datenstruktur",level:2},{value:"Chat-Nachrichten (Overlay 1)",id:"chat-nachrichten-overlay-1",level:2},{value:"Einladungen (Overlays 100 und 101)",id:"einladungen-overlays-100-und-101",level:2},{value:"Listen / Bulletin Boards",id:"listen--bulletin-boards",level:2}],c={toc:u},d="wrapper";function h(e){let{components:n,...t}=e;return(0,i.kt)(d,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"nachrichten-overlays"},"Nachrichten Overlays"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/08-chatapi/"},"Angepasst von: Discreet Log #8: Anmerkungen zur Cwtch Chat API")),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Hinweis: Dieser Abschnitt behandelt Overlay-Protokolle, die auf das Cwtch-Protokoll aufsetzen. F\xfcr Informationen \xfcber das Cwtch-Protokoll Nachrichten selbst schaue unter ",(0,i.kt)("a",{parentName:"strong",href:"/de/security/components/cwtch/message_formats"},"Nachrichtenformate"))),(0,i.kt)("p",null,"Wir sehen Cwtch als eine Plattform f\xfcr die Bereitstellung einer authentifizierten Transportschicht f\xfcr Anwendungen auf h\xf6herer Ebene. Es steht den Entwicklern frei, selbst zu entscheiden, welche Protokolle der Anwendungsschicht sie verwenden wollen, ob sie ma\xdfgeschneiderte bin\xe4re Nachrichtenformate w\xfcnschen oder einfach nur eine HTTP-Bibliothek aufsetzen und die Sache abhaken wollen. Cwtch kann neue Schl\xfcsselpaare f\xfcr Sie generieren (die zu Onion-Adressen werden; es sind keine DNS-Registrierungen erforderlich!) und du kannst mit REST sicher sein, dass alle Daten, die deine Anwendung vom (anonymen Kommunikations-) Netz empf\xe4ngt, bereits authentifiziert wurden."),(0,i.kt)("p",null,"In unserem aktuellen Stack sind die Nachrichten in einen minimalen JSON-Rahmen verpackt, der einige kontextbezogene Informationen \xfcber den Nachrichtentyp hinzuf\xfcgt. Und da es sich bei serialisierten JSON-Objekten nur um W\xf6rterb\xfccher handelt, k\xf6nnen wir sp\xe4ter bei Bedarf problemlos weitere Metadaten hinzuf\xfcgen."),(0,i.kt)("h2",{id:"chat-overlays-listen-und-bulletins"},"Chat-Overlays, Listen und Bulletins"),(0,i.kt)("p",null,'Das urspr\xfcngliche Cwtch alpha zeigte "Overlays": verschiedene Arten, denselben Datenkanal zu interpretieren, abh\xe4ngig von der Struktur der atomaren Daten selbst. Wir haben einfache Checklisten und BBS/Klassifizierungsanzeigen als Overlays eingef\xfcgt, die mit jedem Cwtch-Kontakt angeschaut und geteilt werden konnten, sei es mit einem einzelnen Peer oder einer Gruppe. Das \xdcbertragungsformat sah wie folgt aus:'),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'{o:1,d:"hey there!"}\n{o:2,d:"bread",l:"groceries"}\n{o:3,d:"garage sale",p:"[parent message signature]"}\n')),(0,i.kt)("p",null,"Overlay-Feld ",(0,i.kt)("inlineCode",{parentName:"p"},"o")," bestimmt, ob es ein Chat (1), Liste (2), oder Bulletin (3) Nachricht war. Das Datenfeld ",(0,i.kt)("inlineCode",{parentName:"p"},"d")," ist \xfcberladen und Listen/Bulletins ben\xf6tigen zus\xe4tzliche Informationen dar\xfcber, welcher Gruppe/Beitrag sie angeh\xf6ren. (Wir verwenden Nachrichtensignaturen anstelle von IDs, um Probleme wie Ordnungsprobleme und b\xf6swillig erstellte IDs zu vermeiden. Auf diese Weise teilt auch das Cwtch-Protokoll dem Frontend mit, welche Nachricht abgeholt wird)"),(0,i.kt)("h2",{id:"datenstruktur"},"Datenstruktur"),(0,i.kt)("p",null,"Die Implementierung von baumstrukturierten Daten auf einem sequentiellen Nachrichtenspeicher hat offensichtliche Leistungsnachteile. Betrachte z. B. die Nachrichtenansicht, die die neuesten Nachrichten zuerst l\xe4dt und nur so weit zur\xfcckgeht, dass sie das aktuelle Ansichtsfenster ausf\xfcllt, im Vergleich zu einem (etwas pathologischen) Forum, in dem fast jede Nachricht ein Kind der allerersten Nachricht in der Historie ist, die Gigabytes an Daten enthalten kann. Wenn die Benutzeroberfl\xe4che nur Beitr\xe4ge der obersten Ebene anzeigt, bis der Benutzer sie erweitert, m\xfcssen wir den gesamten Verlauf analysieren, bevor wir gen\xfcgend Informationen erhalten, um \xfcberhaupt etwas anzuzeigen."),(0,i.kt)("p",null,'Ein weiteres Problem besteht darin, dass das Multiplexen all dieser \xdcberlagerungen in einem Datenspeicher "L\xf6cher" in den Daten erzeugt, die ',(0,i.kt)("a",{parentName:"p",href:"https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html"},"lazy-loaded listviews")," und Scrollbars verwirren. Die Anzahl der Nachrichten kann darauf hinweisen, dass es eine Menge weiterer Informationen gibt, die angezeigt werden k\xf6nnen, wenn der Benutzer einfach scrollt, aber wenn sie tats\xe4chlich abgerufen und geparst werden, k\xf6nnten wir feststellen, dass nichts davon f\xfcr das aktuelle Overlay relevant ist."),(0,i.kt)("p",null,"Keines dieser Probleme ist un\xfcberwindbar, aber sie zeigen einen Fehler in unseren urspr\xfcnglichen Annahmen \xfcber die Art des kollaborativen Nachrichtenflusses und die Art und Weise, wie wir mit diesen Daten umgehen sollten."),(0,i.kt)("h1",{id:"overlay-typen"},"Overlay Typen"),(0,i.kt)("p",null,"Wie oben erw\xe4hnt, werden Overlays in einem sehr einfachen JSON-Format mit der folgenden Struktur angegeben:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'type ChatMessage struct {\n O int `json:"o"`\n D string `json:"d"`\n}\n')),(0,i.kt)("p",null,"Wo O f\xfcr ",(0,i.kt)("inlineCode",{parentName:"p"},"Overlay")," mit den unten dokumentierten unterst\xfctzten Overlays steht:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"1: data is a chat string\n2: data is a list state/delta\n3: data is a bulletin state/delta\n100: contact suggestion; data is a peer onion address\n101: contact suggestion; data is a group invite string\n")),(0,i.kt)("h2",{id:"chat-nachrichten-overlay-1"},"Chat-Nachrichten (Overlay 1)"),(0,i.kt)("p",null,"Die einfachste Variante ist eine Chat-Nachricht, die einfach nur rohe, unverarbeitete Informationen \xfcber die Chat-Nachricht enth\xe4lt."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'{o:1,d:"got milk?"}\n')),(0,i.kt)("h2",{id:"einladungen-overlays-100-und-101"},"Einladungen (Overlays 100 und 101)"),(0,i.kt)("p",null,"Anstatt die Einladung als eingehende Kontaktanfrage auf Profilebene zu erhalten, werden neue Inline-Einladungen mit einem bestimmten Kontakt/einer bestimmten Gruppe geteilt, wo sie sp\xe4ter eingesehen und/oder angenommen werden k\xf6nnen, auch wenn sie zun\xe4chst (m\xf6glicherweise versehentlich) abgelehnt wurden."),(0,i.kt)("p",null,"Das Format ist f\xfcr diese gleicherma\xdfen einfach:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}\n{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}\n')),(0,i.kt)("p",null,'Dies stellt eine Abkehr von unserem urspr\xfcnglichen "Overlays"-Denken hin zu einer st\xe4rker handlungsorientierten Darstellung dar. Das Chat-"Overlay" kann mitteilen, dass jemand etwas ',(0,i.kt)("em",{parentName:"p"},"getan"),' hat, selbst wenn es auf "ein Element zu einer Liste hinzugef\xfcgt" umschrieben wird, und die Listen und Bulletins und andere sch\xf6n chaotische Daten k\xf6nnen ihren Zustand vorberechnet und separat gespeichert haben.'),(0,i.kt)("h2",{id:"listen--bulletin-boards"},"Listen / Bulletin Boards"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Hinweis: Wird voraussichtlich in Cwtch Beta 1.5 definiert werden")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/708a1ab9.3254a360.js b/build-staging/de/assets/js/708a1ab9.3254a360.js new file mode 100644 index 00000000..792edd3a --- /dev/null +++ b/build-staging/de/assets/js/708a1ab9.3254a360.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1020],{2771:e=>{e.exports=JSON.parse('{"title":"Verbindung & Tor","slug":"/category/connectivity--tor","permalink":"/de/security/category/connectivity--tor","navigation":{"previous":{"title":"Komponenten Ecosystem \xdcbersicht","permalink":"/de/security/components/ecosystem-overview"},"next":{"title":"Verbindung","permalink":"/de/security/components/connectivity/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/72a13759.4d747520.js b/build-staging/de/assets/js/72a13759.4d747520.js new file mode 100644 index 00000000..85254cf6 --- /dev/null +++ b/build-staging/de/assets/js/72a13759.4d747520.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3642],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},f="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),f=l(n),d=a,g=f["".concat(c,".").concat(d)]||f[d]||p[d]||i;return n?r.createElement(g,s(s({ref:t},u),{},{components:n})):r.createElement(g,s({ref:t},u))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,s=new Array(i);s[0]=d;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[f]="string"==typeof e?e:a,s[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={sidebar_position:5},s="Konversationseinstellungen aufrufen",o={unversionedId:"chat/conversation-settings",id:"chat/conversation-settings",title:"Konversationseinstellungen aufrufen",description:"Klicke in einem Konversationsfenster auf das Einstellungssymbol in der oberen Leiste.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/conversation-settings.md",sourceDirName:"chat",slug:"/chat/conversation-settings",permalink:"/de/docs/chat/conversation-settings",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/conversation-settings.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Nachrichtenformatierung",permalink:"/de/docs/chat/message-formatting"},next:{title:"Auf eine Nachricht antworten",permalink:"/de/docs/chat/reply-to-message"}},c={},l=[],u={toc:l},f="wrapper";function p(e){let{components:t,...i}=e;return(0,a.kt)(f,(0,r.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"konversationseinstellungen-aufrufen"},"Konversationseinstellungen aufrufen"),(0,a.kt)("p",null,"Klicke in einem Konversationsfenster auf das Einstellungssymbol in der oberen Leiste."),(0,a.kt)("figure",null,(0,a.kt)("p",null,(0,a.kt)("a",{target:"_blank",href:n(671).Z},(0,a.kt)("img",{src:n(6305).Z,width:"624",height:"257"}))),(0,a.kt)("figcaption",null)),(0,a.kt)("p",null,"Diese Aktion \xf6ffnet einen neuen Bildschirm, auf dem du den Kontakt ansehen und verwalten kannst."),(0,a.kt)("figure",null,(0,a.kt)("p",null,(0,a.kt)("a",{target:"_blank",href:n(4306).Z},(0,a.kt)("img",{src:n(2289).Z,width:"937",height:"689"}))),(0,a.kt)("figcaption",null)))}p.isMDXComponent=!0},4306:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png"},671:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png"},2289:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png"},6305:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/746f1580.72b2827d.js b/build-staging/de/assets/js/746f1580.72b2827d.js new file mode 100644 index 00000000..27196acc --- /dev/null +++ b/build-staging/de/assets/js/746f1580.72b2827d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9508],{2849:t=>{t.exports=JSON.parse('{"title":"Erste Schritte","slug":"/category/getting-started","permalink":"/de/docs/category/getting-started","navigation":{"previous":{"title":"Was ist Cwtch?","permalink":"/de/docs/intro"},"next":{"title":"Unterst\xfctzte Platformen","permalink":"/de/docs/getting-started/supported_platforms"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/75bff082.f91bcae3.js b/build-staging/de/assets/js/75bff082.f91bcae3.js new file mode 100644 index 00000000..2ec7b6db --- /dev/null +++ b/build-staging/de/assets/js/75bff082.f91bcae3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1132],{5670:e=>{e.exports=JSON.parse('{"title":"Server","slug":"/category/servers","permalink":"/de/docs/category/servers","navigation":{"previous":{"title":"Server verwalten","permalink":"/de/docs/groups/manage-known-servers"},"next":{"title":"Server Einf\xfchrung","permalink":"/de/docs/servers/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/773ceef9.a5e9fd7a.js b/build-staging/de/assets/js/773ceef9.a5e9fd7a.js new file mode 100644 index 00000000..5a31951e --- /dev/null +++ b/build-staging/de/assets/js/773ceef9.a5e9fd7a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[337],{8362:e=>{e.exports=JSON.parse('{"label":"release","permalink":"/de/blog/tags/release","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/7747f3f6.0738ad71.js b/build-staging/de/assets/js/7747f3f6.0738ad71.js new file mode 100644 index 00000000..0de33df5 --- /dev/null +++ b/build-staging/de/assets/js/7747f3f6.0738ad71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5117],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=o,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||a;return n?r.createElement(f,c(c({ref:t},p),{},{components:n})):r.createElement(f,c({ref:t},p))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[u]="string"==typeof e?e:o,c[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:8},c="Einen Kontakt entsperren",i={unversionedId:"chat/unblock-contact",id:"chat/unblock-contact",title:"Einen Kontakt entsperren",description:"1. W\xe4hle den Kontakt in Ihrer Konversationsliste aus. Gesperrte Kontakte werden an das Ende der Liste verschoben.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/unblock-contact.md",sourceDirName:"chat",slug:"/chat/unblock-contact",permalink:"/de/docs/chat/unblock-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/unblock-contact.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"Einen Kontakt blockieren",permalink:"/de/docs/chat/block-contact"},next:{title:"Entfernen einer Konversation",permalink:"/de/docs/chat/delete-contact"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"einen-kontakt-entsperren"},"Einen Kontakt entsperren"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"W\xe4hle den Kontakt in Ihrer Konversationsliste aus. Gesperrte Kontakte werden an das Ende der Liste verschoben."),(0,o.kt)("li",{parentName:"ol"},"Gehe zu den Konversationseinstellungen"),(0,o.kt)("li",{parentName:"ol"},"Scrolle nach unten zum Kontakt sperren"),(0,o.kt)("li",{parentName:"ol"},"Verschiebe den Schalter auf Kontakt entsperren")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/78625d6f.bf004fbb.js b/build-staging/de/assets/js/78625d6f.bf004fbb.js new file mode 100644 index 00000000..17519467 --- /dev/null +++ b/build-staging/de/assets/js/78625d6f.bf004fbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3952],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),l=p(r),m=a,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[l]="string"==typeof e?e:a,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:4},i="Streamer/Pr\xe4sentationsmodus",s={unversionedId:"settings/appearance/streamer-mode",id:"settings/appearance/streamer-mode",title:"Streamer/Pr\xe4sentationsmodus",description:"Streamer/Pr\xe4sentationsmodus macht die App optisch privater. In diesem Modus wird Cwtch keine Hilfsinformationen wie Cwtch-Adressen und andere sensible Informationen auf den Hauptbildschirmen anzeigen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/streamer-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/streamer-mode",permalink:"/de/docs/settings/appearance/streamer-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/streamer-mode.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"UI Spalten",permalink:"/de/docs/settings/appearance/ui-columns"},next:{title:"Behaviour",permalink:"/de/docs/category/behaviour"}},c={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"streamerpr\xe4sentationsmodus"},"Streamer/Pr\xe4sentationsmodus"),(0,a.kt)("p",null,"Streamer/Pr\xe4sentationsmodus macht die App optisch privater. In diesem Modus wird Cwtch keine Hilfsinformationen wie Cwtch-Adressen und andere sensible Informationen auf den Hauptbildschirmen anzeigen."),(0,a.kt)("p",null,"Dies ist n\xfctzlich, wenn Du Screenshots machst oder Cwtch auf andere Art und Weise \xf6ffentlich anzeigst."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Dr\xfccke das Einstellungssymbol"),(0,a.kt)("li",{parentName:"ol"},'"Streamer-Modus" auf "An"'),(0,a.kt)("li",{parentName:"ol"},"\xdcberpr\xfcfe, ob es funktioniert, indem Du Dein Profil oder Deine Kontaktliste ansiehst")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/787066a3.5dbcebe2.js b/build-staging/de/assets/js/787066a3.5dbcebe2.js new file mode 100644 index 00000000..bef02955 --- /dev/null +++ b/build-staging/de/assets/js/787066a3.5dbcebe2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8357],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>h});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var a=r.createContext({}),c=function(e){var n=r.useContext(a),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},u=function(e){var n=c(e.components);return r.createElement(a.Provider,{value:n},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,s=e.originalType,a=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=c(t),d=i,h=p["".concat(a,".").concat(d)]||p[d]||f[d]||s;return t?r.createElement(h,o(o({ref:n},u),{},{components:t})):r.createElement(h,o({ref:n},u))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=t.length,o=new Array(s);o[0]=d;var l={};for(var a in n)hasOwnProperty.call(n,a)&&(l[a]=n[a]);l.originalType=e,l[p]="string"==typeof e?e:i,o[1]=l;for(var c=2;c{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var r=t(7462),i=(t(7294),t(3905));const s={sidebar_position:1.5},o="Ein neues Profil erstellen",l={unversionedId:"profiles/create-a-profile",id:"profiles/create-a-profile",title:"Ein neues Profil erstellen",description:'1. Dr\xfccke die + Aktionstaste in der rechten unteren Ecke und w\xe4hle "Neues Profil"',source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/create-a-profile.md",sourceDirName:"profiles",slug:"/profiles/create-a-profile",permalink:"/de/docs/profiles/create-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/create-a-profile.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Eine Einf\xfchrung in die Cwtch Profile",permalink:"/de/docs/profiles/introduction"},next:{title:"\xc4ndern Deines Anzeigenamens",permalink:"/de/docs/profiles/change-name"}},a={},c=[{value:"Eine Anmerkung zu passwortgesch\xfctzten (verschl\xfcsselten) Profilen",id:"eine-anmerkung-zu-passwortgesch\xfctzten-verschl\xfcsselten-profilen",level:2}],u={toc:c},p="wrapper";function f(e){let{components:n,...t}=e;return(0,i.kt)(p,(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ein-neues-profil-erstellen"},"Ein neues Profil erstellen"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke die ",(0,i.kt)("inlineCode",{parentName:"li"},"+"),' Aktionstaste in der rechten unteren Ecke und w\xe4hle "Neues Profil"'),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle einen Anzeigenamen"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle dies aus, wenn Du dieses Profil lokal mit starker Verschl\xfcsselung sch\xfctzen m\xf6chtest:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Passwort: Dein Konto ist vor anderen Personen gesch\xfctzt, die dieses Ger\xe4t evtl. verwenden k\xf6nnen"),(0,i.kt)("li",{parentName:"ul"},"Kein Passwort: Jeder, der Zugriff auf dieses Ger\xe4t hat, kann auf dieses Profil zugreifen"))),(0,i.kt)("li",{parentName:"ol"},"Gib dein Passwort ein und gib es erneut ein"),(0,i.kt)("li",{parentName:"ol"},"Neues Profil hinzuf\xfcgen anklicken")),(0,i.kt)("h2",{id:"eine-anmerkung-zu-passwortgesch\xfctzten-verschl\xfcsselten-profilen"},"Eine Anmerkung zu passwortgesch\xfctzten (verschl\xfcsselten) Profilen"),(0,i.kt)("p",null,"Die Profile werden lokal auf der Festplatte gespeichert und mittels eines Schl\xfcssels verschl\xfcsselt, der von einem Benutzer bekannten Passwort abgeleitet wird (via pbkdf2)."),(0,i.kt)("p",null,"Beachte, dass einmal verschl\xfcsselt und auf der Festplatte gespeichert die einzige M\xf6glichkeit, ein Profil wiederherzustellen, ist das erneute Ableiten des Schl\xfcssels aus dem Passwort - so ist es nicht m\xf6glich, eine vollst\xe4ndige Liste der Profile anzugeben, auf die ein Benutzer Zugriff haben k\xf6nnte, bis er ein Passwort eingegeben hat."),(0,i.kt)("p",null,"Siehe auch: ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Cwtch Sicherheits-Handbuch: Profil Verschl\xfcsselung & Speicher")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/78e4de8f.24d34fb4.js b/build-staging/de/assets/js/78e4de8f.24d34fb4.js new file mode 100644 index 00000000..b0b53a87 --- /dev/null +++ b/build-staging/de/assets/js/78e4de8f.24d34fb4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4481],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),d=i,h=u["".concat(s,".").concat(d)]||u[d]||m[d]||a;return r?n.createElement(h,o(o({ref:t},p),{},{components:r})):n.createElement(h,o({ref:t},p))}));function h(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:i,o[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const a={sidebar_position:4.5},o="Nachrichtenformatierung",c={unversionedId:"chat/message-formatting",id:"chat/message-formatting",title:"Nachrichtenformatierung",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Nachrichten Formatierung Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/message-formatting.md",sourceDirName:"chat",slug:"/chat/message-formatting",permalink:"/de/docs/chat/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/message-formatting.md",tags:[],version:"current",sidebarPosition:4.5,frontMatter:{sidebar_position:4.5},sidebar:"tutorialSidebar",previous:{title:"Gespr\xe4chsverlauf speichern",permalink:"/de/docs/chat/save-conversation-history"},next:{title:"Konversationseinstellungen aufrufen",permalink:"/de/docs/chat/conversation-settings"}},s={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"nachrichtenformatierung"},"Nachrichtenformatierung"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/message-formatting"},"Nachrichten Formatierung Experiment")," eingeschaltet ist."),(0,i.kt)("p",{parentName:"admonition"},"Optional kannst du ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/clickable-links"},"Klickbare Links")," aktivieren, um URLs in Nachrichten in Cwtch anklickbar zu machen.")),(0,i.kt)("p",null,"Cwtch unterst\xfctzt zur Zeit folgende Formatierungsmarkierungen f\xfcr Nachrichten:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"**bold**")," welches ",(0,i.kt)("strong",{parentName:"li"},"fett")," rendern wird"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"*italic*")," welches ",(0,i.kt)("em",{parentName:"li"},"kursiv")," rendern wird"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"code")," welches ",(0,i.kt)("inlineCode",{parentName:"li"},"code")," rendern wird"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"^superscript^")," das ",(0,i.kt)("sup",null,"superscript")," rendern wird"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"_subscript_")," welches ",(0,i.kt)("sub",null,"subscript")," rendern wird"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"~~strikthrough~~")," welches ",(0,i.kt)("del",null,"strikethrough")," rendern wird")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/7a34d4a9.084018de.js b/build-staging/de/assets/js/7a34d4a9.084018de.js new file mode 100644 index 00000000..787316e0 --- /dev/null +++ b/build-staging/de/assets/js/7a34d4a9.084018de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5508],{3783:e=>{e.exports=JSON.parse('{"label":"reproducible-builds","permalink":"/de/blog/tags/reproducible-builds","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/7bea1ff1.0cd85505.js b/build-staging/de/assets/js/7bea1ff1.0cd85505.js new file mode 100644 index 00000000..fdf06a61 --- /dev/null +++ b/build-staging/de/assets/js/7bea1ff1.0cd85505.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[362],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>h});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var o=r.createContext({}),u=function(e){var t=r.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(o.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,o=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=u(n),m=i,h=d["".concat(o,".").concat(m)]||d[m]||p[m]||a;return n?r.createElement(h,s(s({ref:t},c),{},{components:n})):r.createElement(h,s({ref:t},c))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,s=new Array(a);s[0]=m;var l={};for(var o in t)hasOwnProperty.call(t,o)&&(l[o]=t[o]);l.originalType=e,l[d]="string"==typeof e?e:i,s[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:1},s="Entwicklung von Cwtch",l={unversionedId:"contribute/developing",id:"contribute/developing",title:"Entwicklung von Cwtch",description:"Dieser Abschnitt dokumentiert einige M\xf6glichkeiten, um mit der Cwtch-Entwicklung zu beginnen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/developing.md",sourceDirName:"contribute",slug:"/contribute/developing",permalink:"/de/docs/contribute/developing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/developing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Contribute",permalink:"/de/docs/category/contribute"},next:{title:"Cwtch testen",permalink:"/de/docs/contribute/testing"}},o={},u=[{value:"Cwtch-Fehlerverfolgungsprozess",id:"cwtch-fehlerverfolgungsprozess",level:2},{value:"Cwtch Pull-Request Prozess",id:"cwtch-pull-request-prozess",level:2},{value:"Bot bauen",id:"bot-bauen",level:3},{value:"N\xfctzliche Ressourcen",id:"n\xfctzliche-ressourcen",level:2}],c={toc:u},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"entwicklung-von-cwtch"},"Entwicklung von Cwtch"),(0,i.kt)("p",null,"Dieser Abschnitt dokumentiert einige M\xf6glichkeiten, um mit der Cwtch-Entwicklung zu beginnen."),(0,i.kt)("h2",{id:"cwtch-fehlerverfolgungsprozess"},"Cwtch-Fehlerverfolgungsprozess"),(0,i.kt)("p",null,"Alle Cwtch-Probleme werden aus dem ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"cwtch-ui git Repository"),"verfolgt, auch wenn der Fehler / das Feature in einer Upstream-Bibliothek entsteht. Dies erlaubt uns, alles an einem Ort zu halten."),(0,i.kt)("p",null,"Probleme sind in 4 verschiedene Kategorien unterteilt:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Unbearbeitete")," - Dies sind neue Probleme, die vom Cwtch Team nicht diskutiert wurden."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=195&milestone=0&assignee=0&poster=0"},(0,i.kt)("strong",{parentName:"a"},"Geplant"))," - Diese Probleme wurden f\xfcr eine kommende Ver\xf6ffentlichung eingeplant. Normalerweise werden sie mit der Release Version getaggt, in der sie voraussichtlich in ",(0,i.kt)("inlineCode",{parentName:"li"},"cwtch-1.11")," behoben werden. Ein Kern-Cwtch-Team-Mitglied arbeitet wahrscheinlich an diesem Problem oder wird in den n\xe4chsten Wochen an diesem Thema arbeiten."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=153&milestone=0&assignee=0&poster=0"},(0,i.kt)("strong",{parentName:"a"},"Gew\xfcnscht"))," - Dies sind Probleme, die wir gerne beheben w\xfcrden, aber aus irgendeinem Grund k\xf6nnen wir diese nicht planen. Dies k\xf6nnte daran liegen, dass die Funktion gro\xdf ist und viel Aufwand erfordert, oder weil es einen Blocker gibt (z.B. Eine fehlende Funktion in Flutter oder einer anderen Bibliothek), die die Arbeit an der Funktion verhindert."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=136&milestone=0&assignee=0&poster=0"},(0,i.kt)("strong",{parentName:"a"},"Hilfe gesucht"))," - Dies sind in der Regel kleine Probleme, die wir gerne beheben w\xfcrden, die aber als geringe Priorit\xe4t eingestuft wurden. Dies sind ideale erste Probleme f\xfcr Freiwillige.")),(0,i.kt)("p",null,'Wenn du an einem offenen Fehler/Feature arbeiten m\xf6chtest, bitte kommentiere das Problem und ein Mitglied des Cwtch Teams wird dir Ratschl\xe4ge geben, wohin du von dort gehen solltest. Dies hilft uns, den \xdcberblick zu behalten, wer an welchen Problemen arbeitet, und reduziert den Umfang der doppelten Arbeit. Wir sind bestrebt, die meisten Anfragen innerhalb von 24 Stunden zu beantworten, f\xfchle dich frei, an ein Problem zu "erinnern", wenn es l\xe4nger als diese Zeit dauert.'),(0,i.kt)("admonition",{title:"Hinweis",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Aufgrund eines Problems mit unserem E-Mail-Provider sind wir derzeit nicht in der Lage, E-Mails von unserer gitea-Instanz zu versenden. Bitte \xfcberpr\xfcfe regelm\xe4\xdfig offene Probleme / Pull-Requests auf Updates (oder abonniere die RSS-Feeds des Projektarchivs)")),(0,i.kt)("h2",{id:"cwtch-pull-request-prozess"},"Cwtch Pull-Request Prozess"),(0,i.kt)("p",null,"Alle Pull-Requests m\xfcssen von einem Kernmitglied des Cwtch Teams \xfcberpr\xfcft und genehmigt werden, bevor das Zusammenf\xfchren erfolgt. Sarah pr\xfcft alle neuen und aktiven Pull-Anfragen mehrmals in der Woche."),(0,i.kt)("h3",{id:"bot-bauen"},"Bot bauen"),(0,i.kt)("p",null,"Alle Cwtch Projekte werden mit automatisierten Builds und Tests eingerichtet. Es wird erwartet, dass jeder Pull-Request diese Pipelines durchlaufen kann, bevor er zusammengef\xfchrt wird. Wenn buildbot einen Fehler meldet, dann wird Sarah mit dir zusammenarbeiten, um das Problem und alle notwendigen Korrekturen zu ermitteln."),(0,i.kt)("p",null,"Der Buildbot kann aus Gr\xfcnden, die au\xdferhalb deiner Kontrolle liegen, fehlschlagen, z.B. viele unserer Integrationstests sind auf das Einrichten von Tor-Verbindungen angewiesen, diese k\xf6nnen gelegentlich spr\xf6de sein und zu Timeouts und Fehlern f\xfchren. Best\xe4tige immer die Hauptursache f\xfcr einen Testfehler, bevor du entscheidest, was als n\xe4chstes zu tun ist."),(0,i.kt)("h2",{id:"n\xfctzliche-ressourcen"},"N\xfctzliche Ressourcen"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/security/components/ecosystem-overview"},"Cwtch Ecosystem \xdcbersicht")," - eine Zusammenfassung der aktiven Cwtch Repositories aus dem Cwtch Secure Development Handbuch."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"Beitragen zur Dokumentation")," - Ratschl\xe4ge zum Beitragen zur Cwtch-Dokumentation."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/testing"},"Beitragen zum Testen")," - Ratschl\xe4ge zum Beitragen durch das Testen von Cwtch."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/translate"},"Beitragen zu \xdcbersetzungen")," - Ratschl\xe4ge zum Beitragen von \xdcbersetzungen in Cwtch.")),(0,i.kt)("admonition",{title:"Hinweis",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Alle Beitr\xe4ge sind ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"berechtigt f\xfcr Aufkleber"))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/7c7a84a1.647782ac.js b/build-staging/de/assets/js/7c7a84a1.647782ac.js new file mode 100644 index 00000000..675fc4d1 --- /dev/null +++ b/build-staging/de/assets/js/7c7a84a1.647782ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2979],{3905:(e,n,r)=>{r.d(n,{Zo:()=>o,kt:()=>m});var i=r(7294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,i)}return r}function s(e){for(var n=1;n=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var u=i.createContext({}),l=function(e){var n=i.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},o=function(e){var n=l(e.components);return i.createElement(u.Provider,{value:n},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},g=i.forwardRef((function(e,n){var r=e.components,t=e.mdxType,a=e.originalType,u=e.parentName,o=d(e,["components","mdxType","originalType","parentName"]),c=l(r),g=t,m=c["".concat(u,".").concat(g)]||c[g]||h[g]||a;return r?i.createElement(m,s(s({ref:n},o),{},{components:r})):i.createElement(m,s({ref:n},o))}));function m(e,n){var r=arguments,t=n&&n.mdxType;if("string"==typeof e||t){var a=r.length,s=new Array(a);s[0]=g;var d={};for(var u in n)hasOwnProperty.call(n,u)&&(d[u]=n[u]);d.originalType=e,d[c]="string"==typeof e?e:t,s[1]=d;for(var l=2;l{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>l});var i=r(7462),t=(r(7294),r(3905));const a={},s="Bildervorschau",d={unversionedId:"components/ui/image_previews",id:"components/ui/image_previews",title:"Bildervorschau",description:"Basierend auf dem Filesharing in Cwtch 1.3 werden die Bildvorschauen durch die Erweiterung des vorgeschlagenen Dateinamens (und nein, wir sind nicht daran interessiert, MIME-Typen oder magische Zahlen zu verwenden) und die angezeigte Gr\xf6\xdfe bestimmt. Wenn diese Option aktiviert ist, l\xe4dt das Vorschausystem automatisch freigegebene Bilder in einen konfigurierten Download-Ordner herunter und zeigt sie als Teil der Nachricht selbst an. (Aufgrund von Beschr\xe4nkungen auf Android werden sie im privaten Cache der App gespeichert und Sie haben die M\xf6glichkeit, sie sp\xe4ter an anderer Stelle zu speichern) Die Dateigr\xf6\xdfenbeschr\xe4nkung ist noch nicht festgelegt, wird aber deutlich niedriger sein als die allgemeine Gr\xf6\xdfenbeschr\xe4nkung f\xfcr die gemeinsame Nutzung von Dateien, die derzeit bei 10 Gigabyte liegt.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/image_previews.md",sourceDirName:"components/ui",slug:"/components/ui/image_previews",permalink:"/de/security/components/ui/image_previews",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Android Dienst",permalink:"/de/security/components/ui/android"},next:{title:"Eingabe",permalink:"/de/security/components/ui/input"}},u={},l=[{value:"Bekannte Risiken",id:"bekannte-risiken",level:2},{value:"Andere Anwendungen und/oder das Betriebssystem, die Informationen aus Bildern ableiten",id:"andere-anwendungen-undoder-das-betriebssystem-die-informationen-aus-bildern-ableiten",level:2},{value:"B\xf6sartige Bilder, die Cwtch zum Absturz bringen oder anderweitig kompromittieren",id:"b\xf6sartige-bilder-die-cwtch-zum-absturz-bringen-oder-anderweitig-kompromittieren",level:2},{value:"B\xf6sartige Bilder werden auf verschiedenen Plattformen unterschiedlich gerendert, was zur Offenlegung von Metadaten f\xfchren kann",id:"b\xf6sartige-bilder-werden-auf-verschiedenen-plattformen-unterschiedlich-gerendert-was-zur-offenlegung-von-metadaten-f\xfchren-kann",level:2}],o={toc:l},c="wrapper";function h(e){let{components:n,...r}=e;return(0,t.kt)(c,(0,i.Z)({},o,r,{components:n,mdxType:"MDXLayout"}),(0,t.kt)("h1",{id:"bildervorschau"},"Bildervorschau"),(0,t.kt)("p",null,"Basierend auf dem Filesharing in Cwtch 1.3 werden die Bildvorschauen durch die Erweiterung des vorgeschlagenen Dateinamens (und nein, wir sind nicht daran interessiert, MIME-Typen oder magische Zahlen zu verwenden) und die angezeigte Gr\xf6\xdfe bestimmt. Wenn diese Option aktiviert ist, l\xe4dt das Vorschausystem automatisch freigegebene Bilder in einen konfigurierten Download-Ordner herunter und zeigt sie als Teil der Nachricht selbst an. (Aufgrund von Beschr\xe4nkungen auf Android werden sie im privaten Cache der App gespeichert und Sie haben die M\xf6glichkeit, sie sp\xe4ter an anderer Stelle zu speichern) Die Dateigr\xf6\xdfenbeschr\xe4nkung ist noch nicht festgelegt, wird aber deutlich niedriger sein als die allgemeine Gr\xf6\xdfenbeschr\xe4nkung f\xfcr die gemeinsame Nutzung von Dateien, die derzeit bei 10 Gigabyte liegt."),(0,t.kt)("p",null,"Im Moment unterst\xfctzen wir nur Einzelbildnachrichten und jede Bildbearbeitung/jeder Bildausschnitt muss in einer separaten Anwendung erfolgen. Wie in den FAQ zum Filesharing erw\xe4hnt, enthalten Bilddateien h\xe4ufig auch wichtige versteckte Metadaten und du solltest sie nur mit Personen teilen, denen du vertraust."),(0,t.kt)("h2",{id:"bekannte-risiken"},"Bekannte Risiken"),(0,t.kt)("h2",{id:"andere-anwendungen-undoder-das-betriebssystem-die-informationen-aus-bildern-ableiten"},"Andere Anwendungen und/oder das Betriebssystem, die Informationen aus Bildern ableiten"),(0,t.kt)("p",null,"Bilder m\xfcssen irgendwo gespeichert werden und wir haben uns daf\xfcr entschieden, sie zun\xe4chst unverschl\xfcsselt im Dateisystem zu speichern. Wir haben dies aus 2 Gr\xfcnden gemacht:"),(0,t.kt)("ol",null,(0,t.kt)("li",{parentName:"ol"},"Um leistungsf\xe4higere Dateifreigabeverfahren wie Rehosting zu unterst\xfctzen, m\xfcssen wir in der Lage sein, Dateien effizient zu scannen und Chunks zu liefern - dies \xfcber eine verschl\xfcsselte Datenbankschicht zu tun, w\xfcrde die Leistung beeintr\xe4chtigen."),(0,t.kt)("li",{parentName:"ol"},"Diese Informationen m\xfcssen immer die Anwendungsgrenze passieren (entweder \xfcber Anzeigetreiber oder durch Speichern und Anzeigen der Datei in einer externen Anwendung) - es gibt nichts, was Cwtch nach diesem Punkt tun kann.")),(0,t.kt)("h2",{id:"b\xf6sartige-bilder-die-cwtch-zum-absturz-bringen-oder-anderweitig-kompromittieren"},"B\xf6sartige Bilder, die Cwtch zum Absturz bringen oder anderweitig kompromittieren"),(0,t.kt)("p",null,"Flutter verwendet Skia, um Bilder zu rendern. Der zugrundeliegende Code ist zwar speicherunsicher, wird aber im Rahmen der regul\xe4ren Entwicklung ",(0,t.kt)("a",{parentName:"p",href:"https://github.com/google/skia/tree/main/fuzz"},"ausf\xfchrlich zerfusselt"),"."),(0,t.kt)("p",null,"Wir f\xfchren auch unsere eigenen Fuzz-Tests von Cwtch-Komponenten durch. Bei dieser Analyse haben wir einen einzigen Absturzfehler gefunden, der mit einer fehlerhaften GIF-Datei, die den Renderer dazu veranlasste, eine l\xe4cherliche Menge an Speicher zuzuweisen (und schlie\xdflich vom Kernel abgelehnt wurde). Um zu verhindern, dass sich dies auf Cwtch auswirkt, haben wir die Richtlinie eingef\xfchrt, immer eine maximale ",(0,t.kt)("inlineCode",{parentName:"p"},"cacheWidth")," und/oder ",(0,t.kt)("inlineCode",{parentName:"p"},"cacheHeight")," f\xfcr Bild-Widgets."),(0,t.kt)("h2",{id:"b\xf6sartige-bilder-werden-auf-verschiedenen-plattformen-unterschiedlich-gerendert-was-zur-offenlegung-von-metadaten-f\xfchren-kann"},"B\xf6sartige Bilder werden auf verschiedenen Plattformen unterschiedlich gerendert, was zur Offenlegung von Metadaten f\xfchren kann"),(0,t.kt)("p",null,"Vor kurzem wurde ",(0,t.kt)("a",{parentName:"p",href:"https://www.da.vidbuchanan.co.uk/widgets/pngdiff/"},"ein Fehler in Apples png-Parser")," gefunden, der dazu f\xfchrte, dass ein Bild auf Apple-Ger\xe4ten anders dargestellt wurde als auf Nicht-Apple-Ger\xe4ten."),(0,t.kt)("p",null,"Wir haben einige Tests mit unseren Mac-Builds durchgef\xfchrt und konnten dieses Problem f\xfcr Flutter nicht replizieren (da alle Flutter-Builds Skia f\xfcr das Rendering verwenden), aber wir werden solche F\xe4lle weiterhin in unseren Testkorpus aufnehmen."),(0,t.kt)("p",null,"Die Bildvorschau bleibt vorerst experimentell und auf freiwilliger Basis."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/803df0d9.1e172b64.js b/build-staging/de/assets/js/803df0d9.1e172b64.js new file mode 100644 index 00000000..6b032ca0 --- /dev/null +++ b/build-staging/de/assets/js/803df0d9.1e172b64.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2112],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var s=r.createContext({}),l=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(s.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(t),f=a,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||o;return t?r.createElement(m,i(i({ref:n},p),{},{components:t})):r.createElement(m,i({ref:n},p))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,i=new Array(o);i[0]=f;var c={};for(var s in n)hasOwnProperty.call(n,s)&&(c[s]=n[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=t(7462),a=(t(7294),t(3905));const o={sidebar_position:2},i="Neue Konversationen akzeptieren/ablehnen",c={unversionedId:"chat/accept-deny-new-conversation",id:"chat/accept-deny-new-conversation",title:"Neue Konversationen akzeptieren/ablehnen",description:"1. Zu deinem Profil gehen",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/accept-deny-new-conversation.md",sourceDirName:"chat",slug:"/chat/accept-deny-new-conversation",permalink:"/de/docs/chat/accept-deny-new-conversation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/accept-deny-new-conversation.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Neues Gespr\xe4ch beginnen",permalink:"/de/docs/chat/add-contact"},next:{title:"Teilen von Cwtch Adressen",permalink:"/de/docs/chat/share-address-with-friends"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:n,...t}=e;return(0,a.kt)(u,(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"neue-konversationen-akzeptierenablehnen"},"Neue Konversationen akzeptieren/ablehnen"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Zu deinem Profil gehen"),(0,a.kt)("li",{parentName:"ol"},"Wenn dich jemand als Kontakt hinzugef\xfcgt hat, dann erscheint ein neuer Name und zwei Optionen",(0,a.kt)("ol",{parentName:"li"},(0,a.kt)("li",{parentName:"ol"},"Klicke auf das Herzsymbol um diese neue Verbindung zu akzeptieren"),(0,a.kt)("li",{parentName:"ol"},"Klicke auf das Papierkorb-Symbol, um sie zu blockieren")))),(0,a.kt)("p",null,"Siehe auch: ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/behaviour/block-unknown-connections"},"Einstellung: Blockiere unbekannte Verbindungen")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/814f3328.46222a47.js b/build-staging/de/assets/js/814f3328.46222a47.js new file mode 100644 index 00000000..f205c580 --- /dev/null +++ b/build-staging/de/assets/js/814f3328.46222a47.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2535],{5641:t=>{t.exports=JSON.parse('{"title":"Neueste Logs","items":[{"title":"Cwtch Stable Roadmap Update","permalink":"/de/blog/cwtch-stable-roadmap-update-june"},{"title":"Cwtch Beta 1.12","permalink":"/de/blog/cwtch-nightly-1-12"},{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/de/blog/cwtch-nightly-v.11-74"},{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/de/blog/cwtch-developer-documentation"},{"title":"Availability Status and Profile Attributes","permalink":"/de/blog/availability-status-profile-attributes"},{"title":"Cwtch Stable Roadmap Update","permalink":"/de/blog/cwtch-stable-roadmap-update"},{"title":"Cwtch Beta 1.11","permalink":"/de/blog/cwtch-nightly-1-11"},{"title":"Updates to Cwtch Documentation","permalink":"/de/blog/cwtch-documentation"},{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/de/blog/autobindings-ii"},{"title":"Autogenerating Cwtch Bindings","permalink":"/de/blog/autobindings"},{"title":"Notes on Cwtch UI Testing (II)","permalink":"/de/blog/cwtch-testing-ii"},{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/de/blog/cwtch-android-reproducibility"},{"title":"Notes on Cwtch UI Testing","permalink":"/de/blog/cwtch-testing-i"},{"title":"Cwtch UI Platform Support","permalink":"/de/blog/cwtch-platform-support"},{"title":"Making Cwtch Bindings Reproducible","permalink":"/de/blog/cwtch-bindings-reproducible"},{"title":"Cwtch Stable API Design","permalink":"/de/blog/cwtch-stable-api-design"},{"title":"Path to Cwtch Stable","permalink":"/de/blog/path-to-cwtch-stable"}]}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/824a28c6.a3dd5280.js b/build-staging/de/assets/js/824a28c6.a3dd5280.js new file mode 100644 index 00000000..5e9eb493 --- /dev/null +++ b/build-staging/de/assets/js/824a28c6.a3dd5280.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5905],{3905:(t,e,i)=>{i.d(e,{Zo:()=>s,kt:()=>b});var r=i(7294);function n(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function o(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,r)}return i}function a(t){for(var e=1;e=0||(n[i]=t[i]);return n}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,i)&&(n[i]=t[i])}return n}var l=r.createContext({}),p=function(t){var e=r.useContext(l),i=e;return t&&(i="function"==typeof t?t(e):a(a({},e),t)),i},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},h="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var i=t.components,n=t.mdxType,o=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),h=p(i),d=n,b=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return i?r.createElement(b,a(a({ref:e},s),{},{components:i})):r.createElement(b,a({ref:e},s))}));function b(t,e){var i=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var o=i.length,a=new Array(o);a[0]=d;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[h]="string"==typeof t?t:n,a[1]=c;for(var p=2;p{i.r(e),i.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=i(7462),n=(i(7294),i(3905));const o={sidebar_position:1},a="Getting Started",c={unversionedId:"building-a-cwtch-app/intro",id:"building-a-cwtch-app/intro",title:"Getting Started",description:"Choosing A Cwtch Library",source:"@site/developing/building-a-cwtch-app/intro.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/intro",permalink:"/de/developing/building-a-cwtch-app/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Building a Cwtch App",permalink:"/de/developing/category/building-a-cwtch-app"},next:{title:"Core Concepts",permalink:"/de/developing/building-a-cwtch-app/core-concepts"}},l={},p=[{value:"Choosing A Cwtch Library",id:"choosing-a-cwtch-library",level:2},{value:"Cwtch Go Lib",id:"cwtch-go-lib",level:3},{value:"CwtchBot",id:"cwtchbot",level:3},{value:"Autobindings (C-bindings)",id:"autobindings-c-bindings",level:3},{value:"libCwtch-rs (Rust)",id:"libcwtch-rs-rust",level:3}],s={toc:p},h="wrapper";function u(t){let{components:e,...i}=t;return(0,n.kt)(h,(0,r.Z)({},s,i,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"getting-started"},"Getting Started"),(0,n.kt)("h2",{id:"choosing-a-cwtch-library"},"Choosing A Cwtch Library"),(0,n.kt)("h3",{id:"cwtch-go-lib"},"Cwtch Go Lib"),(0,n.kt)("p",null,"The official Cwtch library is written in Go and can be found at ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"https://git.openprivacy.ca/cwtch.im/cwtch"),". This library allows access to all Cwtch functionality."),(0,n.kt)("h3",{id:"cwtchbot"},"CwtchBot"),(0,n.kt)("p",null,"We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot#using-cwtchbot-go"},"building an echobot tutorial"),"."),(0,n.kt)("h3",{id:"autobindings-c-bindings"},"Autobindings (C-bindings)"),(0,n.kt)("p",null,"The ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"official c-bindings for Cwtch")," are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI."),(0,n.kt)("h3",{id:"libcwtch-rs-rust"},"libCwtch-rs (Rust)"),(0,n.kt)("p",null,"An experimental rust-fied version of Cwtch Autobindings is available in ",(0,n.kt)("a",{parentName:"p",href:"https://crates.io/crates/libcwtch"},"libCwtch-rs"),". While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/85f98c10.5193f85b.js b/build-staging/de/assets/js/85f98c10.5193f85b.js new file mode 100644 index 00000000..95a6b24d --- /dev/null +++ b/build-staging/de/assets/js/85f98c10.5193f85b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[420],{2294:e=>{e.exports=JSON.parse('{"label":"security-handbook","permalink":"/de/blog/tags/security-handbook","allTagsPath":"/de/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/8638bedc.9fde2922.js b/build-staging/de/assets/js/8638bedc.9fde2922.js new file mode 100644 index 00000000..c32ee266 --- /dev/null +++ b/build-staging/de/assets/js/8638bedc.9fde2922.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8493],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},f="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=c(r),u=i,m=f["".concat(s,".").concat(u)]||f[u]||d[u]||o;return r?n.createElement(m,l(l({ref:t},p),{},{components:r})):n.createElement(m,l({ref:t},p))}));function m(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,l=new Array(o);l[0]=u;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[f]="string"==typeof e?e:i,l[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:1},l="Eine Einf\xfchrung in die Cwtch Profile",a={unversionedId:"profiles/introduction",id:"profiles/introduction",title:"Eine Einf\xfchrung in die Cwtch Profile",description:"Mit Cwtch kannst Du eines von mehrere Profile erstellen. Jedes Profil erzeugt ein zuf\xe4lliges ed25519 Schl\xfcsselpaar, welches kompatibel mit dem Tor-Netzwerk ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/introduction.md",sourceDirName:"profiles",slug:"/profiles/introduction",permalink:"/de/docs/profiles/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Profiles",permalink:"/de/docs/category/profiles"},next:{title:"Ein neues Profil erstellen",permalink:"/de/docs/profiles/create-a-profile"}},s={},c=[{value:"Profile verwalten",id:"profile-verwalten",level:2}],p={toc:c},f="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(f,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eine-einf\xfchrung-in-die-cwtch-profile"},"Eine Einf\xfchrung in die Cwtch Profile"),(0,i.kt)("p",null,"Mit Cwtch kannst Du eines von mehrere ",(0,i.kt)("strong",{parentName:"p"},"Profile")," erstellen. Jedes Profil erzeugt ein zuf\xe4lliges ed25519 Schl\xfcsselpaar, welches kompatibel mit dem Tor-Netzwerk ist."),(0,i.kt)("p",null,"Dies ist der Identifikator, den Du Personen geben kannst und den diese verwenden k\xf6nnen, um dich \xfcber Cwtch zu kontaktieren."),(0,i.kt)("p",null,"Cwtch erm\xf6glicht das Erstellen und Verwalten mehrerer separater Profile. Jedes Profil ist mit einem anderen Schl\xfcsselpaar verkn\xfcpft, welches einen anderen Onion-Dienst startet."),(0,i.kt)("h2",{id:"profile-verwalten"},"Profile verwalten"),(0,i.kt)("p",null,'Beim Start startet Cwtch den Bildschirm "Profile verwalten". Von diesem Bildschirm aus kannst Du:'),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/create-a-profile"},"Neues Profil erstellen")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/unlock-profile"},"Existierende verschl\xfcsselte Profile freischalten")),(0,i.kt)("li",{parentName:"ul"},"Geladene Profile verwalten",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-name/"},"\xc4ndern des Anzeigennamens eines Profils")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-password/"},"\xc4ndern des Passwortes eines Profils")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/delete-profile"},"L\xf6schen eines Profils")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-profile-image/"},"\xc4ndern eines Profilbildes"))))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/89504eb8.bbcb116a.js b/build-staging/de/assets/js/89504eb8.bbcb116a.js new file mode 100644 index 00000000..90563cfb --- /dev/null +++ b/build-staging/de/assets/js/89504eb8.bbcb116a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5745],{5758:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/89f86a37.977505fc.js b/build-staging/de/assets/js/89f86a37.977505fc.js new file mode 100644 index 00000000..4a483b5b --- /dev/null +++ b/build-staging/de/assets/js/89f86a37.977505fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9759],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function c(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),s=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=s(a),u=n,d=m["".concat(l,".").concat(u)]||m[u]||h[u]||o;return a?r.createElement(d,c(c({ref:t},p),{},{components:a})):r.createElement(d,c({ref:t},p))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,c=new Array(o);c[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:n,c[1]=i;for(var s=2;s{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},c=void 0,i={permalink:"/de/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"29. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"release",permalink:"/de/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/de/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/de/blog/cwtch-documentation"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},m="wrapper";function h(e){let{components:t,...o}=e;return(0,n.kt)(m,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},6094:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/8b57ba24.61fcf910.js b/build-staging/de/assets/js/8b57ba24.61fcf910.js new file mode 100644 index 00000000..6c1f9926 --- /dev/null +++ b/build-staging/de/assets/js/8b57ba24.61fcf910.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3407],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,g=p["".concat(s,".").concat(m)]||p[m]||d[m]||l;return n?r.createElement(g,i(i({ref:t},c),{},{components:n})):r.createElement(g,i({ref:t},c))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[p]="string"==typeof e?e:a,i[1]=o;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>u});var r=n(7462),a=(n(7294),n(3905));const l={sidebar_position:2},i="Helles/Dunkles Design und Theme-Aufteilung",o={unversionedId:"settings/appearance/light-dark-mode",id:"settings/appearance/light-dark-mode",title:"Helles/Dunkles Design und Theme-Aufteilung",description:"1. Dr\xfccke das Einstellungssymbol",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/light-dark-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/light-dark-mode",permalink:"/de/docs/settings/appearance/light-dark-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/light-dark-mode.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Sprache wechseln",permalink:"/de/docs/settings/appearance/change-language"},next:{title:"UI Spalten",permalink:"/de/docs/settings/appearance/ui-columns"}},s={},u=[],c={toc:u},p="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"hellesdunkles-design-und-theme-aufteilung"},"Helles/Dunkles Design und Theme-Aufteilung"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Dr\xfccke das Einstellungssymbol"),(0,a.kt)("li",{parentName:"ol"},"Du kannst ein helles oder dunkles Thema w\xe4hlen, indem Du den Schalter \u201eVerwende helles Theme\u201c einschaltest"),(0,a.kt)("li",{parentName:"ol"},"W\xe4hle mit dem Dropdown-Men\xfc \u201eFarb-Theme\u201c ein Theme aus, das Dir gef\xe4llt"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("ol",{parentName:"li"},(0,a.kt)("li",{parentName:"ol"},"Cwtch: lila T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Geist: Graue T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Meerjungfrau: T\xfcrkise und violette T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Mitternacht: Schwarze und graue T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Neon 1: lila und rosa T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Neon 2: lila und t\xfcrkise T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"K\xfcrbis: lila und orange T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Hexe: Gr\xfcne und rosa T\xf6nung"),(0,a.kt)("li",{parentName:"ol"},"Vampir: Violette und rote T\xf6nung")))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/8e4780ba.c33e9ba5.js b/build-staging/de/assets/js/8e4780ba.c33e9ba5.js new file mode 100644 index 00000000..936cad4d --- /dev/null +++ b/build-staging/de/assets/js/8e4780ba.c33e9ba5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2044],{8895:e=>{e.exports=JSON.parse('{"title":"Profile","slug":"/category/profiles","permalink":"/de/docs/category/profiles","navigation":{"previous":{"title":"Unterst\xfctzte Platformen","permalink":"/de/docs/getting-started/supported_platforms"},"next":{"title":"Eine Einf\xfchrung in die Cwtch Profile","permalink":"/de/docs/profiles/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/8fe7a387.4209f6b8.js b/build-staging/de/assets/js/8fe7a387.4209f6b8.js new file mode 100644 index 00000000..ac392779 --- /dev/null +++ b/build-staging/de/assets/js/8fe7a387.4209f6b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5233],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=i.createContext({}),s=function(e){var t=i.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=s(e.components);return i.createElement(p.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(n),h=a,g=d["".concat(p,".").concat(h)]||d[h]||m[h]||r;return n?i.createElement(g,o(o({ref:t},c),{},{components:n})):i.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=h;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[d]="string"==typeof e?e:a,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const r={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"3. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"autobindings",permalink:"/de/blog/tags/autobindings"},{label:"libcwtch",permalink:"/de/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/de/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/de/blog/autobindings"}},p={authorsImageUrls:[void 0]},s=[{value:"The Structure of an Application Experiment",id:"the-structure-of-an-application-experiment",level:2},{value:"New Required Management APIs",id:"new-required-management-apis",level:3},{value:"Adding Support for Application Experiments in the Spec File",id:"adding-support-for-application-experiments-in-the-spec-file",level:3},{value:"Generation-Time Inclusion",id:"generation-time-inclusion",level:3},{value:"Cwtch UI Integration",id:"cwtch-ui-integration",level:3},{value:"Nightlies & Next Steps",id:"nightlies--next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:s},d="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,i.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"the-structure-of-an-application-experiment"},"The Structure of an Application Experiment"),(0,a.kt)("p",null,"An application-level experiment consists of:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"A set of top-level APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DeleteServer")," - these are the APIs that we want to expose to calling applications."),(0,a.kt)("li",{parentName:"ol"},"An encapsulating structure for the set of APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ServersFunctionality")," - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity."),(0,a.kt)("li",{parentName:"ol"},"A global variable that exists at the top level of libCwtch, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"var serverExperiment *servers.ServersFunctionality servers")," - our single pointer to the underlying functionality."),(0,a.kt)("li",{parentName:"ol"},"A set of management-related APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"Init"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"UpdateSettings"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"OnACNEvent")," - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers)."),(0,a.kt)("li",{parentName:"ol"},"Management code within ",(0,a.kt)("inlineCode",{parentName:"li"},"_startCwtch")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"_reconnectCwtch")," that calls the management APIs on the global variable.")),(0,a.kt)("p",null,"From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on ",(0,a.kt)("inlineCode",{parentName:"p"},"application")," or a specific ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"."),(0,a.kt)("p",null,"Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template."),(0,a.kt)("h3",{id:"new-required-management-apis"},"New Required Management APIs"),(0,a.kt)("p",null,"To achieve this weaving, we now require application-level experiments to implement an ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandlerInterface")," interface and expose itself via an\ninitialize constructor ",(0,a.kt)("inlineCode",{parentName:"p"},"Init(acn, appDir) -> EventHandlerInterface"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"Enable(app, acn)"),"."),(0,a.kt)("p",null,"For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface."),(0,a.kt)("p",null,"We can then generate, and optionally include blocks of code like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," = .Init(&globalACN, appDir)\n eventHandler.AddModule()\n .Enable(application, &globalACN)\n")),(0,a.kt)("p",null,"and place them at specific points in the code. ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandler")," has also been extended to maintain a collection of ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," so that it can\npass on interesting events."),(0,a.kt)("h3",{id:"adding-support-for-application-experiments-in-the-spec-file"},"Adding Support for Application Experiments in the Spec File"),(0,a.kt)("p",null,"We have introduced a new ",(0,a.kt)("inlineCode",{parentName:"p"},"!")," operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option ",(0,a.kt)("inlineCode",{parentName:"p"},"exp")," which will call the function on the configured experiment, and ",(0,a.kt)("inlineCode",{parentName:"p"},"global")," to allow the setting up\nof a global functionality within the library."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},' # Server Hosting Experiment\n !serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"\n !serverExperiment global serverExperiment *servers.ServersFunctionality servers\n !serverExperiment exp CreateServer application password string:description bool:autostart\n !serverExperiment exp SetServerAttribute application string:handle string:key string:val\n !serverExperiment exp LoadServers application acn password\n !serverExperiment exp LaunchServers application acn\n !serverExperiment exp LaunchServer application string:handle\n !serverExperiment exp StopServer application string:handle\n !serverExperiment exp StopServers application\n !serverExperiment exp DestroyServers\n !serverExperiment exp DeleteServer application string:handle password\n')),(0,a.kt)("h3",{id:"generation-time-inclusion"},"Generation-Time Inclusion"),(0,a.kt)("p",null," Without any arguments provided ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," will not generate code for any experiments."),(0,a.kt)("p",null," In order to determine what experimental code to generate, ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," now interprets arguments as enabled compile time experiments, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings serverExperiment")," will turn on\ngeneration of server hosting code, per the spec file above."),(0,a.kt)("h3",{id:"cwtch-ui-integration"},"Cwtch UI Integration"),(0,a.kt)("p",null,"The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"c_LoadServers")," - if it doesn't then the UI is safe to assume the\nfeature is not available."),(0,a.kt)("figure",null,(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7365).Z,width:"1290",height:"754"})),(0,a.kt)("figcaption",null,"A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.")),(0,a.kt)("h2",{id:"nightlies--next-steps"},"Nightlies & Next Steps"),(0,a.kt)("p",null,"We are now publishing ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/"},"nightlies")," of autobinding derived libCwtch-go, along with ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2"},"Repliqate scripts")," for reproducibility."),(0,a.kt)("p",null,"With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11."),(0,a.kt)("p",null,"However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),".")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}m.isMDXComponent=!0},7365:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png"},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/92123ee2.0766ae56.js b/build-staging/de/assets/js/92123ee2.0766ae56.js new file mode 100644 index 00000000..b59f601b --- /dev/null +++ b/build-staging/de/assets/js/92123ee2.0766ae56.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6773],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=i,v=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[d]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:3},a="Wie man einen Server bearbeitet",s={unversionedId:"servers/edit-server",id:"servers/edit-server",title:"Wie man einen Server bearbeitet",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/edit-server.md",sourceDirName:"servers",slug:"/servers/edit-server",permalink:"/de/docs/servers/edit-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/edit-server.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Wie man einen Server erstellt",permalink:"/de/docs/servers/create-server"},next:{title:"Wie man einen Server l\xf6scht",permalink:"/de/docs/servers/delete-server"}},c={},l=[],p={toc:l},d="wrapper";function u(e){let{components:r,...t}=e;return(0,i.kt)(d,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"wie-man-einen-server-bearbeitet"},"Wie man einen Server bearbeitet"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," eingeschaltet ist.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zum Server-Symbol gehen"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle den Server aus, den du bearbeiten m\xf6chtest"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke das Stift-Symbol"),(0,i.kt)("li",{parentName:"ol"},"\xc4ndere die Beschreibung oder den Server aktivieren oder deaktivieren"),(0,i.kt)("li",{parentName:"ol"},'Klicke auf "Server speichern"')),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/server_edit.mp4"}))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/924c44fc.e836e1ce.js b/build-staging/de/assets/js/924c44fc.e836e1ce.js new file mode 100644 index 00000000..3d8c7b4c --- /dev/null +++ b/build-staging/de/assets/js/924c44fc.e836e1ce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3413],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=s(n),g=i,d=p["".concat(l,".").concat(g)]||p[g]||h[g]||o;return n?r.createElement(d,c(c({ref:t},u),{},{components:n})):r.createElement(d,c({ref:t},u))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,c=new Array(o);c[0]=g;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:i,c[1]=a;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>s});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:2},c="Benachrichtigungsrichtlinie",a={unversionedId:"settings/behaviour/notification-policy",id:"settings/behaviour/notification-policy",title:"Benachrichtigungsrichtlinie",description:"1. Zu den Einstellungen",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/behaviour/notification-policy.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-policy",permalink:"/de/docs/settings/behaviour/notification-policy",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-policy.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Unbekannte Verbindungen blockieren",permalink:"/de/docs/settings/behaviour/block-unknown-connections"},next:{title:"Benachrichtigungsinhalt",permalink:"/de/docs/settings/behaviour/notification-content"}},l={},s=[],u={toc:s},p="wrapper";function h(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"benachrichtigungsrichtlinie"},"Benachrichtigungsrichtlinie"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"Zum Verhalten scrollen"),(0,i.kt)("li",{parentName:"ol"},"Die Benachrichtigungsrichtlinie steuert das Benachrichtigungsverhalten"),(0,i.kt)("li",{parentName:"ol"},"Auf Voreinstellung klicken, um das Verhalten zum Einschalten oder Stummschalten aller Benachrichtigungen zu \xe4ndern"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle deine bevorzugte Benachrichtigungsrichtlinie")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9323a439.d4fdc476.js b/build-staging/de/assets/js/9323a439.d4fdc476.js new file mode 100644 index 00000000..618d4442 --- /dev/null +++ b/build-staging/de/assets/js/9323a439.d4fdc476.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6395],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var a=r.createContext({}),u=function(e){var t=r.useContext(a),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(a.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,a=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(n),f=i,m=d["".concat(a,".").concat(f)]||d[f]||p[f]||o;return n?r.createElement(m,l(l({ref:t},c),{},{components:n})):r.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,l=new Array(o);l[0]=f;var s={};for(var a in t)hasOwnProperty.call(t,a)&&(s[a]=t[a]);s.originalType=e,s[d]="string"==typeof e?e:i,l[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={},l="Ver\xf6ffentlichung",s={unversionedId:"deployment",id:"deployment",title:"Ver\xf6ffentlichung",description:"Risiko: Bin\xe4rdateien werden auf der Website durch b\xf6swillige Versionen ersetzt",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/deployment.md",sourceDirName:".",slug:"/deployment",permalink:"/de/security/deployment",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Nachrichten Overlays",permalink:"/de/security/components/ui/overlays"},next:{title:"Entwicklung",permalink:"/de/security/development"}},a={},u=[{value:"Risiko: Bin\xe4rdateien werden auf der Website durch b\xf6swillige Versionen ersetzt",id:"risiko-bin\xe4rdateien-werden-auf-der-website-durch-b\xf6swillige-versionen-ersetzt",level:2}],c={toc:u},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"ver\xf6ffentlichung"},"Ver\xf6ffentlichung"),(0,i.kt)("h2",{id:"risiko-bin\xe4rdateien-werden-auf-der-website-durch-b\xf6swillige-versionen-ersetzt"},"Risiko: Bin\xe4rdateien werden auf der Website durch b\xf6swillige Versionen ersetzt"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert")),(0,i.kt)("p",null,"W\xe4hrend dieser Prozess jetzt gr\xf6\xdftenteils automatisiert ist, sollte diese Automatisierung jemals kompromittiert sein, dann gibt es in unserem aktuellen Prozess nichts, was dies erkennen w\xfcrde."),(0,i.kt)("p",null,"Wir ben\xf6tigen:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Reproduzierbare Builds - derzeit verwenden wir \xf6ffentliche Docker-Container f\xfcr alle Builds, was jedem erlauben sollte, verteilte Builds mit denen aus dem Quellcode zu vergleichen."),(0,i.kt)("li",{parentName:"ul"},"Signierte Ver\xf6ffentlichungen - Open Privacy verwaltet noch keinen \xf6ffentlichen Datensatz von Mitarbeitern \xf6ffentlichen Schl\xfcsseln. Dies ist wahrscheinlich eine Notwendigkeit um ver\xf6ffentlichte Builds zu signieren und eine Audit-Kette zu erstellen, die von der Organisation unterst\xfctzt wird. Dieser Prozess muss per Definition manuell sein.")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/935f2afb.a1a09f05.js b/build-staging/de/assets/js/935f2afb.a1a09f05.js new file mode 100644 index 00000000..b1721be7 --- /dev/null +++ b/build-staging/de/assets/js/935f2afb.a1a09f05.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"N\xe4chste","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Was ist Cwtch?","href":"/de/docs/intro","docId":"intro"},{"type":"category","label":"Erste Schritte","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Unterst\xfctzte Platformen","href":"/de/docs/getting-started/supported_platforms","docId":"getting-started/supported_platforms"}],"href":"/de/docs/category/getting-started"},{"type":"category","label":"Profile","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Eine Einf\xfchrung in die Cwtch Profile","href":"/de/docs/profiles/introduction","docId":"profiles/introduction"},{"type":"link","label":"Ein neues Profil erstellen","href":"/de/docs/profiles/create-a-profile","docId":"profiles/create-a-profile"},{"type":"link","label":"\xc4ndern Deines Anzeigenamens","href":"/de/docs/profiles/change-name","docId":"profiles/change-name"},{"type":"link","label":"Passwort \xe4ndern","href":"/de/docs/profiles/change-password","docId":"profiles/change-password"},{"type":"link","label":"Dein Profilbild \xe4ndern","href":"/de/docs/profiles/change-profile-image","docId":"profiles/change-profile-image"},{"type":"link","label":"Verschl\xfcsselte Profile entsperren","href":"/de/docs/profiles/unlock-profile","docId":"profiles/unlock-profile"},{"type":"link","label":"Ein Profil l\xf6schen","href":"/de/docs/profiles/delete-profile","docId":"profiles/delete-profile"},{"type":"link","label":"Sicherung oder Export eines Profils","href":"/de/docs/profiles/exporting-profile","docId":"profiles/exporting-profile"},{"type":"link","label":"Profil importieren","href":"/de/docs/profiles/importing-a-profile","docId":"profiles/importing-a-profile"},{"type":"link","label":"Verf\xfcgbarkeitsstatus einstellen","href":"/de/docs/profiles/availability-status","docId":"profiles/availability-status"},{"type":"link","label":"Profilattribute einstellen","href":"/de/docs/profiles/profile-info","docId":"profiles/profile-info"}],"href":"/de/docs/category/profiles"},{"type":"category","label":"Konversationen","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Eine Einf\xfchrung in die Cwtch P2P Chat","href":"/de/docs/chat/introduction","docId":"chat/introduction"},{"type":"link","label":"Neues Gespr\xe4ch beginnen","href":"/de/docs/chat/add-contact","docId":"chat/add-contact"},{"type":"link","label":"Neue Konversationen akzeptieren/ablehnen","href":"/de/docs/chat/accept-deny-new-conversation","docId":"chat/accept-deny-new-conversation"},{"type":"link","label":"Teilen von Cwtch Adressen","href":"/de/docs/chat/share-address-with-friends","docId":"chat/share-address-with-friends"},{"type":"link","label":"Gespr\xe4chsverlauf speichern","href":"/de/docs/chat/save-conversation-history","docId":"chat/save-conversation-history"},{"type":"link","label":"Nachrichtenformatierung","href":"/de/docs/chat/message-formatting","docId":"chat/message-formatting"},{"type":"link","label":"Konversationseinstellungen aufrufen","href":"/de/docs/chat/conversation-settings","docId":"chat/conversation-settings"},{"type":"link","label":"Auf eine Nachricht antworten","href":"/de/docs/chat/reply-to-message","docId":"chat/reply-to-message"},{"type":"link","label":"Eine Datei teilen","href":"/de/docs/chat/share-file","docId":"chat/share-file"},{"type":"link","label":"Einen Kontakt blockieren","href":"/de/docs/chat/block-contact","docId":"chat/block-contact"},{"type":"link","label":"Einen Kontakt entsperren","href":"/de/docs/chat/unblock-contact","docId":"chat/unblock-contact"},{"type":"link","label":"Entfernen einer Konversation","href":"/de/docs/chat/delete-contact","docId":"chat/delete-contact"}],"href":"/de/docs/category/conversations"},{"type":"category","label":"Gruppen","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Eine Einf\xfchrung in die Cwtch Gruppen","href":"/de/docs/groups/introduction","docId":"groups/introduction"},{"type":"link","label":"Eine neue Gruppe erstellen","href":"/de/docs/groups/create-group","docId":"groups/create-group"},{"type":"link","label":"Einladungen an eine Gruppe senden","href":"/de/docs/groups/send-invite","docId":"groups/send-invite"},{"type":"link","label":"Eine Gruppeneinladung annehmen","href":"/de/docs/groups/accept-group-invite","docId":"groups/accept-group-invite"},{"type":"link","label":"Wie man eine Gruppe verl\xe4sst?","href":"/de/docs/groups/leave-group","docId":"groups/leave-group"},{"type":"link","label":"Einen Gruppennamen bearbeiten","href":"/de/docs/groups/edit-group-name","docId":"groups/edit-group-name"},{"type":"link","label":"Server verwalten","href":"/de/docs/groups/manage-known-servers","docId":"groups/manage-known-servers"}],"href":"/de/docs/category/groups"},{"type":"category","label":"Server","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Server Einf\xfchrung","href":"/de/docs/servers/introduction","docId":"servers/introduction"},{"type":"link","label":"Wie man einen Server erstellt","href":"/de/docs/servers/create-server","docId":"servers/create-server"},{"type":"link","label":"Wie man einen Server bearbeitet","href":"/de/docs/servers/edit-server","docId":"servers/edit-server"},{"type":"link","label":"Wie man einen Server l\xf6scht","href":"/de/docs/servers/delete-server","docId":"servers/delete-server"},{"type":"link","label":"Wie du dein Server-Schl\xfcsselpaket teilst","href":"/de/docs/servers/share-key","docId":"servers/share-key"},{"type":"link","label":"Wie man einen Server entsperrt","href":"/de/docs/servers/unlock-server","docId":"servers/unlock-server"}],"href":"/de/docs/category/servers"},{"type":"category","label":"Einstellungen","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Eine Einf\xfchrung in die Cwtch App-Einstellungen","href":"/de/docs/settings/introduction","docId":"settings/introduction"},{"type":"category","label":"Darstellung","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Sprache wechseln","href":"/de/docs/settings/appearance/change-language","docId":"settings/appearance/change-language"},{"type":"link","label":"Helles/Dunkles Design und Theme-Aufteilung","href":"/de/docs/settings/appearance/light-dark-mode","docId":"settings/appearance/light-dark-mode"},{"type":"link","label":"UI Spalten","href":"/de/docs/settings/appearance/ui-columns","docId":"settings/appearance/ui-columns"},{"type":"link","label":"Streamer/Pr\xe4sentationsmodus","href":"/de/docs/settings/appearance/streamer-mode","docId":"settings/appearance/streamer-mode"}],"href":"/de/docs/category/appearance"},{"type":"category","label":"Verhalten","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Unbekannte Verbindungen blockieren","href":"/de/docs/settings/behaviour/block-unknown-connections","docId":"settings/behaviour/block-unknown-connections"},{"type":"link","label":"Benachrichtigungsrichtlinie","href":"/de/docs/settings/behaviour/notification-policy","docId":"settings/behaviour/notification-policy"},{"type":"link","label":"Benachrichtigungsinhalt","href":"/de/docs/settings/behaviour/notification-content","docId":"settings/behaviour/notification-content"}],"href":"/de/docs/category/behaviour"},{"type":"category","label":"Experimentelle Funktionen","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"experimentelle Gruppen Funktion","href":"/de/docs/settings/experiments/group-experiment","docId":"settings/experiments/group-experiment"},{"type":"link","label":"Server Hosting","href":"/de/docs/settings/experiments/server-hosting","docId":"settings/experiments/server-hosting"},{"type":"link","label":"Dateifreigabe","href":"/de/docs/settings/experiments/file-sharing","docId":"settings/experiments/file-sharing"},{"type":"link","label":"Bildvorschau und Profilbilder","href":"/de/docs/settings/experiments/image-previews-and-profile-pictures","docId":"settings/experiments/image-previews-and-profile-pictures"},{"type":"link","label":"Experiment klickbarer Links","href":"/de/docs/settings/experiments/clickable-links","docId":"settings/experiments/clickable-links"},{"type":"link","label":"Nachrichtenformatierung","href":"/de/docs/settings/experiments/message-formatting","docId":"settings/experiments/message-formatting"},{"type":"link","label":"QR Codes","href":"/de/docs/settings/experiments/qrcodes","docId":"settings/experiments/qrcodes"}],"href":"/de/docs/category/experiments"}],"href":"/de/docs/category/settings"},{"type":"link","label":"Tor","href":"/de/docs/tor","docId":"tor"},{"type":"category","label":"Mitwirken","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Entwicklung von Cwtch","href":"/de/docs/contribute/developing","docId":"contribute/developing"},{"type":"link","label":"Cwtch testen","href":"/de/docs/contribute/testing","docId":"contribute/testing"},{"type":"link","label":"Cwtch \xfcbersetzen","href":"/de/docs/contribute/translate","docId":"contribute/translate"},{"type":"link","label":"Stilregeln der Dokumentation","href":"/de/docs/contribute/documentation","docId":"contribute/documentation"},{"type":"link","label":"Aufkleber","href":"/de/docs/contribute/stickers","docId":"contribute/stickers"}],"href":"/de/docs/category/contribute"},{"type":"category","label":"Plattformen","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cwtch in Tails laufen lassen","href":"/de/docs/platforms/tails","docId":"platforms/tails"}],"href":"/de/docs/category/platforms"}]},"docs":{"chat/accept-deny-new-conversation":{"id":"chat/accept-deny-new-conversation","title":"Neue Konversationen akzeptieren/ablehnen","description":"1. Zu deinem Profil gehen","sidebar":"tutorialSidebar"},"chat/add-contact":{"id":"chat/add-contact","title":"Neues Gespr\xe4ch beginnen","description":"1. Ein Profil ausw\xe4hlen","sidebar":"tutorialSidebar"},"chat/block-contact":{"id":"chat/block-contact","title":"Einen Kontakt blockieren","description":"1. In einem Konversationsfenster","sidebar":"tutorialSidebar"},"chat/conversation-settings":{"id":"chat/conversation-settings","title":"Konversationseinstellungen aufrufen","description":"Klicke in einem Konversationsfenster auf das Einstellungssymbol in der oberen Leiste.","sidebar":"tutorialSidebar"},"chat/delete-contact":{"id":"chat/delete-contact","title":"Entfernen einer Konversation","description":"Diese Funktion wird unwiderruflich l\xf6schen. Dieses kann nicht r\xfcckg\xe4ngig gemacht werden.","sidebar":"tutorialSidebar"},"chat/introduction":{"id":"chat/introduction","title":"Eine Einf\xfchrung in die Cwtch P2P Chat","description":"Cwtch benutzt Tor v3 Onion Dienste, um anonyme, Peer-to-Peer-Verbindungen zwischen Profilen herzustellen.","sidebar":"tutorialSidebar"},"chat/message-formatting":{"id":"chat/message-formatting","title":"Nachrichtenformatierung","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Nachrichten Formatierung Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"chat/reply-to-message":{"id":"chat/reply-to-message","title":"Auf eine Nachricht antworten","description":"1. W\xe4hle eine Nachricht aus, auf die du antworten m\xf6chtest","sidebar":"tutorialSidebar"},"chat/save-conversation-history":{"id":"chat/save-conversation-history","title":"Gespr\xe4chsverlauf speichern","description":"Standardm\xe4\xdfig speichert Cwtch aus Gr\xfcnden der Privatsph\xe4re keine Unterhaltungshistorie zwischen den Sitzungen.","sidebar":"tutorialSidebar"},"chat/share-address-with-friends":{"id":"chat/share-address-with-friends","title":"Teilen von Cwtch Adressen","description":"Es gibt viele M\xf6glichkeiten, eine Cwtch Adresse zu teilen.","sidebar":"tutorialSidebar"},"chat/share-file":{"id":"chat/share-file","title":"Eine Datei teilen","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Datei Teilen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"chat/unblock-contact":{"id":"chat/unblock-contact","title":"Einen Kontakt entsperren","description":"1. W\xe4hle den Kontakt in Ihrer Konversationsliste aus. Gesperrte Kontakte werden an das Ende der Liste verschoben.","sidebar":"tutorialSidebar"},"contribute/developing":{"id":"contribute/developing","title":"Entwicklung von Cwtch","description":"Dieser Abschnitt dokumentiert einige M\xf6glichkeiten, um mit der Cwtch-Entwicklung zu beginnen.","sidebar":"tutorialSidebar"},"contribute/documentation":{"id":"contribute/documentation","title":"Stilregeln der Dokumentation","description":"Dieser Abschnitt dokumentiert die erwartete Struktur und Qualit\xe4t der Cwtch-Dokumentation.","sidebar":"tutorialSidebar"},"contribute/stickers":{"id":"contribute/stickers","title":"Aufkleber","description":"Alle Beitr\xe4ge sind f\xfcr Aufkleber berechtigt. Wenn du zu Bugs, Features, Testen oder Sprache beitr\xe4gst oder in der Vergangenheit einen wesentlichen Beitrag geleistet hast, schreibe bitte eine E-Mail an erinn@openprivacy. mit Details und einer Adresse f\xfcr uns, damit wir die Aufkleber dir schicken k\xf6nnen.","sidebar":"tutorialSidebar"},"contribute/testing":{"id":"contribute/testing","title":"Cwtch testen","description":"Dieser Abschnitt dokumentiert einige M\xf6glichkeiten, um mit Cwtch-Tests zu beginnen.","sidebar":"tutorialSidebar"},"contribute/translate":{"id":"contribute/translate","title":"Cwtch \xfcbersetzen","description":"Wenn du \xdcbersetzungen zu Cwtch beitragen m\xf6chtest, entweder zur App oder zu diesem Handbuch, kommt hier wie dies m\xf6glich ist.","sidebar":"tutorialSidebar"},"getting-started/supported_platforms":{"id":"getting-started/supported_platforms","title":"Unterst\xfctzte Platformen","description":"Die folgende Tabelle stellt unser aktuelles Verst\xe4ndnis von Cwtch-Unterst\xfctzung auf verschiedenen Betriebssystemen und Architekturen dar (Stand Cwtch 1.10 und Januar 2023).","sidebar":"tutorialSidebar"},"groups/accept-group-invite":{"id":"groups/accept-group-invite","title":"Eine Gruppeneinladung annehmen","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"groups/create-group":{"id":"groups/create-group","title":"Eine neue Gruppe erstellen","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"groups/edit-group-name":{"id":"groups/edit-group-name","title":"Einen Gruppennamen bearbeiten","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"groups/introduction":{"id":"groups/introduction","title":"Eine Einf\xfchrung in die Cwtch Gruppen","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"groups/leave-group":{"id":"groups/leave-group","title":"Wie man eine Gruppe verl\xe4sst?","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"groups/manage-known-servers":{"id":"groups/manage-known-servers","title":"Server verwalten","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"groups/send-invite":{"id":"groups/send-invite","title":"Einladungen an eine Gruppe senden","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Was ist Cwtch?","description":"Cwtch (/k\u028at\u0283/ - ein walisisches Wort, das grob \xfcbersetzt \u201eeine Umarmung, die einen sicheren Ort schafft\u201c bedeutet) ist eine dezentralisierte, Privatsp\xe4hre bewahrende, metadatenresistente Messenger-App.","sidebar":"tutorialSidebar"},"platforms/tails":{"id":"platforms/tails","title":"Cwtch in Tails laufen lassen","description":"Diese Funktionalit\xe4t ist derzeit nur verf\xfcgbar in den N\xe4chtlichen Release Builds von Cwtch.","sidebar":"tutorialSidebar"},"profiles/availability-status":{"id":"profiles/availability-status","title":"Verf\xfcgbarkeitsstatus einstellen","description":"Diese Funktionalit\xe4t ist derzeit nur verf\xfcgbar in den N\xe4chtlichen Release Builds von Cwtch.","sidebar":"tutorialSidebar"},"profiles/change-name":{"id":"profiles/change-name","title":"\xc4ndern Deines Anzeigenamens","description":"1. In der Ansicht Profile verwalten, klicke auf den Stift neben dem Profil, das Du bearbeiten m\xf6chtest","sidebar":"tutorialSidebar"},"profiles/change-password":{"id":"profiles/change-password","title":"Passwort \xe4ndern","description":"1. Dr\xfccke den Stift neben dem Profil, das du bearbeiten m\xf6chtest","sidebar":"tutorialSidebar"},"profiles/change-profile-image":{"id":"profiles/change-profile-image","title":"Dein Profilbild \xe4ndern","description":"Diese Funktion erfordert, dass Experimente aktiviert sind und sowohl die Dateifreigabe als auch Bild-Vorschau und Profilbilder aktiviert sind.","sidebar":"tutorialSidebar"},"profiles/create-a-profile":{"id":"profiles/create-a-profile","title":"Ein neues Profil erstellen","description":"1. Dr\xfccke die + Aktionstaste in der rechten unteren Ecke und w\xe4hle \\"Neues Profil\\"","sidebar":"tutorialSidebar"},"profiles/delete-profile":{"id":"profiles/delete-profile","title":"Ein Profil l\xf6schen","description":"Diese Funktion wird das Schl\xfcsselmaterial unwiderruflich l\xf6schen. Dies kann nicht r\xfcckg\xe4ngig gemacht werden.","sidebar":"tutorialSidebar"},"profiles/exporting-profile":{"id":"profiles/exporting-profile","title":"Sicherung oder Export eines Profils","description":"Auf der Profil-Verwaltungsseite:","sidebar":"tutorialSidebar"},"profiles/importing-a-profile":{"id":"profiles/importing-a-profile","title":"Profil importieren","description":"1. Dr\xfccke die + Aktionstaste in der rechten unteren Ecke und w\xe4hle \\"Importiere Profil\\"","sidebar":"tutorialSidebar"},"profiles/introduction":{"id":"profiles/introduction","title":"Eine Einf\xfchrung in die Cwtch Profile","description":"Mit Cwtch kannst Du eines von mehrere Profile erstellen. Jedes Profil erzeugt ein zuf\xe4lliges ed25519 Schl\xfcsselpaar, welches kompatibel mit dem Tor-Netzwerk ist.","sidebar":"tutorialSidebar"},"profiles/profile-info":{"id":"profiles/profile-info","title":"Profilattribute einstellen","description":"Diese Funktionalit\xe4t ist derzeit nur verf\xfcgbar in den N\xe4chtlichen Release Builds von Cwtch.","sidebar":"tutorialSidebar"},"profiles/unlock-profile":{"id":"profiles/unlock-profile","title":"Verschl\xfcsselte Profile entsperren","description":"Wenn du Cwtch neu startest und ein Passwort in deinem Profil benutzst, dann wird es nicht als Standard geladen, sondern Du musst es erst entsperren.","sidebar":"tutorialSidebar"},"servers/create-server":{"id":"servers/create-server","title":"Wie man einen Server erstellt","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"servers/delete-server":{"id":"servers/delete-server","title":"Wie man einen Server l\xf6scht","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"servers/edit-server":{"id":"servers/edit-server","title":"Wie man einen Server bearbeitet","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"servers/introduction":{"id":"servers/introduction","title":"Server Einf\xfchrung","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"servers/share-key":{"id":"servers/share-key","title":"Wie du dein Server-Schl\xfcsselpaket teilst","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"servers/unlock-server":{"id":"servers/unlock-server","title":"Wie man einen Server entsperrt","description":"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.","sidebar":"tutorialSidebar"},"settings/appearance/change-language":{"id":"settings/appearance/change-language","title":"Sprache wechseln","description":"Dank der Hilfe von Freiwilligenwurde die Cwtch-App in viele Sprachen \xfcbersetzt.","sidebar":"tutorialSidebar"},"settings/appearance/light-dark-mode":{"id":"settings/appearance/light-dark-mode","title":"Helles/Dunkles Design und Theme-Aufteilung","description":"1. Dr\xfccke das Einstellungssymbol","sidebar":"tutorialSidebar"},"settings/appearance/streamer-mode":{"id":"settings/appearance/streamer-mode","title":"Streamer/Pr\xe4sentationsmodus","description":"Streamer/Pr\xe4sentationsmodus macht die App optisch privater. In diesem Modus wird Cwtch keine Hilfsinformationen wie Cwtch-Adressen und andere sensible Informationen auf den Hauptbildschirmen anzeigen.","sidebar":"tutorialSidebar"},"settings/appearance/ui-columns":{"id":"settings/appearance/ui-columns","title":"UI Spalten","description":"1. Dr\xfccke das Einstellungssymbol","sidebar":"tutorialSidebar"},"settings/behaviour/block-unknown-connections":{"id":"settings/behaviour/block-unknown-connections","title":"Unbekannte Verbindungen blockieren","description":"Standardm\xe4\xdfig interpretiert Cwtch Verbindungen von unbekannten Cwtch-Adressen als Kontaktanfragen. Du kannst dieses Verhalten durch die Blockierung unbekannter Verbindungen \xe4ndern.","sidebar":"tutorialSidebar"},"settings/behaviour/notification-content":{"id":"settings/behaviour/notification-content","title":"Benachrichtigungsinhalt","description":"1. Zu den Einstellungen","sidebar":"tutorialSidebar"},"settings/behaviour/notification-policy":{"id":"settings/behaviour/notification-policy","title":"Benachrichtigungsrichtlinie","description":"1. Zu den Einstellungen","sidebar":"tutorialSidebar"},"settings/experiments/clickable-links":{"id":"settings/experiments/clickable-links","title":"Experiment klickbarer Links","description":"Wenn aktiviert, stellt diese Funktion ein Entanonymisierung Risiko dar.","sidebar":"tutorialSidebar"},"settings/experiments/file-sharing":{"id":"settings/experiments/file-sharing","title":"Dateifreigabe","description":"Diese Einstellung aktiviert Cwtch Dateisharing-Funktionalit\xe4t. Dies zeigt die Option \\"Datei teilen\\" im Konversationsbereich an und erlaubt dir Dateien von Konversationen herunterzuladen.","sidebar":"tutorialSidebar"},"settings/experiments/group-experiment":{"id":"settings/experiments/group-experiment","title":"experimentelle Gruppen Funktion","description":"Erm\xf6glicht Cwtch eine Verbindung zu nicht vertrauensw\xfcrdigen Server und verwendet diese f\xfcr private, asynchrone Gruppen.","sidebar":"tutorialSidebar"},"settings/experiments/image-previews-and-profile-pictures":{"id":"settings/experiments/image-previews-and-profile-pictures","title":"Bildvorschau und Profilbilder","description":"Dieses experimentelle Funktion erfordert das File Sharing aktiviert ist.","sidebar":"tutorialSidebar"},"settings/experiments/message-formatting":{"id":"settings/experiments/message-formatting","title":"Nachrichtenformatierung","description":"Wenn aktiviert, \xe4ndert diese experimentelle Funktion die Konversationsbox um Nachrichtenformatierung UX hinzuzuf\xfcgen.","sidebar":"tutorialSidebar"},"settings/experiments/qrcodes":{"id":"settings/experiments/qrcodes","title":"QR Codes","description":"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem du es mit vergr\xf6\xdferst.","sidebar":"tutorialSidebar"},"settings/experiments/server-hosting":{"id":"settings/experiments/server-hosting","title":"Server Hosting","description":"Server-Hosting ist derzeit eine experimentelle Funktion in Cwtch, es ist standardm\xe4\xdfig nicht aktiviert.","sidebar":"tutorialSidebar"},"settings/introduction":{"id":"settings/introduction","title":"Eine Einf\xfchrung in die Cwtch App-Einstellungen","description":"Darstellung","sidebar":"tutorialSidebar"},"tor":{"id":"tor","title":"Tor","description":"Cwtch verwendet Tor um Routing und Verbindungen bereitzustellen. Die Verwendung von Tor-versteckten Diensten f\xfcr das Hosten von Profilen und nebenbei generierte \\"ephemerale\\" Verbindungen, wenn eine Verbindung aufgebaut wird, bietet eine starke Anonymit\xe4t f\xfcr Benutzer von Cwtch.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/940964f5.c09d4cfe.js b/build-staging/de/assets/js/940964f5.c09d4cfe.js new file mode 100644 index 00000000..a299c12c --- /dev/null +++ b/build-staging/de/assets/js/940964f5.c09d4cfe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9178],{7186:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/cwtch","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/de/blog/tags/cwtch/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9428180e.e7e66090.js b/build-staging/de/assets/js/9428180e.e7e66090.js new file mode 100644 index 00000000..8883bce9 --- /dev/null +++ b/build-staging/de/assets/js/9428180e.e7e66090.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9550],{3905:(e,t,n)=>{n.d(t,{Zo:()=>f,kt:()=>b});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},f=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,f=s(e,["components","mdxType","originalType","parentName"]),p=c(n),d=i,b=p["".concat(l,".").concat(d)]||p[d]||u[d]||o;return n?r.createElement(b,a(a({ref:t},f),{},{components:n})):r.createElement(b,a({ref:t},f))}));function b(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:i,a[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:15},a="Profilattribute einstellen",s={unversionedId:"profiles/profile-info",id:"profiles/profile-info",title:"Profilattribute einstellen",description:"Diese Funktionalit\xe4t ist derzeit nur verf\xfcgbar in den N\xe4chtlichen Release Builds von Cwtch.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/profile-info.md",sourceDirName:"profiles",slug:"/profiles/profile-info",permalink:"/de/docs/profiles/profile-info",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/profile-info.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_position:15},sidebar:"tutorialSidebar",previous:{title:"Verf\xfcgbarkeitsstatus einstellen",permalink:"/de/docs/profiles/availability-status"},next:{title:"Conversations",permalink:"/de/docs/category/conversations"}},l={},c=[],f={toc:c},p="wrapper";function u(e){let{components:t,...o}=e;return(0,i.kt)(p,(0,r.Z)({},f,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"profilattribute-einstellen"},"Profilattribute einstellen"),(0,i.kt)("admonition",{title:"Warnung Feature des n\xe4chtlichen Releases",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktionalit\xe4t ist derzeit ",(0,i.kt)("strong",{parentName:"p"},"nur ")," verf\xfcgbar in den ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"N\xe4chtlichen Release")," Builds von Cwtch."),(0,i.kt)("p",{parentName:"admonition"},"Diese Funktionalit\xe4t kann unvollst\xe4ndig und/oder gef\xe4hrlich sein, wenn sie falsch benutzt wird. Bitte hilf uns bei der \xdcberpr\xfcfung und dem Test.")),(0,i.kt)("p",null,"Im ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/introduction#manage-profiles"},"Profilverwaltungsfenster")," befinden sich drei freiformatige Textfelder unterhalb deines Profilbilds."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(92).Z},(0,i.kt)("img",{src:n(6689).Z,width:"783",height:"354"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Du kannst diese Felder mit allen Informationen ausf\xfcllen, die du potenzielle Kontakte wissen m\xf6chtest. ",(0,i.kt)("strong",{parentName:"p"},"Diese Informationen sind \xf6ffentlich")," - lege hier keine Informationen an, die du nicht mit allen teilen m\xf6chtest."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(2243).Z},(0,i.kt)("img",{src:n(3506).Z,width:"730",height:"342"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Kontakte k\xf6nnen diese Informationen in den ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/conversation-settings"},"Konversationseinstellungen")," einsehen."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(5637).Z},(0,i.kt)("img",{src:n(136).Z,width:"294",height:"195"}))),(0,i.kt)("figcaption",null)))}u.isMDXComponent=!0},5637:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},92:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png"},2243:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},136:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},6689:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png"},3506:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/948dc444.62bf25d1.js b/build-staging/de/assets/js/948dc444.62bf25d1.js new file mode 100644 index 00000000..42fd395f --- /dev/null +++ b/build-staging/de/assets/js/948dc444.62bf25d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8851],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(r),f=i,m=d["".concat(c,".").concat(f)]||d[f]||u[f]||o;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function m(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:4},a="Bildvorschau und Profilbilder",s={unversionedId:"settings/experiments/image-previews-and-profile-pictures",id:"settings/experiments/image-previews-and-profile-pictures",title:"Bildvorschau und Profilbilder",description:"Dieses experimentelle Funktion erfordert das File Sharing aktiviert ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/image-previews-and-profile-pictures.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/image-previews-and-profile-pictures",permalink:"/de/docs/settings/experiments/image-previews-and-profile-pictures",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/image-previews-and-profile-pictures.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Dateifreigabe",permalink:"/de/docs/settings/experiments/file-sharing"},next:{title:"Experiment klickbarer Links",permalink:"/de/docs/settings/experiments/clickable-links"}},c={},l=[],p={toc:l},d="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"bildvorschau-und-profilbilder"},"Bildvorschau und Profilbilder"),(0,i.kt)("admonition",{title:"Vorsicht",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Dieses experimentelle Funktion erfordert das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"File Sharing")," aktiviert ist.")),(0,i.kt)("p",null,"Wenn aktiviert, wird Cwtch die Bilddateien automatisch herunterladen, Bildvorschau im Konversationsfenster anzeigen und ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profilbilder")," aktivieren;"),(0,i.kt)("p",null,"Auf dem Desktop, durch das Aktivieren dieser experimentellen Funktion wird der Zugriff auf eine zus\xe4tzliche Einstellung ",(0,i.kt)("inlineCode",{parentName:"p"},'"'),"Downloadordner` erlaubt, die ge\xe4ndert werden kann, um Cwtch zu sagen, wo (automatisch) Bilder heruntergeladen werden sollen."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9785.e0c467d7.js b/build-staging/de/assets/js/9785.e0c467d7.js new file mode 100644 index 00000000..b1c5c624 --- /dev/null +++ b/build-staging/de/assets/js/9785.e0c467d7.js @@ -0,0 +1 @@ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9785],{3905:(e,t,n)=>{"use strict";n.d(t,{Zo:()=>u,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),s=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return o.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=s(n),p=a,f=m["".concat(i,".").concat(p)]||m[p]||d[p]||r;return n?o.createElement(f,c(c({ref:t},u),{},{components:n})):o.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,c=new Array(r);c[0]=p;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[m]="string"==typeof e?e:a,c[1]=l;for(var s=2;s{"use strict";n.d(t,{Z:()=>u});var o=n(7294),a=n(5999),r=n(5281),c=n(7462),l=n(6010);const i={iconEdit:"iconEdit_Z9Sw"};function s(e){let{className:t,...n}=e;return o.createElement("svg",(0,c.Z)({fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,l.Z)(i.iconEdit,t),"aria-hidden":"true"},n),o.createElement("g",null,o.createElement("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})))}function u(e){let{editUrl:t}=e;return o.createElement("a",{href:t,target:"_blank",rel:"noreferrer noopener",className:r.k.common.editThisPage},o.createElement(s,null),o.createElement(a.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page"},"Edit this page"))}},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var o=n(7462),a=n(7294),r=n(6010),c=n(5999),l=n(6668),i=n(9960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function u(e){let{as:t,id:n,...u}=e;const{navbar:{hideOnScroll:m}}=(0,l.L)();if("h1"===t||!n)return a.createElement(t,(0,o.Z)({},u,{id:void 0}));const d=(0,c.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return a.createElement(t,(0,o.Z)({},u,{className:(0,r.Z)("anchor",m?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n}),u.children,a.createElement(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d},"\u200b"))}},1506:(e,t,n)=>{"use strict";n.d(t,{Z:()=>he});var o=n(7294),a=n(3905),r=n(7462),c=n(5742);var l=n(2389),i=n(6010),s=n(2949),u=n(6668);function m(){const{prism:e}=(0,u.L)(),{colorMode:t}=(0,s.I)(),n=e.theme,o=e.darkTheme||n;return"dark"===t?o:n}var d=n(5281),p=n(7594),f=n.n(p);const g=/title=(?["'])(?.*?)\1/,h=/\{(?<range>[\d,-]+)\}/,y={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function b(e,t){const n=e.map((e=>{const{start:n,end:o}=y[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${o})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:o,magicComments:a,metastring:r}=t;if(r&&h.test(r)){const e=r.match(h).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${r}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,o=f()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(o),code:n}}if(void 0===o)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);default:return b(Object.keys(y),t)}}(o,a),l=n.split("\n"),i=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),s=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let p=0;p<l.length;){const e=l[p].match(c);if(!e){p+=1;continue}const t=e.slice(1).find((e=>void 0!==e));s[t]?i[s[t]].range+=`${p},`:u[t]?i[u[t]].start=p:m[t]&&(i[m[t]].range+=`${i[m[t]].start}-${p-1},`),l.splice(p,1)}n=l.join("\n");const d={};return Object.entries(i).forEach((e=>{let[t,{range:n}]=e;f()(n).forEach((e=>{d[e]??=[],d[e].push(t)}))})),{lineClassNames:d,code:n}}const E={codeBlockContainer:"codeBlockContainer_Ckt0"};function k(e){let{as:t,...n}=e;const a=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[o,a]=e;const r=t[o];r&&"string"==typeof a&&(n[r]=a)})),n}(m());return o.createElement(t,(0,r.Z)({},n,{style:a,className:(0,i.Z)(n.className,E.codeBlockContainer,d.k.common.codeBlock)}))}const N={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function C(e){let{children:t,className:n}=e;return o.createElement(k,{as:"pre",tabIndex:0,className:(0,i.Z)(N.codeBlockStandalone,"thin-scrollbar",n)},o.createElement("code",{className:N.codeBlockLines},t))}var w=n(902);const B={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Z(e,t){const[n,a]=(0,o.useState)(),r=(0,o.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,o.useEffect)((()=>{r()}),[r]),function(e,t,n){void 0===n&&(n=B);const a=(0,w.zX)(t),r=(0,w.Ql)(n);(0,o.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,r),()=>t.disconnect()}),[e,a,r])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),r())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}const T={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]};var L={Prism:n(7410).Z,theme:T};function j(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _(){return _=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},_.apply(this,arguments)}var x=/\r\n|\r|\n/,O=function(e){0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},S=function(e,t){var n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)};function P(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&-1===t.indexOf(o)&&(n[o]=e[o]);return n}var z=function(e){function t(){for(var t=this,n=[],o=arguments.length;o--;)n[o]=arguments[o];e.apply(this,n),j(this,"getThemeDict",(function(e){if(void 0!==t.themeDict&&e.theme===t.prevTheme&&e.language===t.prevLanguage)return t.themeDict;t.prevTheme=e.theme,t.prevLanguage=e.language;var n=e.theme?function(e,t){var n=e.plain,o=Object.create(null),a=e.styles.reduce((function(e,n){var o=n.languages,a=n.style;return o&&!o.includes(t)||n.types.forEach((function(t){var n=_({},e[t],a);e[t]=n})),e}),o);return a.root=n,a.plain=_({},n,{backgroundColor:null}),a}(e.theme,e.language):void 0;return t.themeDict=n})),j(this,"getLineProps",(function(e){var n=e.key,o=e.className,a=e.style,r=_({},P(e,["key","className","style","line"]),{className:"token-line",style:void 0,key:void 0}),c=t.getThemeDict(t.props);return void 0!==c&&(r.style=c.plain),void 0!==a&&(r.style=void 0!==r.style?_({},r.style,a):a),void 0!==n&&(r.key=n),o&&(r.className+=" "+o),r})),j(this,"getStyleForToken",(function(e){var n=e.types,o=e.empty,a=n.length,r=t.getThemeDict(t.props);if(void 0!==r){if(1===a&&"plain"===n[0])return o?{display:"inline-block"}:void 0;if(1===a&&!o)return r[n[0]];var c=o?{display:"inline-block"}:{},l=n.map((function(e){return r[e]}));return Object.assign.apply(Object,[c].concat(l))}})),j(this,"getTokenProps",(function(e){var n=e.key,o=e.className,a=e.style,r=e.token,c=_({},P(e,["key","className","style","token"]),{className:"token "+r.types.join(" "),children:r.content,style:t.getStyleForToken(r),key:void 0});return void 0!==a&&(c.style=void 0!==c.style?_({},c.style,a):a),void 0!==n&&(c.key=n),o&&(c.className+=" "+o),c})),j(this,"tokenize",(function(e,t,n,o){var a={code:t,grammar:n,language:o,tokens:[]};e.hooks.run("before-tokenize",a);var r=a.tokens=e.tokenize(a.code,a.grammar,a.language);return e.hooks.run("after-tokenize",a),r}))}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.render=function(){var e=this.props,t=e.Prism,n=e.language,o=e.code,a=e.children,r=this.getThemeDict(this.props),c=t.languages[n];return a({tokens:function(e){for(var t=[[]],n=[e],o=[0],a=[e.length],r=0,c=0,l=[],i=[l];c>-1;){for(;(r=o[c]++)<a[c];){var s=void 0,u=t[c],m=n[c][r];if("string"==typeof m?(u=c>0?u:["plain"],s=m):(u=S(u,m.type),m.alias&&(u=S(u,m.alias)),s=m.content),"string"==typeof s){var d=s.split(x),p=d.length;l.push({types:u,content:d[0]});for(var f=1;f<p;f++)O(l),i.push(l=[]),l.push({types:u,content:d[f]})}else c++,t.push(u),n.push(s),o.push(0),a.push(s.length)}c--,t.pop(),n.pop(),o.pop(),a.pop()}return O(l),i}(void 0!==c?this.tokenize(t,o,c,n):[o]),className:"prism-code language-"+n,style:void 0!==r?r.root:{},getLineProps:this.getLineProps,getTokenProps:this.getTokenProps})},t}(o.Component);const A=z,I={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function W(e){let{line:t,classNames:n,showLineNumbers:a,getLineProps:c,getTokenProps:l}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const s=c({line:t,className:(0,i.Z)(n,a&&I.codeLine)}),u=t.map(((e,t)=>o.createElement("span",(0,r.Z)({key:t},l({token:e,key:t})))));return o.createElement("span",s,a?o.createElement(o.Fragment,null,o.createElement("span",{className:I.codeLineNumber}),o.createElement("span",{className:I.codeLineContent},u)):u,o.createElement("br",null))}var M=n(5999);function H(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"}))}function D(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))}const V={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function R(e){let{code:t,className:n}=e;const[a,r]=(0,o.useState)(!1),c=(0,o.useRef)(void 0),l=(0,o.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const o=document.createElement("textarea"),a=document.activeElement;o.value=e,o.setAttribute("readonly",""),o.style.contain="strict",o.style.position="absolute",o.style.left="-9999px",o.style.fontSize="12pt";const r=document.getSelection(),c=r.rangeCount>0&&r.getRangeAt(0);n.append(o),o.select(),o.selectionStart=0,o.selectionEnd=e.length;let l=!1;try{l=document.execCommand("copy")}catch{}o.remove(),c&&(r.removeAllRanges(),r.addRange(c)),a&&a.focus()}(t),r(!0),c.current=window.setTimeout((()=>{r(!1)}),1e3)}),[t]);return(0,o.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),o.createElement("button",{type:"button","aria-label":a?(0,M.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,M.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,M.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.Z)("clean-btn",n,V.copyButton,a&&V.copyButtonCopied),onClick:l},o.createElement("span",{className:V.copyButtonIcons,"aria-hidden":"true"},o.createElement(H,{className:V.copyButtonIcon}),o.createElement(D,{className:V.copyButtonSuccessIcon})))}function $(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"}))}const F={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function q(e){let{className:t,onClick:n,isEnabled:a}=e;const r=(0,M.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return o.createElement("button",{type:"button",onClick:n,className:(0,i.Z)("clean-btn",t,a&&F.wordWrapButtonEnabled),"aria-label":r,title:r},o.createElement($,{className:F.wordWrapButtonIcon,"aria-hidden":"true"}))}function G(e){let{children:t,className:n="",metastring:a,title:c,showLineNumbers:l,language:s}=e;const{prism:{defaultLanguage:d,magicComments:p}}=(0,u.L)(),f=s??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??d,h=m(),y=function(){const[e,t]=(0,o.useState)(!1),[n,a]=(0,o.useState)(!1),r=(0,o.useRef)(null),c=(0,o.useCallback)((()=>{const n=r.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[r,e]),l=(0,o.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=r.current,n=e>t||r.current.querySelector("code").hasAttribute("style");a(n)}),[r]);return Z(r,l),(0,o.useEffect)((()=>{l()}),[e,l]),(0,o.useEffect)((()=>(window.addEventListener("resize",l,{passive:!0}),()=>{window.removeEventListener("resize",l)})),[l]),{codeBlockRef:r,isEnabled:e,isCodeScrollable:n,toggle:c}}(),b=function(e){return e?.match(g)?.groups.title??""}(a)||c,{lineClassNames:E,code:C}=v(t,{metastring:a,language:f,magicComments:p}),w=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return o.createElement(k,{as:"div",className:(0,i.Z)(n,f&&!n.includes(`language-${f}`)&&`language-${f}`)},b&&o.createElement("div",{className:N.codeBlockTitle},b),o.createElement("div",{className:N.codeBlockContent},o.createElement(A,(0,r.Z)({},L,{theme:h,code:C,language:f??"text"}),(e=>{let{className:t,tokens:n,getLineProps:a,getTokenProps:r}=e;return o.createElement("pre",{tabIndex:0,ref:y.codeBlockRef,className:(0,i.Z)(t,N.codeBlock,"thin-scrollbar")},o.createElement("code",{className:(0,i.Z)(N.codeBlockLines,w&&N.codeBlockLinesWithNumbering)},n.map(((e,t)=>o.createElement(W,{key:t,line:e,getLineProps:a,getTokenProps:r,classNames:E[t],showLineNumbers:w})))))})),o.createElement("div",{className:N.buttonGroup},(y.isEnabled||y.isCodeScrollable)&&o.createElement(q,{className:N.codeButton,onClick:()=>y.toggle(),isEnabled:y.isEnabled}),o.createElement(R,{className:N.codeButton,code:C}))))}function U(e){let{children:t,...n}=e;const a=(0,l.Z)(),c=function(e){return o.Children.toArray(e).some((e=>(0,o.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof c?G:C;return o.createElement(i,(0,r.Z)({key:String(a)},n),c)}var Q=n(9960);var X=n(6043);const Y={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function J(e){return!!e&&("SUMMARY"===e.tagName||J(e.parentElement))}function K(e,t){return!!e&&(e===t||K(e.parentElement,t))}function ee(e){let{summary:t,children:n,...a}=e;const c=(0,l.Z)(),s=(0,o.useRef)(null),{collapsed:u,setCollapsed:m}=(0,X.u)({initialState:!a.open}),[d,p]=(0,o.useState)(a.open),f=o.isValidElement(t)?t:o.createElement("summary",null,t??"Details");return o.createElement("details",(0,r.Z)({},a,{ref:s,open:d,"data-collapsed":u,className:(0,i.Z)(Y.details,c&&Y.isBrowser,a.className),onMouseDown:e=>{J(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;J(t)&&K(t,s.current)&&(e.preventDefault(),u?(m(!1),p(!0)):m(!0))}}),f,o.createElement(X.z,{lazy:!1,collapsed:u,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{m(e),p(!e)}},o.createElement("div",{className:Y.collapsibleContent},n)))}const te={details:"details_b_Ee"},ne="alert alert--info";function oe(e){let{...t}=e;return o.createElement(ee,(0,r.Z)({},t,{className:(0,i.Z)(ne,te.details,t.className)}))}var ae=n(2503);function re(e){return o.createElement(ae.Z,e)}const ce={containsTaskList:"containsTaskList_mC6p"};const le={img:"img_ev3q"};const ie="admonition_LlT9",se="admonitionHeading_tbUL",ue="admonitionIcon_kALy",me="admonitionContent_S0QG";const de={note:{infimaClassName:"secondary",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:o.createElement(M.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:o.createElement(M.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 16 16"},o.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:o.createElement(M.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},pe={secondary:"note",important:"info",success:"tip",warning:"danger"};function fe(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=o.Children.toArray(e),n=t.find((e=>o.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n,rest:a}}(e.children);return{...e,title:e.title??t,children:n}}const ge={head:function(e){const t=o.Children.map(e.children,(e=>o.isValidElement(e)?function(e){if(e.props?.mdxType&&e.props.originalType){const{mdxType:t,originalType:n,...a}=e.props;return o.createElement(e.props.originalType,a)}return e}(e):e));return o.createElement(c.Z,e,t)},code:function(e){const t=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return o.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")||(0,o.isValidElement)(e)&&t.includes(e.props?.mdxType)))?o.createElement("code",e):o.createElement(U,e)},a:function(e){return o.createElement(Q.Z,e)},pre:function(e){return o.createElement(U,(0,o.isValidElement)(e.children)&&"code"===e.children.props?.originalType?e.children.props:{...e})},details:function(e){const t=o.Children.toArray(e.children),n=t.find((e=>o.isValidElement(e)&&"summary"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return o.createElement(oe,(0,r.Z)({},e,{summary:n}),a)},ul:function(e){return o.createElement("ul",(0,r.Z)({},e,{className:(t=e.className,(0,i.Z)(t,t?.includes("contains-task-list")&&ce.containsTaskList))}));var t},img:function(e){return o.createElement("img",(0,r.Z)({loading:"lazy"},e,{className:(t=e.className,(0,i.Z)(t,le.img))}));var t},h1:e=>o.createElement(re,(0,r.Z)({as:"h1"},e)),h2:e=>o.createElement(re,(0,r.Z)({as:"h2"},e)),h3:e=>o.createElement(re,(0,r.Z)({as:"h3"},e)),h4:e=>o.createElement(re,(0,r.Z)({as:"h4"},e)),h5:e=>o.createElement(re,(0,r.Z)({as:"h5"},e)),h6:e=>o.createElement(re,(0,r.Z)({as:"h6"},e)),admonition:function(e){const{children:t,type:n,title:a,icon:r}=fe(e),c=function(e){const t=pe[e]??e,n=de[t];return n||(console.warn(`No admonition config found for admonition type "${t}". Using Info as fallback.`),de.info)}(n),l=a??c.label,{iconComponent:s}=c,u=r??o.createElement(s,null);return o.createElement("div",{className:(0,i.Z)(d.k.common.admonition,d.k.common.admonitionType(e.type),"alert",`alert--${c.infimaClassName}`,ie)},o.createElement("div",{className:se},o.createElement("span",{className:ue},u),l),o.createElement("div",{className:me},t))},mermaid:n(1875).Z};function he(e){let{children:t}=e;return o.createElement(a.Zo,{components:ge},t)}},2244:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var o=n(7294),a=n(6010),r=n(9960);function c(e){const{permalink:t,title:n,subLabel:c,isNext:l}=e;return o.createElement(r.Z,{className:(0,a.Z)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},c&&o.createElement("div",{className:"pagination-nav__sublabel"},c),o.createElement("div",{className:"pagination-nav__label"},n))}},3008:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var o=n(7294),a=n(6010),r=n(9960);const c={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function l(e){let{permalink:t,label:n,count:l}=e;return o.createElement(r.Z,{href:t,className:(0,a.Z)(c.tag,l?c.tagWithCount:c.tagRegular)},n,l&&o.createElement("span",null,l))}},1526:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var o=n(7294),a=n(6010),r=n(5999),c=n(3008);const l={tags:"tags_jXut",tag:"tag_QGVx"};function i(e){let{tags:t}=e;return o.createElement(o.Fragment,null,o.createElement("b",null,o.createElement(r.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list"},"Tags:")),o.createElement("ul",{className:(0,a.Z)(l.tags,"padding--none","margin-left--sm")},t.map((e=>{let{label:t,permalink:n}=e;return o.createElement("li",{key:n,className:l.tag},o.createElement(c.Z,{label:t,permalink:n}))}))))}},7594:(e,t)=>{function n(e){let t,n=[];for(let o of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(o))n.push(parseInt(o,10));else if(t=o.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,o,a,r]=t;if(o&&r){o=parseInt(o),r=parseInt(r);const e=o<r?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(r+=e);for(let t=o;t!==r;t+=e)n.push(t)}}return n}t.default=n,e.exports=n}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/979b71b8.a0be1006.js b/build-staging/de/assets/js/979b71b8.a0be1006.js new file mode 100644 index 00000000..9cf68cb3 --- /dev/null +++ b/build-staging/de/assets/js/979b71b8.a0be1006.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2543],{1708:a=>{a.exports=JSON.parse('{"label":"api","permalink":"/de/blog/tags/api","allTagsPath":"/de/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/980b70df.5d920609.js b/build-staging/de/assets/js/980b70df.5d920609.js new file mode 100644 index 00000000..27789747 --- /dev/null +++ b/build-staging/de/assets/js/980b70df.5d920609.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6900],{4444:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/bindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/98609693.d9ca1bf2.js b/build-staging/de/assets/js/98609693.d9ca1bf2.js new file mode 100644 index 00000000..c5f320f3 --- /dev/null +++ b/build-staging/de/assets/js/98609693.d9ca1bf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9794],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var u=r.createContext({}),s=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=s(e.components);return r.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,u=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=s(n),h=i,f=d["".concat(u,".").concat(h)]||d[h]||p[h]||o;return n?r.createElement(f,a(a({ref:t},l),{},{components:n})):r.createElement(f,a({ref:t},l))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=h;var c={};for(var u in t)hasOwnProperty.call(t,u)&&(c[u]=t[u]);c.originalType=e,c[d]="string"==typeof e?e:i,a[1]=c;for(var s=2;s<o;s++)a[s]=n[s];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},7960:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:1},a="Eine Einf\xfchrung in die Cwtch P2P Chat",c={unversionedId:"chat/introduction",id:"chat/introduction",title:"Eine Einf\xfchrung in die Cwtch P2P Chat",description:"Cwtch benutzt Tor v3 Onion Dienste, um anonyme, Peer-to-Peer-Verbindungen zwischen Profilen herzustellen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/introduction.md",sourceDirName:"chat",slug:"/chat/introduction",permalink:"/de/docs/chat/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Conversations",permalink:"/de/docs/category/conversations"},next:{title:"Neues Gespr\xe4ch beginnen",permalink:"/de/docs/chat/add-contact"}},u={},s=[{value:"Wie P2P-Chat unter der Haube funktioniert",id:"wie-p2p-chat-unter-der-haube-funktioniert",level:2}],l={toc:s},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eine-einf\xfchrung-in-die-cwtch-p2p-chat"},"Eine Einf\xfchrung in die Cwtch P2P Chat"),(0,i.kt)("p",null,"Cwtch benutzt Tor v3 Onion Dienste, um anonyme, Peer-to-Peer-Verbindungen zwischen Profilen herzustellen."),(0,i.kt)("h2",{id:"wie-p2p-chat-unter-der-haube-funktioniert"},"Wie P2P-Chat unter der Haube funktioniert"),(0,i.kt)("p",null,"Um mit deinen Freunden in einem Peer-to-Peer-Gespr\xe4ch zu chatten, m\xfcssen beide online sein."),(0,i.kt)("p",null,"Nach einer erfolgreichen Verbindung beteiligen sich beide Seiten an einem ",(0,i.kt)("strong",{parentName:"p"},"-Authentifizierungsprotokoll")," von:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Behauptet, dass jede Seite Zugang zu dem privaten Schl\xfcssel hat, der mit ihrer \xf6ffentlichen Identit\xe4t verbunden ist."),(0,i.kt)("li",{parentName:"ul"},"Erzeugt einen ephemeren Session-Schl\xfcssel, der zur Verschl\xfcsselung aller weiteren Kommunikation w\xe4hrend der Sitzung verwendet wird.")),(0,i.kt)("p",null,"Dieser Austausch (detailliert im ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/authentication_protocol.html"},"-Authentifizierungsprotokoll"),"dokumentiert) ist ",(0,i.kt)("em",{parentName:"p"},"offline verweigerbar")," d. h. es ist m\xf6glich f\xfcr jede Seite Transkripte dieses Protokoll-Auszutausches zu f\xe4lschen und daher ist es unm\xf6glich definitiv zu beweisen, dass der Austausch \xfcberhaupt stattgefunden hat."),(0,i.kt)("p",null,"Sobald der Authentifizierungsprozess erfolgreich ist, kannst Du und dein Freund sicher sein, dass niemand anderes etwas \xfcber den Inhalt oder die Metadaten eurer Konversation erfahren kann."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/995c4a51.55d04cd2.js b/build-staging/de/assets/js/995c4a51.55d04cd2.js new file mode 100644 index 00000000..2505f718 --- /dev/null +++ b/build-staging/de/assets/js/995c4a51.55d04cd2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4582],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>h});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function c(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=r.createContext({}),u=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},l=function(e){var n=u(e.components);return r.createElement(s.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},b=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),d=u(t),b=i,h=d["".concat(s,".").concat(b)]||d[b]||p[b]||o;return t?r.createElement(h,a(a({ref:n},l),{},{components:t})):r.createElement(h,a({ref:n},l))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=b;var c={};for(var s in n)hasOwnProperty.call(n,s)&&(c[s]=n[s]);c.originalType=e,c[d]="string"==typeof e?e:i,a[1]=c;for(var u=2;u<o;u++)a[u]=t[u];return r.createElement.apply(null,a)}return r.createElement.apply(null,t)}b.displayName="MDXCreateElement"},8492:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const o={sidebar_position:1},a="Unbekannte Verbindungen blockieren",c={unversionedId:"settings/behaviour/block-unknown-connections",id:"settings/behaviour/block-unknown-connections",title:"Unbekannte Verbindungen blockieren",description:"Standardm\xe4\xdfig interpretiert Cwtch Verbindungen von unbekannten Cwtch-Adressen als Kontaktanfragen. Du kannst dieses Verhalten durch die Blockierung unbekannter Verbindungen \xe4ndern.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/behaviour/block-unknown-connections.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/block-unknown-connections",permalink:"/de/docs/settings/behaviour/block-unknown-connections",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/block-unknown-connections.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Behaviour",permalink:"/de/docs/category/behaviour"},next:{title:"Benachrichtigungsrichtlinie",permalink:"/de/docs/settings/behaviour/notification-policy"}},s={},u=[],l={toc:u},d="wrapper";function p(e){let{components:n,...t}=e;return(0,i.kt)(d,(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"unbekannte-verbindungen-blockieren"},"Unbekannte Verbindungen blockieren"),(0,i.kt)("p",null,"Standardm\xe4\xdfig interpretiert Cwtch Verbindungen von unbekannten Cwtch-Adressen als ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/chat/accept-deny-new-conversation"},"Kontaktanfragen"),". Du kannst dieses Verhalten durch die Blockierung unbekannter Verbindungen \xe4ndern."),(0,i.kt)("p",null,"Wenn aktiviert, schlie\xdft Cwtch automatisch alle Verbindungen von Cwtch-Adressen, die Du nicht zur Konversationsliste hinzugef\xfcgt hast. Dadurch wird verhindert, dass Personen, die Deine Cwtch-Adresse haben, sich mit Dir in Verbindung setzen, es sei denn, Du f\xfcgst diese hinzu."),(0,i.kt)("p",null,"Zum Aktivieren:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"Blockieren unbekannter Kontakte aktivieren")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9ad9d6dc.db6df9ae.js b/build-staging/de/assets/js/9ad9d6dc.db6df9ae.js new file mode 100644 index 00000000..01b8ec51 --- /dev/null +++ b/build-staging/de/assets/js/9ad9d6dc.db6df9ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[828],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(r),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var p=2;p<o;p++)i[p]=r[p];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1472:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:1},i="Paketformat",c={unversionedId:"components/tapir/packet_format",id:"components/tapir/packet_format",title:"Paketformat",description:"Alle Tapir-Pakete haben eine feste L\xe4nge (8192 Bytes) und die ersten 2 Bytes zeigen die tats\xe4chliche L\xe4nge der Nachricht, len Bytes an Daten und der Rest mit null aufgef\xfcllt:",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/tapir/packet_format.md",sourceDirName:"components/tapir",slug:"/components/tapir/packet_format",permalink:"/de/security/components/tapir/packet_format",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Tapir",permalink:"/de/security/category/tapir"},next:{title:"Authentifizierungsprotokoll",permalink:"/de/security/components/tapir/authentication_protocol"}},s={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"paketformat"},"Paketformat"),(0,a.kt)("p",null,"Alle Tapir-Pakete haben eine feste L\xe4nge (8192 Bytes) und die ersten 2 Bytes zeigen die tats\xe4chliche L\xe4nge der Nachricht, ",(0,a.kt)("inlineCode",{parentName:"p"},"len")," Bytes an Daten und der Rest mit null aufgef\xfcllt:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|\n")),(0,a.kt)("p",null,"Einmal verschl\xfcsselt, ist das gesamte 8192-Byte-Datenpaket mit ",(0,a.kt)("a",{parentName:"p",href:"https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox"},"libsodium secretbox")," verschl\xfcsselt unter Verwendung der Standardstruktur ( beachte in diesem Fall die tats\xe4chlich benutzbare Gr\xf6\xdfe des Datenpakets ist 8190-14, um die Nonce in der Geheimbox zu unterbringen)"),(0,a.kt)("p",null,"Informationen dar\xfcber, wie der geheime Schl\xfcssel abgeleitet wird, findest du im ",(0,a.kt)("a",{parentName:"p",href:"/de/security/components/tapir/authentication_protocol"},"Authentifizierungsprotokoll")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9b12a270.8c3428a2.js b/build-staging/de/assets/js/9b12a270.8c3428a2.js new file mode 100644 index 00000000..4229da0a --- /dev/null +++ b/build-staging/de/assets/js/9b12a270.8c3428a2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9249],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>g});var r=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function o(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?a(Object(i),!0).forEach((function(t){n(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):a(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function c(e,t){if(null==e)return{};var i,r,n=function(e,t){if(null==e)return{};var i,r,n={},a=Object.keys(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var s=r.createContext({}),l=function(e){var t=r.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},d=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,a=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),p=l(i),h=n,g=p["".concat(s,".").concat(h)]||p[h]||u[h]||a;return i?r.createElement(g,o(o({ref:t},d),{},{components:i})):r.createElement(g,o({ref:t},d))}));function g(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=i.length,o=new Array(a);o[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:n,o[1]=c;for(var l=2;l<a;l++)o[l]=i[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,i)}h.displayName="MDXCreateElement"},9816:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=i(7462),n=(i(7294),i(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/de/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"10. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/de/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"repliqate",permalink:"/de/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/de/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/de/blog/cwtch-testing-i"}},s={authorsImageUrls:[void 0]},l=[{value:"Changes Necessary for Reproducible Android Bindings",id:"changes-necessary-for-reproducible-android-bindings",level:2},{value:"Repliqate Scripts",id:"repliqate-scripts",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:l},p="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,r.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(4756).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"changes-necessary-for-reproducible-android-bindings"},"Changes Necessary for Reproducible Android Bindings"),(0,n.kt)("p",null,"After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Insufficient path stripping introduced by Android NDK tools")," - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/android/ndk/wiki/Changelog-r22"},"changed the binutils and default linker")," to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our ",(0,n.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-platform-support"},"long term support plan"),", we will be moving towards adopting the latest NDK in the future."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Paths in DWARF entries")," - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.")),(0,n.kt)("figure",null,(0,n.kt)("p",null,(0,n.kt)("a",{target:"_blank",href:i(4560).Z},(0,n.kt)("img",{src:i(9842).Z,width:"1863",height:"428"}))),(0,n.kt)("figcaption",null,"Vimdiff comparing the decoded (",(0,n.kt)("code",null,"readelf --debug-dump=line"),") DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Go Compiler Acquisition")," - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there ",(0,n.kt)("em",{parentName:"li"},"was")," a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.")),(0,n.kt)("h2",{id:"repliqate-scripts"},"Repliqate Scripts"),(0,n.kt)("p",null,"With those issues now fixed, Cwtch Android bindings are ",(0,n.kt)("strong",{parentName:"p"},"officially reproducible!")," The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script"},"cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script")," in the ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/"},"Cwtch Repliqate scripts repository"),"."),(0,n.kt)("p",null,"This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4560:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},9842:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},4756:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"},4515:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9bd730d3.9aafd7fc.js b/build-staging/de/assets/js/9bd730d3.9aafd7fc.js new file mode 100644 index 00000000..bf73a0e4 --- /dev/null +++ b/build-staging/de/assets/js/9bd730d3.9aafd7fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2051],{3905:(e,n,t)=>{t.d(n,{Zo:()=>d,kt:()=>f});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function a(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},s=Object.keys(e);for(r=0;r<s.length;r++)t=s[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)t=s[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},d=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,s=e.originalType,c=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),u=l(t),h=i,f=u["".concat(c,".").concat(h)]||u[h]||p[h]||s;return t?r.createElement(f,o(o({ref:n},d),{},{components:t})):r.createElement(f,o({ref:n},d))}));function f(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=t.length,o=new Array(s);o[0]=h;var a={};for(var c in n)hasOwnProperty.call(n,c)&&(a[c]=n[c]);a.originalType=e,a[u]="string"==typeof e?e:i,o[1]=a;for(var l=2;l<s;l++)o[l]=t[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,t)}h.displayName="MDXCreateElement"},9735:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=t(7462),i=(t(7294),t(3905));const s={sidebar_position:3},o="Teilen von Cwtch Adressen",a={unversionedId:"chat/share-address-with-friends",id:"chat/share-address-with-friends",title:"Teilen von Cwtch Adressen",description:"Es gibt viele M\xf6glichkeiten, eine Cwtch Adresse zu teilen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/share-address-with-friends.md",sourceDirName:"chat",slug:"/chat/share-address-with-friends",permalink:"/de/docs/chat/share-address-with-friends",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-address-with-friends.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Neue Konversationen akzeptieren/ablehnen",permalink:"/de/docs/chat/accept-deny-new-conversation"},next:{title:"Gespr\xe4chsverlauf speichern",permalink:"/de/docs/chat/save-conversation-history"}},c={},l=[{value:"Teilen deiner Cwtch Adresse",id:"teilen-deiner-cwtch-adresse",level:2}],d={toc:l},u="wrapper";function p(e){let{components:n,...t}=e;return(0,i.kt)(u,(0,r.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"teilen-von-cwtch-adressen"},"Teilen von Cwtch Adressen"),(0,i.kt)("p",null,"Es gibt viele M\xf6glichkeiten, eine Cwtch Adresse zu teilen."),(0,i.kt)("h2",{id:"teilen-deiner-cwtch-adresse"},"Teilen deiner Cwtch Adresse"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zu deinem Profil gehen"),(0,i.kt)("li",{parentName:"ol"},"Klicke auf das Kopiere-Adresse-Symbol")),(0,i.kt)("p",null,"Du kannst diese Adresse nun teilen. Personen mit dieser Adresse k\xf6nnen dich als Cwtch Kontakt hinzuf\xfcgen."),(0,i.kt)("p",null,"F\xfcr Informationen zum Blockieren von Verbindungen von Personen, die du nicht kennst, lies bitte ",(0,i.kt)("a",{parentName:"p",href:"/docs/settings/behaviour/block-unknown-connections"},"Einstellungen: Unbekannte Verbindungen blockieren")),(0,i.kt)("h1",{id:"teilen-der-cwtch-adresse-von-freunden"},"Teilen der Cwtch Adresse von Freunden"),(0,i.kt)("p",null,"Innerhalb von Cwtch gibt es einen weiteren Mechanismus zum Austausch von Cwtch-Adressen."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9bec89a3.bd2b9eed.js b/build-staging/de/assets/js/9bec89a3.bd2b9eed.js new file mode 100644 index 00000000..d27a44b7 --- /dev/null +++ b/build-staging/de/assets/js/9bec89a3.bd2b9eed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8344],{5294:a=>{a.exports=JSON.parse('{"label":"planning","permalink":"/de/blog/tags/planning","allTagsPath":"/de/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9c488c02.6046e2f8.js b/build-staging/de/assets/js/9c488c02.6046e2f8.js new file mode 100644 index 00000000..a7c270e7 --- /dev/null +++ b/build-staging/de/assets/js/9c488c02.6046e2f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[97],{3905:(e,n,r)=>{r.d(n,{Zo:()=>d,kt:()=>g});var t=r(7294);function i(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function a(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){i(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function u(e,n){if(null==e)return{};var r,t,i=function(e,n){if(null==e)return{};var r,t,i={},s=Object.keys(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||(i[r]=e[r]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=t.createContext({}),o=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):a(a({},n),e)),r},d=function(e){var n=o(e.components);return t.createElement(l.Provider,{value:n},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},m=t.forwardRef((function(e,n){var r=e.components,i=e.mdxType,s=e.originalType,l=e.parentName,d=u(e,["components","mdxType","originalType","parentName"]),c=o(r),m=i,g=c["".concat(l,".").concat(m)]||c[m]||h[m]||s;return r?t.createElement(g,a(a({ref:n},d),{},{components:r})):t.createElement(g,a({ref:n},d))}));function g(e,n){var r=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=r.length,a=new Array(s);a[0]=m;var u={};for(var l in n)hasOwnProperty.call(n,l)&&(u[l]=n[l]);u.originalType=e,u[c]="string"==typeof e?e:i,a[1]=u;for(var o=2;o<s;o++)a[o]=r[o];return t.createElement.apply(null,a)}return t.createElement.apply(null,r)}m.displayName="MDXCreateElement"},7580:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>u,toc:()=>o});var t=r(7462),i=(r(7294),r(3905));const s={sidebar_position:2},a="Risiko-Modell",u={unversionedId:"risk",id:"risk",title:"Risiko-Modell",description:"Es ist bekannt, dass Kommunikationsmetadaten von verschiedenen Gegnern ausgenutzt werden, um die Sicherheit von Systemen zu untergraben, Opfer zu verfolgen und gro\xdf angelegte Analysen sozialer Netzwerke durchzuf\xfchren, um die Massen\xfcberwachung zu unterst\xfctzen. Metadaten-resistente Tools stecken noch in den Kinderschuhen und es fehlt an Forschung zur Konstruktion und Benutzererfahrung solcher Tools.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/risk.md",sourceDirName:".",slug:"/risk",permalink:"/de/security/risk",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch Sicherheitshandbuch",permalink:"/de/security/intro"},next:{title:"Cwtch Components",permalink:"/de/security/category/cwtch-components"}},l={},o=[{value:"Bedrohungsmodell",id:"bedrohungsmodell",level:2},{value:"Aktive Angriffe",id:"aktive-angriffe",level:3},{value:"Falschdarstellungsangriffe",id:"falschdarstellungsangriffe",level:4},{value:"Eine Anmerkung zu physischen Angriffen",id:"eine-anmerkung-zu-physischen-angriffen",level:2}],d={toc:o},c="wrapper";function h(e){let{components:n,...s}=e;return(0,i.kt)(c,(0,t.Z)({},d,s,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"risiko-modell"},"Risiko-Modell"),(0,i.kt)("p",null,"Es ist bekannt, dass Kommunikationsmetadaten von verschiedenen Gegnern ausgenutzt werden, um die Sicherheit von Systemen zu untergraben, Opfer zu verfolgen und gro\xdf angelegte Analysen sozialer Netzwerke durchzuf\xfchren, um die Massen\xfcberwachung zu unterst\xfctzen. Metadaten-resistente Tools stecken noch in den Kinderschuhen und es fehlt an Forschung zur Konstruktion und Benutzererfahrung solcher Tools."),(0,i.kt)("p",null,(0,i.kt)("img",{src:r(5448).Z,width:"1920",height:"1080"})),(0,i.kt)("p",null,"Cwtch wurde urspr\xfcnglich als Erweiterung des Metadaten-resistenten Protokolls Ricochet konzipiert, um die asynchrone Multi-Peer-Gruppenkommunikation durch die Verwendung einer verwerfbaren, nicht vertrauensw\xfcrdigen, anonymen Infrastruktur zu unterst\xfctzen."),(0,i.kt)("p",null,"Seitdem hat sich Cwtch zu einem eigenst\xe4ndigen Protokoll entwickelt. In diesem Abschnitt werden die verschiedenen bekannten Risiken beschrieben, die Cwtch zu mindern versucht, und es wird im Rest des Dokuments stark darauf verwiesen, wenn die verschiedenen Unterkomponenten der Cwtch-Architektur er\xf6rtert werden."),(0,i.kt)("h2",{id:"bedrohungsmodell"},"Bedrohungsmodell"),(0,i.kt)("p",null,"Es ist wichtig zu erkennen und zu verstehen, dass Metadaten in Kommunikationsprotokollen allgegenw\xe4rtig sind, es ist in der Tat notwendig, dass solche Protokolle effizient und in gro\xdfem Umfang funktionieren. Informationen, die f\xfcr die Unterst\xfctzung von Peers und Servern n\xfctzlich sind, sind jedoch auch f\xfcr Gegner, die solche Informationen ausnutzen m\xf6chten, von gro\xdfer Bedeutung."),(0,i.kt)("p",null,"F\xfcr unsere Problemstellung gehen wir davon aus, dass der Inhalt einer Kommunikation so verschl\xfcsselt ist, dass ein Angreifer sie praktisch nicht knacken kann (siehe ",(0,i.kt)("a",{parentName:"p",href:"/security/category/tapir"},"tapir")," und ",(0,i.kt)("a",{parentName:"p",href:"security/category/cwtch"},"cwtch")," f\xfcr Details zu der von uns verwendeten Verschl\xfcsselung) und daher konzentrieren wir uns auf den Kontext der Kommunikationsmetadaten."),(0,i.kt)("p",null,"Wir bem\xfchen uns, die folgenden Kommunikationskontexte zu sch\xfctzen:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Wer ist an einer Kommunikation beteiligt? Es kann m\xf6glich sein, Personen oder einfach Ger\xe4te- oder Netzwerkkennungen zu identifizieren. Beispiel: \u201eAn dieser Kommunikation sind Alice, eine Journalistin, und Bob, ein Regierungsangestellter, beteiligt.\u201c."),(0,i.kt)("li",{parentName:"ul"},"Wo sind die Gespr\xe4chsteilnehmer? Beispiel: \u201eW\xe4hrend dieser Kommunikation war Alice in Frankreich und Bob in Kanada.\u201c"),(0,i.kt)("li",{parentName:"ul"},"Wann hat ein Gespr\xe4ch stattgefunden? Der Zeitpunkt und die L\xe4nge der Kommunikation k\xf6nnen viel \xfcber die Art eines Anrufs verraten, z. B. \u201eBob, ein Regierungsangestellter, hat gestern Abend eine Stunde lang mit Alice telefoniert. Dies ist das erste Mal, dass sie kommuniziert haben.\u201c *Wie wurde das Gespr\xe4ch vermittelt? Ob eine Konversation \xfcber eine verschl\xfcsselte oder unverschl\xfcsselte E-Mail stattgefunden hat, kann n\xfctzliche Informationen liefern. Beispiel: \u201eAlice hat gestern eine verschl\xfcsselte E-Mail an Bob gesendet, w\xe4hrend sie normalerweise nur Klartext-E-Mails aneinander senden.\u201c"),(0,i.kt)("li",{parentName:"ul"},"Worum geht es in dem Gespr\xe4ch? Selbst wenn der Inhalt der Kommunikation verschl\xfcsselt ist, ist es manchmal m\xf6glich, einen wahrscheinlichen Kontext eines Gespr\xe4chs abzuleiten, ohne genau zu wissen, was gesagt wird, z. \u201eEine Person hat zum Abendessen in einem Pizzaladen angerufen\u201c oder \u201eJemand hat um 3 Uhr morgens eine bekannte Selbstmord-Hotline angerufen.\u201c")),(0,i.kt)("p",null,"\xdcber einzelne Konversationen hinaus versuchen wir auch, uns gegen Kontextkorrelationsangriffe zu verteidigen, wobei mehrere Konversationen analysiert werden, um Informationen auf h\xf6herer Ebene abzuleiten:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Beziehungen: Entdeckung sozialer Beziehungen zwischen zwei Entit\xe4ten durch Analyse der H\xe4ufigkeit und L\xe4nge ihrer Kommunikation \xfcber einen bestimmten Zeitraum. z.B. Carol und Eve telefonieren jeden Tag mehrere Stunden am St\xfcck."),(0,i.kt)("li",{parentName:"ul"},"Cliquen: Entdeckung sozialer Beziehungen zwischen einer Gruppe von Einheiten, die alle miteinander interagieren. z.B. Alice, Bob und Eve kommunizieren alle miteinander."),(0,i.kt)("li",{parentName:"ul"},"Lose verbundene Cliquen und Br\xfccken-Individuen: Entdeckung von Gruppen, die \xfcber Vermittler miteinander kommunizieren, indem Kommunikationsketten analysiert werden (z. B. jedes Mal, wenn Alice mit Bob spricht, spricht sie fast unmittelbar danach mit Carol; Bob und Carol kommunizieren nie.)"),(0,i.kt)("li",{parentName:"ul"},"Muster des Lebens: Entdecken, welche Kommunikation zyklisch und vorhersehbar ist. z.B. Alice ruft Eve jeden Montagabend etwa eine Stunde lang an.")),(0,i.kt)("h3",{id:"aktive-angriffe"},"Aktive Angriffe"),(0,i.kt)("h4",{id:"falschdarstellungsangriffe"},"Falschdarstellungsangriffe"),(0,i.kt)("p",null,"Cwtch bietet keine globale Anzeigenamenregistrierung und daher sind Personen, die Cwtch verwenden, anf\xe4lliger f\xfcr Angriffe, die auf falscher Darstellung beruhen, d. h. Personen, die vorgeben, andere Personen zu sein:"),(0,i.kt)("p",null,"Ein grundlegender Ablauf eines dieser Angriffe sieht wie folgt aus, obwohl auch andere Abl\xe4ufe existieren:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Alice hat einen Freund namens Bob und einen anderen namens Eve"),(0,i.kt)("li",{parentName:"ul"},"Eve findet heraus, dass Alice einen Freund namens Bob hat"),(0,i.kt)("li",{parentName:"ul"},"Eve erstellt Tausende neuer Konten, um eines zu finden, das ein \xe4hnliches Bild / einen \xe4hnlichen \xf6ffentlichen Schl\xfcssel wie Bob hat (wird nicht identisch sein, k\xf6nnte aber jemanden f\xfcr ein paar Minuten t\xe4uschen)"),(0,i.kt)("li",{parentName:"ul"},'Eve nennt dieses neue Konto "Eve Neues Konto" und f\xfcgt Alice als Freundin hinzu.'),(0,i.kt)("li",{parentName:"ul"},'Eve \xe4ndert dann ihren Namen auf "Eve Neues Konto" in "Bob"'),(0,i.kt)("li",{parentName:"ul"},"Alice sendet Nachrichten, die f\xfcr \u201eBob\u201c bestimmt sind, an Eves gef\xe4lschtes Bob-Konto")),(0,i.kt)("p",null,"Da es bei Angriffen mit falscher Darstellung an sich um Vertrauen und Verifizierung geht, besteht die einzige absolute M\xf6glichkeit, sie zu verhindern, darin, dass Benutzer den \xf6ffentlichen Schl\xfcssel absolut validieren. Das ist offensichtlich nicht ideal und wird in vielen F\xe4llen einfach ",(0,i.kt)("em",{parentName:"p"},"nicht passieren"),"."),(0,i.kt)("p",null,"Daher m\xf6chten wir einige Hinweise zur Benutzererfahrung in der ",(0,i.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," bereitstellen, um Menschen bei der Entscheidung zu helfen, Konten zu vertrauen und/oder Konten zu unterscheiden die m\xf6glicherweise versuchen, sich als andere Benutzer auszugeben."),(0,i.kt)("h2",{id:"eine-anmerkung-zu-physischen-angriffen"},"Eine Anmerkung zu physischen Angriffen"),(0,i.kt)("p",null,"Cwtch betrachtet Angriffe, die physischen Zugriff (oder gleichwertigen Zugriff) auf den Computer des Benutzers erfordern, nicht als praktisch verteidigbar. Im Interesse einer guten Sicherheitstechnik werden wir jedoch in diesem Dokument immer noch auf Angriffe oder Bedingungen verweisen, die ein solches Privileg erfordern und darauf hinweisen, wo von uns eingerichtete Minderungsma\xdfnahmen fehlschlagen."))}h.isMDXComponent=!0},5448:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/4-698e941dd333a7200cddec8d926e9ca9.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9dd8190d.76d06a78.js b/build-staging/de/assets/js/9dd8190d.76d06a78.js new file mode 100644 index 00000000..aa97ec48 --- /dev/null +++ b/build-staging/de/assets/js/9dd8190d.76d06a78.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2688],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),s=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(n),g=a,m=h["".concat(c,".").concat(g)]||h[g]||d[g]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=g;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var s=2;s<o;s++)r[s]=n[s];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}g.displayName="MDXCreateElement"},7561:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const o={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/de/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"24. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"autobindings",permalink:"/de/blog/tags/autobindings"},{label:"libcwtch",permalink:"/de/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/de/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/de/blog/cwtch-testing-ii"}},c={authorsImageUrls:[void 0]},s=[{value:"A Brief History of Cwtch Bindings",id:"a-brief-history-of-cwtch-bindings",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:s},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,a.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,a.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"a-brief-history-of-cwtch-bindings"},"A Brief History of Cwtch Bindings"),(0,a.kt)("p",null,"Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/therecipe/qt"},"therecipe/qt"),". However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework."),(0,a.kt)("p",null,"As part of early prototyping efforts for Flutter we built out a first version of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libCwtch-go"),", and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings."),(0,a.kt)("p",null,"This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape"},"experimental features")," - handle settings, ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings"},"duplication of logic between Cwtch and libCwtch-go"),", and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go"},"special behaviour in libCwtch-go that better belongs in the core Cwtch library"),"."),(0,a.kt)("p",null,"As part of a broader effort to ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"refine the Cwtch API in preparation for Cwtch Stable")," we have taken the opportunity to fix many of these problems."),(0,a.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,a.kt)("p",null,"The current ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockContact")," API implementation is:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"//export c_BlockContact\nfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\n BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\n}\n\nfunc BlockContact(profileOnion string, conversationID int) {\n profile := application.GetPeer(profileOnion)\n if profile != nil {\n profile.BlockConversation(conversationID)\n }\n}\n")),(0,a.kt)("p",null,"All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively."),(0,a.kt)("p",null,"In the new ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings")," we reduce these multiple lines to ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19"},"a single one"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"profile BlockConversation conversation\n")),(0,a.kt)("p",null,"Defining a ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"-level function, called ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockConversation")," which takes in a single parameter of type ",(0,a.kt)("inlineCode",{parentName:"p"},"conversation"),"."),(0,a.kt)("p",null,"Using a similar boilerplate-reduction for the reset of ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," yields ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format"},"5-basic function prototypes"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateProfile")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"BlockConversation")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"GetMessage")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"DownloadFile")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareFile"))),(0,a.kt)("p",null,"Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec"},"described in fewer than 50 lines, including comments"),". Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.)."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments"))," (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on ",(0,a.kt)("inlineCode",{parentName:"li"},"cwtch-server"),"). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart-side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch API"),": This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the ",(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"Cwtch Stable API redesign"),". In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9e2a7473.b8282671.js b/build-staging/de/assets/js/9e2a7473.b8282671.js new file mode 100644 index 00000000..6118b174 --- /dev/null +++ b/build-staging/de/assets/js/9e2a7473.b8282671.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1258],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),c=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return i.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),u=a,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var c=2;c<o;c++)r[c]=n[c];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},8725:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var i=n(7462),a=(n(7294),n(3905));const o={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/de/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"13. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"},{label:"api",permalink:"/de/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/de/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/de/blog/path-to-cwtch-stable"}},s={authorsImageUrls:[void 0]},c=[{value:"Clarifying Terminology",id:"clarifying-terminology",level:3},{value:"Tenets of the Cwtch API Design",id:"tenets-of-the-cwtch-api-design",level:3},{value:"The Cwtch Experiment Landscape",id:"the-cwtch-experiment-landscape",level:3},{value:"The Problem with Experiments",id:"the-problem-with-experiments",level:3},{value:"Restricting Powerful Cwtch APIs",id:"restricting-powerful-cwtch-apis",level:3},{value:"Pre-Registered Hooks",id:"pre-registered-hooks",level:4},{value:"<code>ProtocolEngine</code> Subsystems",id:"protocolengine-subsystems",level:4},{value:"Impact on Enabling (Powerful) New Functionality",id:"impact-on-enabling-powerful-new-functionality",level:4},{value:"Application Experiments",id:"application-experiments",level:2},{value:"Bindings",id:"bindings",level:2},{value:"Timelines and Next Actions",id:"timelines-and-next-actions",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2},{value:"Appendix A: Special Behaviour Defined by libcwtch-go",id:"appendix-a-special-behaviour-defined-by-libcwtch-go",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,a.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,a.kt)("p",null,"As we move out of Beta and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,a.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(4867).Z,width:"1005",height:"481"})),(0,a.kt)("h3",{id:"clarifying-terminology"},"Clarifying Terminology"),(0,a.kt)("p",null,"Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch")," refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtchlib")," refers to the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"reference implementation of the Cwtch Protocol")," / Application framework, currently written in Go."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Bindings")," refers to C/Java/Kotlin/Rust bindings (primarily ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libcwtch-go"),") that act as an interface between Cwtchlib and downstream applications."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.")),(0,a.kt)("h3",{id:"tenets-of-the-cwtch-api-design"},"Tenets of the Cwtch API Design"),(0,a.kt)("p",null,"Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Robustness")," - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Completeness")," - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Security")," \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.")),(0,a.kt)("h3",{id:"the-cwtch-experiment-landscape"},"The Cwtch Experiment Landscape"),(0,a.kt)("p",null,"A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Groups")," \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Hybrid Groups")," - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Server Hosting")," \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Message Formatting")," \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search / Microblogging")," \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status / Profile Metadata")," \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.")),(0,a.kt)("h3",{id:"the-problem-with-experiments"},"The Problem with Experiments"),(0,a.kt)("p",null,"We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"SendMessages")," interface that only allows callers to send messages."),(0,a.kt)("p",null,"We have also worked to package experimental functionality into so-called ",(0,a.kt)("strong",{parentName:"p"},"Gated Functionalities")," that are only available if a given experiment is turned on."),(0,a.kt)("p",null,"Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"SendMessages")," \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing)."),(0,a.kt)("li",{parentName:"ul"},"The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality."),(0,a.kt)("li",{parentName:"ul"},"This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.")),(0,a.kt)("h3",{id:"restricting-powerful-cwtch-apis"},"Restricting Powerful Cwtch APIs"),(0,a.kt)("p",null,"To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through ",(0,a.kt)("inlineCode",{parentName:"li"},"Application")," and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile."),(0,a.kt)("li",{parentName:"ul"},"Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a ",(0,a.kt)("inlineCode",{parentName:"li"},"RestrictedCwtchConversationInterface")," which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact."),(0,a.kt)("li",{parentName:"ul"},"Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," to control which experiments get access to which events at a given time.")),(0,a.kt)("h4",{id:"pre-registered-hooks"},"Pre-Registered Hooks"),(0,a.kt)("p",null,"In order to implement certain functionality actions need to take place in-between events handled by ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),". As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group)."),(0,a.kt)("p",null,"This is currently only possible with invasive changes to the ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort."),(0,a.kt)("p",null,"We are introducing a new set of Cwtch APIs designed for this purpose:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnNewPeerMessage")," - hooked prior to inserting the message into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnPeerMessageConfirmed")," \u2013 hooked after a peer message has been inserted into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEncryptedGroupMessage")," \u2013 hooked after receiving an encrypted message from a group server."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnGroupMessageReceived")," \u2013 hooked after a successful decryption of a group message, but before inserting it into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactRequestValue")," \u2013 hooked on request of a scoped (the permission level of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"public")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation")," level attributes), zoned ( relating to a specific feature e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"filesharing")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"chat"),"), and keyed (the name of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"name")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest"),") value from a contact."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactReceiveValue")," \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.")),(0,a.kt)("p",null,"Including the following APIs for managing hooked functionality:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the extension is interested processing."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," - returns a set of experiments that the extension is interested in being notified about"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," - to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (assuming all experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," is active)")),(0,a.kt)("h4",{id:"protocolengine-subsystems"},(0,a.kt)("inlineCode",{parentName:"h4"},"ProtocolEngine")," Subsystems"),(0,a.kt)("p",null,"As mentioned in our experiment summary, some functionality needs to be implemented directly in the ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),". The ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus)."),(0,a.kt)("p",null,"Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),"."),(0,a.kt)("p",null,"At the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," ecosystem. "),(0,a.kt)("p",null,"We are formalizing this subsystem into an interface, similar to the hooked functionality in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the subsystem needs to consume to operate."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," \u2013 to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (when all the experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," are active)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterContexts")," - returns the set of contexts that the subsystem implements e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"im.cwtch.filesharing"))),(0,a.kt)("p",null,"This also requires a formalization of two ",(0,a.kt)("em",{parentName:"p"},"engine specific")," events (for use on the event bus):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SendCwtchMessage")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage")," that is used internally in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," for messages between subsystems."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchMessageReceived")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.")),(0,a.kt)("p",null,"And the introduction of three ",(0,a.kt)("strong",{parentName:"p"},"additional")," ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEnine")," specific events:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StartEngineSubsystem")," \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StopEngineSubsystem")," \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SubsystemStatus")," \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging")),(0,a.kt)("p",null,"This will allow us to move the following functionality, currently part of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," itself, into generic subsystems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Attribute Lookup Handling")," - this functionality is currently part of the overloaded ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function, filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter of the ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage"),". As such it can be entirely delegated to a subsystem. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Chunk Request Handling")," \u2013 this is also part of handlePeerMessage, also filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage"),")"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Start File Share/Stop File Share")," \u2013 this is currently part of the ",(0,a.kt)("inlineCode",{parentName:"li"},"handleEvent")," behaviour of ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," and can be moved into an ",(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," handler of the file sharing subsystem (where such events are already processed).")),(0,a.kt)("p",null,"The introduction of pre-registered hooks in combination with the formalizations of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," subsystems will allow the follow functionality, currently implemented in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," or libcwtch-go to be moved to standalone packages:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Filesharing also depends on the file sharing subsystem to be enabled in a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),". This subsystem is responsible for processing chunk requests."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Legacy Groups")," \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status/Profile Metadata")," \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.")),(0,a.kt)("h4",{id:"impact-on-enabling-powerful-new-functionality"},"Impact on Enabling (Powerful) New Functionality"),(0,a.kt)("p",null,"None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search")," \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Non Chat Conversation Contexts")," - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.")),(0,a.kt)("h2",{id:"application-experiments"},"Application Experiments"),(0,a.kt)("p",null,"One kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers."),(0,a.kt)("p",null,"This kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library."),(0,a.kt)("p",null,"This functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface."),(0,a.kt)("h2",{id:"bindings"},"Bindings"),(0,a.kt)("p",null,"The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications."),(0,a.kt)("p",null,"We can split the bindings into four core areas:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Management")," - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Experiments")," - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Core Profile Management")," - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Experimental Profile Features")," \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.")),(0,a.kt)("p",null,"The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings."),(0,a.kt)("p",null,"In an ideal future, all of these bindings could be ",(0,a.kt)("strong",{parentName:"p"},"generated automatically")," from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)"),(0,a.kt)("p",null,"We can define three types of C/Java/Kotlin interface function templates:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileMethodName(profilehandle String, args...)")," \u2013 which directly resolves the Cwtch Profile and calls the function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileExperimentalMethodName(profilehandle String, args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ApplicationExperimentalMethodName(args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.")),(0,a.kt)("p",null,"All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ",(0,a.kt)("inlineCode",{parentName:"p"},"ProfileInterface")," for the first, exported methods of the various ",(0,a.kt)("inlineCode",{parentName:"p"},"Functionalities")," for the second, and ",(0,a.kt)("inlineCode",{parentName:"p"},"ApplicationExperiment")," definitions for the third."),(0,a.kt)("h2",{id:"timelines-and-next-actions"},"Timelines and Next Actions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Freeze any changes to the bindings interface")," - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib."),(0,a.kt)("li",{parentName:"ul"},"As part of Cwtch 1.11 and 1.12 Release Cycles",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Implement the ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," Subsystem Design as outlined above."),(0,a.kt)("li",{parentName:"ul"},"Implement the Hooks API."),(0,a.kt)("li",{parentName:"ul"},"Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting)."),(0,a.kt)("li",{parentName:"ul"},"Move event handling from the bindings into Application."),(0,a.kt)("li",{parentName:"ul"},"Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions."))),(0,a.kt)("li",{parentName:"ul"},"Once Automated UI Tests have been integrated into the Cwtch UI Repository:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings ",(0,a.kt)("strong",{parentName:"li"},"and")," a dart calling convention library from cwtchlib and any configured application experiments libraries"),(0,a.kt)("li",{parentName:"ul"},"Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process)."),(0,a.kt)("li",{parentName:"ul"},"At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.")))),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})),(0,a.kt)("h2",{id:"appendix-a-special-behaviour-defined-by-libcwtch-go"},"Appendix A: Special Behaviour Defined by libcwtch-go"),(0,a.kt)("p",null,"The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application Settings",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Including Enabling / Disabling Experiment"))),(0,a.kt)("li",{parentName:"ul"},"ACN Process Management - starting/stopping/restarting/configuring Tor."),(0,a.kt)("li",{parentName:"ul"},"Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)"),(0,a.kt)("li",{parentName:"ul"},"Logging Levels - configuring appropriate logging levels (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"INFO")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"DEBUG"),")"),(0,a.kt)("li",{parentName:"ul"},"Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled."),(0,a.kt)("li",{parentName:"ul"},"UI Contact Structures - aggregating contact information for the main Cwtch UI."),(0,a.kt)("li",{parentName:"ul"},"Group Experiment Functionality",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Experiment Gating"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfoList"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfo"),(0,a.kt)("li",{parentName:"ul"},"UI Server Struct Definition"))),(0,a.kt)("li",{parentName:"ul"},"Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients."),(0,a.kt)("li",{parentName:"ul"},'"Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".'),(0,a.kt)("li",{parentName:"ul"},"Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled)."),(0,a.kt)("li",{parentName:"ul"},"Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Profile Engine Activation - starting/stopping a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," when requested by the UI, or in response to changes in ACN state."),(0,a.kt)("li",{parentName:"ul"},"UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event."),(0,a.kt)("li",{parentName:"ul"},"File sharing restarts "),(0,a.kt)("li",{parentName:"ul"},"UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting ",(0,a.kt)("inlineCode",{parentName:"li"},"handle")," to a ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation id"),"). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself."),(0,a.kt)("li",{parentName:"ul"},"Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)")))}d.isMDXComponent=!0},4867:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9e4087bc.582408aa.js b/build-staging/de/assets/js/9e4087bc.582408aa.js new file mode 100644 index 00000000..6b05be93 --- /dev/null +++ b/build-staging/de/assets/js/9e4087bc.582408aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3608],{3169:(e,t,a)=>{a.r(t),a.d(t,{default:()=>o});var r=a(7294),l=a(9960),n=a(5999),c=a(1944),m=a(7961);function s(e){let{year:t,posts:a}=e;return r.createElement(r.Fragment,null,r.createElement("h3",null,t),r.createElement("ul",null,a.map((e=>r.createElement("li",{key:e.metadata.date},r.createElement(l.Z,{to:e.metadata.permalink},e.metadata.formattedDate," - ",e.metadata.title))))))}function i(e){let{years:t}=e;return r.createElement("section",{className:"margin-vert--lg"},r.createElement("div",{className:"container"},r.createElement("div",{className:"row"},t.map(((e,t)=>r.createElement("div",{key:t,className:"col col--4 margin-vert--lg"},r.createElement(s,e)))))))}function o(e){let{archive:t}=e;const a=(0,n.I)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),l=(0,n.I)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),s=function(e){const t=e.reduceRight(((e,t)=>{const a=t.metadata.date.split("-")[0],r=e.get(a)??[];return e.set(a,[t,...r])}),new Map);return Array.from(t,(e=>{let[t,a]=e;return{year:t,posts:a}}))}(t.blogPosts);return r.createElement(r.Fragment,null,r.createElement(c.d,{title:a,description:l}),r.createElement(m.Z,null,r.createElement("header",{className:"hero hero--primary"},r.createElement("div",{className:"container"},r.createElement("h1",{className:"hero__title"},a),r.createElement("p",{className:"hero__subtitle"},l))),r.createElement("main",null,s.length>0&&r.createElement(i,{years:s}))))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/9f1c7621.9a518122.js b/build-staging/de/assets/js/9f1c7621.9a518122.js new file mode 100644 index 00000000..6b17c26e --- /dev/null +++ b/build-staging/de/assets/js/9f1c7621.9a518122.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1312],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>g});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function s(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(a),h=r,g=d["".concat(p,".").concat(h)]||d[h]||u[h]||i;return a?n.createElement(g,o(o({ref:t},c),{},{components:a})):n.createElement(g,o({ref:t},c))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var l=2;l<i;l++)o[l]=a[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},4387:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/de/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"17. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"support",permalink:"/de/blog/tags/support"},{label:"testing",permalink:"/de/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/de/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/de/blog/cwtch-android-reproducibility"}},p={authorsImageUrls:[void 0]},l=[{value:"Constraining Cwtch UI Fields",id:"constraining-cwtch-ui-fields",level:2},{value:"More Automated UI Tests",id:"more-automated-ui-tests",level:2},{value:"New Release of Cwtchbot",id:"new-release-of-cwtchbot",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:l},d="wrapper";function u(e){let{components:t,...i}=e;return(0,r.kt)(d,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,r.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6097).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraining-cwtch-ui-fields"},"Constraining Cwtch UI Fields"),(0,r.kt)("p",null,"Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3785).Z},(0,r.kt)("img",{src:a(6561).Z,width:"410",height:"90"}))),(0,r.kt)("figcaption",null,"Screenshot demonstrating how certain strings would violate the bounds of their containers.")),(0,r.kt)("p",null,"These cases were fixed by parenting impacted elements in a ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"clip: hardEdge")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"decoration:BoxDecoration()")," (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration)."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3551).Z},(0,r.kt)("img",{src:a(9812).Z,width:"427",height:"76"}))),(0,r.kt)("figcaption",null,"Now these clipped strings are tightly constrained to their container bounds.")),(0,r.kt)("p",null,"These fixes are available in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"latest Cwtch Nightly"),", and will be officially released in Cwtch 1.11."),(0,r.kt)("h2",{id:"more-automated-ui-tests"},"More Automated UI Tests"),(0,r.kt)("p",null,"We have added two new sets of automated UI tests to our pipeline:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"02: Global Settings")," - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628"},"PR: 628"),")"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"04: Profile Management")," - these tests check that creating, unlocking, and deleting a profile work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632"},"PR: 632"),")")),(0,r.kt)("h2",{id:"new-release-of-cwtchbot"},"New Release of Cwtchbot"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"Cwtchbot")," has been updated to use the latest Cwtch 0.18.10 API."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},3551:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png"},3785:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},6097:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"},9812:(e,t,a)=>{a.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAasAAABMCAIAAABcRQ+0AAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO2deUBU57n/n3Nm34cBZhiYYVhkXwURxAV0kLggauK1McSkadIm2i1tr/mV5N70Nm1q9zXVtvc2aWLV2zSrsTFBiGiMYECibAIjwjBsMwPD7Ps55/4xhhIYYVhC7C/vR/+YOed93+/zDMzDe97lebHnD+4FBAKB+PxR06nFP2sbEAgE4jMDRUAEAvH5BUVABALx+QVFQAQC8fkFRUAEAvH5hf7pNS2JUUkUKpEsRhApE4RL2QIhmy+iMRgAQPh8brvFbbPaxg02o96iHzINak1D2k/PGAQCgZjJEkdABostT8mUrUiTxidLE5Jvq8pk8iWRfElkhCpx8qLhZo+hr0d/4/pId7vP415awxAIBGImSxYBxXJFbHaBMitPGn8r8Fmt1qampra2tp6eHq1Wq9frLRaL2+0GADabLRKJoqKiYmNjk5OTc3JyioqKpAnJ0oTkTHWFoa9H19Yy0NpkHhlcKvMQCARiJksQASUxqvj84ri8ImFkFADodLrTp0/X1tZevnz5dlXcbjeO426X++rVq3Q6vXRtiQQTSIQSM9glsvCY+GRpfHLSmtL+lsa+K5fQ0zECgfiUWFQEZPH4SWs2Jq0pFUcpAKCuru748eM1NTVzVuRxeU8+/sSHHzW9eea0ShH75aqHaGZK3zfYbun56R9+UVS8pqqqSq1WZ9+1KzZnlaahXtNwzuOwL8ZUBAKBmMnCI6AiIzd5bZkqpwAA6urqjhw5Mkunbyo4hlduqViZkD1hmWCz2dvLt0VwJGatEaPhToeDpKiampqamprCwsKDBw+q1eqC3fdLE1J6Pqgd7Li6YGsRCARiJguKgBiWXro1vXSrIEKq0+kOHz586tSp0Guz2exdm7a7BqxZaZkRYeEbVq91jdpJH0HDMLvdQVJkoNjly5cvX75cWVlZXV2tyimQxKg668901p8BilqIzQgEAjGDea8H5AhEBburCvc8KIiQnjx5ctOmTfMKfwCQkZrO93AoP8VhsMPDw8P4Iq/NAwCAgZ/wU58McKdOndq0adPJkycFEdLCPQ8W7K7iCETztRmBQCCCMr8IKIiQ5e/cl6neAQDV1dWHDh1yuVzzlcxITfdYXEABHaOnJaXQKBrpJwAAo+Eur5skyGnlXS7XoUOHqqurASBTvSN/5z5BhGy+oggEAjGTeURAQYRs5bY9SWs2Wq3WqqqqY8eOLUySz+H53X4KKBrQlDEK0k9SBAUANB5DNzro8/uC1jp27FhVVZXVak1as3Hltj0oCCIQiMUTagTkCEQ5W3YnFm4wGAz79u07f/78wjUxAIoCCiiSxHEa6SOAojAa7mX4R8f0JDm9DzjJ+fPn9+3bZzAYEgs35GzZjR6HEQjEIgktAmJY5uYdgd7fQw89dO3atcVIerwenEEHDEggHQ4H4fYDAI1B09uMo0b97HWvXbv20EMPBXqCmZt3AIYtxhIEAvE5J6S54PTSrYGxvwMHDiwy/AFAt6Zne5Ka9GMYEzebLaSfBAAan3GpsdFiscxZ/dq1awcOHDh+/HimeodjwtR57u1F2rMMVBx6Vhgpsxr1vU3vX69/Z9rdtJIteTv2ep1OfW9Xa80bQXfCzN5CgHt//CegqHFdf9f7Nbq2KzMLhCK0/oGvxmbnO80Tuo6W5tePf7ZCc3q9bEKheB2KEOJOA5szS74iI7do78OCCGl1dfWCx/5uiWFYrCK2vFR9f8W9gGMjFsMrb7zy8Ob9jhGrV0z+6MVftF/vCLGp/fv3Hz582DZmaHz5z2idIAKBWAA1nVrazoKMWUqwePyV2/dKE5JPnjz585//fDFiXA73sS9++dDXvpOfk8fksegsukDAz8/Jo9yE3+Vr13efOV/j9XlDbK21tVUul+cXFtGZ7OGuViLkistP6vry9Q9+NXX9ZtuY3jamX1v1aNHehzQN50i/P1Bgyzf+M0NdIU/O6P+okS0Q3f2fvxRFxejaW0JvAQDWVj2at+PepMKSnkvvAcC2b39/RVHpjcb6qZbMKcQWiHY88aPU9Zs5QvGopjNx9YZtj3/PaTFNDA0sv1AoXi+b0JxehyKEuNPoNVrmGAdMWrNRlVOg0+mefvrpxSiJheIfP/3DL+z+NwGfz2AwAhdpOI3D4fAVIjyKdfGjBvs89709/fTTOp1OlVOQtGbjYmz7tJEmJBn7NKTfF5dXlLxWHZ9frO/t9rn/uYqIIwrrvlgrT84AgI0PP85gc9rOnppXCwAgUcR1XXhXEBmlylldtPehyPik/pbGaZbMKaTIyPV53KbB/pj03AhVYl7FXrvJ2Pvh+5+JUCheL5vQnF6HIoS4A5mtDyiJUeVVfoHNF1ZXV3d0hPp8OhOhQPCT7z27MnsljUabeRej4Xaf4/W33xwzjc+rWb/fbzQat2/fzguTGHq7Xba5xxA/E5xWszIzT5aYQni9SWtKR7ra6v/866kFuCJx2oa7KJJMXb+ZFxZ++dUXRzWd82oBACiCSN1QzhWJBREyRUZux3v/aH33jWll5hQyDWplK9Jis1f5ve7U9eUep+3Ci8+5P/nBLptQKF4vm9CcXocihLjT6DVaZpsJic8vFkcp6urq5rvrYyocNuc/vl2dlZ6F47f6myRFulwuDpszeSVCEpGfk9d9Q0PNc8fbqVOn7rnnHrVaHZ9ffMemkDH2aVg8vtflwOn05jdPzBxod1ktDA7H63Qa+28EHc6fswUA0DTW5++6z+d2eV3O+ud/E3Sofk6hj6FwnKZpPBd0OH/ZhELxetmEQvF6TiHEHchtn4LFckVcXhEAHDlyZOGt43jllor83Lypvb9uTc+2vZVdvT2TV+h0+oqEFRw2ZwESAfPi8orEcsWC7fy0Of2zp0488cjpnz0V9NsVt7KQ8PkmhgcuvPicY2L8337w3NqqR6cWYAtEbL6AJIjRno7r9e8krl5f9fPnpz37p67fTBEESRKaS+/p2q4U7/vy3mePMD75kYYiJEtMIXw+XduV5tePL1goLFrp93r9Xs+FF58zjwxu+9b3t3/nmWle8yURhM9nG9M3v36cwebMNCZ1/WaeWOL3edvPnrpe/86nJxTKx1u878sUSXoc9rNHDuvarixMCHEHctsIGJtdIIyMqqurmyXjC5POwD4Gx3E6bXqPUiQUbd5YxuVwp14Ml0iy0jP5XN4nmmIwJ7uE8+Ly5ct1dXXCyKjY7IIFVA+Rgrv3P/T7v2WoKyavMBYUr4Miliu73j8rW5EKABsf+RaLyw8Mt0+SuGotRZLGPk10WrZQKs/dtsdlNWsazk0tI0/NGh/s97ndsTmr4vOLE1atHdfenDaYtWxCssRUTcM5niQicfWG/J37IhOSZs7Xz2nMsgmF4vWSCCHuQIKPAzJY7LwdX+CFhf/whz/s7e0NWpNBZ5Tnlo5M6EVcEZvBihSFKyNi9GbjZAEMw1TK2B2bttK8OI1Fn9z7wePytm3eKhJ+YkfHlWstzVev+HzBt8TNjtPp3LlzJ53J7L/SQBL+uSvcntIvfXPjI9/O2lzZc+k9v9czeT0mLUeakDx0vdXY1wMA6+5/rOSL3+AIRIMdHy1GLoAwUhafX4wBJKxaFxYde+XNkwPXmqYWMI8OylMyZStSCa83ZZ0aKOrCS793mk1Ty5B+nzw5U6JQEV5v0pqN47q+s0cOf1ZCTDZXtbKIKxKzuLz4vCLNpXPNb56YrzHLJhSK10sihLjTuO04oDwlUxqfrNPpZkl3KuYKB8dHwngiuUTOoNH8pL9d2zW1AIvB5DO5tkELU4AzeEygKDqbEbQpDIMNGzb0Dw+8U/Ouw+GYrxs1NTU6nU4ZnyxPyRxobZ5v9alExie57TY2X5Cprmh+47ZDOSRBkISfJInFaE0yMayLW1nkdTmshuELL/5u5mCWz+1y26wUSQJAf0vjh6++NLORgdbm7PJdHocdp9Gv/uPvHcEWii+bUGvNG2mlW1wWMwDUP/+boD+UOY1ZNqFQvF4SIcQdSPAV0QV3789UVxw9evTZZ5+9XU0eiwsAHp/HTxLKiJgwnqhD1018HBQwwBh0RkJs3H8eeiohLp4iKYqiaIxgc8EYxuaxxZFhhjHj95/5QcPlhgmLeZbdwUF56qmnDhw40F53uum1ha/ZTly9YcMDBzvqz6SsVZtHBt/66ZOTtwIfyIevHeuoO73g9hEIxCJRZuZt+OLXZxuDoqih69fOHvlxKK3VdGqD9wEDpx3V1tbOUtnhcU6+HhofzkvLHTbrxyy3VrRQQPkJvzRalpieyKaxvG5vIAXWNDAMY3JYwnARRsNFAtG3HvtGcV5h7du1A/pBrUHnI0J9KK6trT1w4MDkIU0LI2FVsd/n7ag9LUtMDYtW8sThDvP8FujMl9xtexJXr+cIRDQG0+tyWEaHm988YbjZPbXM+ge+Kk/OYPH4GIZ7nHb9jesfnPjT1OGwcGV8we77xXIFi8snCL/bbu1rvnTl1MlPuFawLqtsBy8snMHh+t1uh3m84723pw11LZvQkni9bEKheL0kQoiQwDAAwD5+MZP5ricJMg4oiVHlV95rtVqffPLJoHVmguO0L6mrGrubHe5/PsNSQK1cuXLLXVuEYSIGk4HTaDgGGAYYjuM4TqPRmGwmT8QXSIR0Bt3v8o1r9DQ6TRUbmx6elB2TzsDpPcO9IfozNDT0yCOPSKKiB641LXhhYOGeBy36kY73TovlClliKgA1dL01cGvaOGDB3fvv+tpTPo878BYAMtUV6x84uGrXfbnb7klZV8bkcAML01YUlZR88RsFu+/P2bI7Pr/YY7OaR4cCVdbc+0iWugIADH09Y9peoEAan6TMzu9rvjT5xdj+nWeUWfkeh83Q220eHWSyufLkDHlyxuQQO1sg2vat/5JEx1oNI/ob151mE18SochYyRNLJldsrCgqWVv1KJsvHBu4abzZ7XW5JApVbHaBc2LcNNi/zEJL4vWyCYXi9ZIIIULEahhpq3kTp9GiVqTNvGsbN5x44uGbTRdDbC34OKBEoQKApqYgg7gsBksiCJuwmT0+T2D+N1oSpTMOifnCmNgYu3v6EN7Q0LDX66WJaBwBl83jUCRJEiQFt4IajU7HaTiGgc/pHWrp9xE+tpRPo9NkGTHimHAhV9A9fKNjoGuGFcFpampSq9UShWphCwOzNley+cLui7UA0HWhJnXd5qik9BDr5lfuy9y8w2oY7WtpoDOYQqnc7/MCQOLq9cX3PmI3jd24fJ7OZCszVxbf92XT8IDVMMIWiBJWrXXZrbVHfzKmvTXXtPqeBzI2bc/fdd+Fv/wOAFLXl0fGJ49pe6c+j299/HuyFWmp68u73q8BgMJ7HuCKwjQN5y7+9Q+BAoII2dZvPh2XV/Tha8cC38CMTdsxDG98+fmAdwAQl1e04YGvpW/cqmmsX06hpfJ62YTm9HqphBCfFUEWoIhkMQDQ1tY28xaHxU5XJCdGqVYmZCXI4nLjMyMEEsDgi/seEIaLD3zpK4poBYP+z+kOl8tFkiSGAYYBTsNoDBqDzWCwmEw2k8li0ug4hgHhJQxdI5aRCZxFx2k4ANA5DF6UICJOujo9Hws5/1XA4IDxC0CZme9zuwJ7qqyGEYthWCxXhJKHlcHmJK/dZNWPvP6Db188drT++d+c+vF322reBIBMdYXP7Xr7V//V8L9/fv+l3ze/cYLJ5WdtrgQAZcZKJoc72N4y+bUBgA9ffclls4hl0YG30oRkDMMCTU1y9cyrGIZFxq0IvBVFKTwO2+T3EwBsY3pdewuTw1Nm5Qeu8CWRpsH+yWABAP0tjeO6m3xJ5DILLZXXyyY0p9dLJYT4rAjSBxREygCgp6dn5i2/3+/xe8dtE06PM4wvlvDF73c2UhRVuqGUB9zKrRXFq4v6tP3Xe7qGRoa5XO72u7byeXygAg/uH0NRgGEURQWiG+EjTH1jOJvOELAAA6CAAgrDMGG85AsP3vth/9WOrpA25AUMDhg/X9gCkUQZ57Ka8ypuzQt5XU4ag5leuuXyKy/OXjc+bw2bL+xrvjTzllAqNw32T/6Wu2wWn9spCJcCgFAmBwCLYaTi0LNh0cqJYd3pnz0FAB67jcUTBMpzhGLC7/N53Hu+/1u2QKRru3L+hd+OdLf7vR6OKCxQhsXjue223G170jaUA4Zfrz9z9cyrZv0QAITJFQDAYHOYbI7TMlH6pW8qMlZ6nPb3Xzoyqul0mici45PZApHbZlk2oSXxetmEQvF6qYQQnxXBImC4FAC02iDPkk6P63J3M0GSJEV6/F6nx+32eQCg+4OOtqFOVXLCuqLiNQVFq1bmE34Cx3Emk2nXW3wmN1fCp7PogGE4HSP9BE6n+VxeigS73uq2OAmfz2vxskRsBp/lGLYKYkV0DhOn417Ce+PmjRA9CRgcMH6+ZJXtYLDYjMio9I3bpl6XrZj7QTgsWgkATsvEtOsRqkQ6kyVNSCl77IlP3MAwAHDbbQAQrojjhYU3vf7Xor1fUmbl69qukIQfp99aK+5zu2g0etKaUpfNou/tVmTkBq6TBEGj3/rB+b1eJoerzMofaG2WKOMVGSuvnnnV7/EAAJ3JCjRC+H1MLk8cldz0+l/zKvYmrFo7qukkCD+GYRyhyG2zLJvQkni9bEKheL1UQojPiiA/ALZACAB6fZB0zSRFTp5k5PF5x3zjgf5aJFPyRu1p77u+438/cf/eqvVFxXweHwAoijJeH3UZ7BiG0ZgMDAcmj9XVc1Mg5HExJpvJYgvZOIcuTpVatSazZgwoABwEKnFAok/b75myLHl2AgYHjJ8v8pQsr9Nx/NCXpl7c+eRPxfIYoVRuNYzMUtfrcgIAVyyZdn1M20v4fKbB/tM//4+ZtfqvNKzadR9bIHKYxgr3fJGiSJOuf1qZiRGdKne13+flCETSuCTbuGFmOw6TUZSafbPp4orCDWyBaKgzSKpEp2VCECEd6W4vuHs/g8WeOVO0bEJL5fWyCc3p9VIJIeYF9zZ9ZwZr3ju1gowDsvkiAAglXfOtOQ0KXqg9YXFYXW7XTW3fj3/9k8f+/evvvFfjcDr8Th9OYkABRsO9To/b4jIOjz3/xitHThzXG8YooMLSZMKEMDqXIUqMYIdxSYIEDAscnAQAVrstdE8CBgeMnxfhyvgwuWL84znESYx9GhqdkV66dfJK0H17+t5ukiTkKZkzb9lNxrCY2Ljcwpm3HOZxt80qiJB2f1BHkcSYtnfmypvBjo+Aonji8KHOa4Bhw11BRmYt+mEMx0mSsBpHSZK4ESwdk2NinCsM63r/rNflcNss7bVvfVZCS+X1sgnN6fVSCSHmhSzYRDAAsHn83G175tXU9D4gTqPTGAwAcLvdITZBAXW+44NbrynK4/X29vX+8Oc/kkvlD27fv/WebQwZVxAlcgxZTd16sZC3d/s2h8eTvjadJ+VRtFtjhDQmLSwtksLBqbfpm3V2iZchYB9/ZfrGo1kIGExjBN92MgtpJXfhdPrMP++axvqk4o2BbZ7OiXEAiM1eRZLktEXRw12toz2d0alZO5/82WhPO+H3SxRxoz0drTVvtNedLtr70NqqR2NzCiz6YUGETCSTf3DiT4HdAm67VSxXFN/7iMdpb3rtrzMNM/ZpfB63LDElOiVzTNt76eR/zywzMawDgPTSrXQmS9NQH3QdgNNswnB888HvYhje/MbxmWvQlk1oqbxeNqFQvF4SIUQoMNicFYUlyWs3CSOjgpfAsKzNlbyw8N4P35+WJ+12hDQMwWFycuIzbE6bZqTPR/hSFUl8FtdgHR8cGyYpksNkS0URTo9LzBPRcPz6oIaiKD9BOK3e02fqm5s6FdFycYSYw2fTSVwVpizasprDZc/sT2E4Pu60vnOxXszl/e3yyw/ed39Pb6iDgItBlpjqdTqmZdYEAGOfxmbUi2UxYTGxHefejssriohNFETIej6om1by3d/9cOPD35IlpaWW3EX6/U6zaQQoAOj5oI7weTPLdigz8+JXFRNer21MLwiXBiKg3+vBcZrZMNT48vPTVs9OQvi8DJZwqKvt3P/8MmgBx8Q4AGAYfv38u40vPx+0jM/jDshdPfPq7Q7BWDahJfF62YRC8XpJhBChkLW5MmfL3bOXoTNZycWb5CmZrzz99VDaDLIrbv+vjtGZzKSkpMnT0MU8UWZs2pBpWMAR8FhcwEDAEdwc7ZOHRdndjhiJvN84MDox6vX5IoXhvXotANBp9F2F29anrdNZjG2abrvDwefxKRqFAQYYJhYLv/zYfTw+FwAIggAA0u23DZgtw+Y/nXpFbx4fsfV7KIdrPivmORyORqPxe73HvrU/9FoIBOJfhbwdX5gzAgawjRtCiYDBd8W57Ra+JFIkEgUiIIZhXr+3TdvpI/wDxiEcwwUcPo7jE3az1jBIARUbqRi3ToxZJwDA6rqV6V4eJtuQXRwtkSpk0tWJaeMWy5jFzIrkuq1unoRPY9Id3RNevsND+j648pFSFBkjiqAIkoHT0lSJ4zZzOEfWPxHqWugAIpEoYPy8aiEQiH8VWt76W/f7n9iqm1VemVayxT5ufPuX35t6nQg5R1SwCGiz8iWRMplsdHQUACiKcnpcALe6YwQQJvvE5GsAqPnoPZf3E4OGDBojOy5j3GSz273x0dFMBjM6WhYVGY4z6DQ5nUbHSYIk/CRh99Hp2Nq0bMLlB5ICDAOKSlclfNjV6ifYAlaY2T0WohsAIJPJAsaHXgWBQPxrMW2iKZDRhwJqwVv4g0xuBmbrVSpViE1MC38AECkKX5dW1Nnfe+1Gl8ftZQvY/AgBjUGnCNI1YbcbrWaD2WQw2SfsLpPDPeH0ON2EnwCKAoBwkYjL5mCASbhSHJtHztSAwWipAQKBCJ0gfUCbUQ8AyckLzLPCpDPyE3NVUkUYX+Lxer0+H0mRkSlyl9XlmXAAgM/vr7/aPDRmyEtOV0RIO7W941bL6tRMeXgEBsCg0fKS0t776DILuAJmmMUTamgPGBwwHoFAIEIhSAS06IcAICsra2EthvHFG7PWEQTJpNFrWxspitrF2eSt66Azb2kNj49d6rhKUuSIySgLCx80jpIUhWP49qJ1NBwHgBRF3IXWK36CCOfJbN4JkgopV2DA4IDxCAQCEQpBHjNNg1oAKChYyLEbTDojPzHHanfXtlwes5jj5THFWbksFhMoivARgQXUfoKgKBIA3F6PVj9MfJwMdTIPlkQoDBMIAYCOM1m0UBd5BwwOGI9AIBChEKQPaBrSGm72SBOSCwsLZzkmKSh8Dn9LXpnT5fMTpIjPj4uSs8VceYbSMmSyjVoCiQ9iIiJlkshR0z9PFOGzuamxcXTarXBMw/GcxKTrgx02j8VLhLQrrrCwUCgUGm72LCw1VlhMbP6Oe6NTs9rOnvroH39XZuZllu0Qy5VMLtfv8Yxpe8//5XfTzn5Vf+XfY3P++UfCbbOc/O5XAq+T1mzMVFfwwsJxOt1pNl098+qNxvMLsAqBQHzaBF8RbejrkSYkl5WVzSsCMmj0NamrpKIIUkDFRESyGEwMA9JHep0eu9E2uYmOxWRWFpe+dal+dGIMAPgcblleUVxU9NSmkhQqi3fM6XUGFZpJWVlZwOzQrZ1kw4Nfi81e5bSYJrPO0ugMj8P+0emX7SZDTHpuYsG6dVWP1v7hp1Nr0RgM05D2zR89Ma211PWbC+7eP9LT0XHubZ/LGZORa9EPL8AqBAIxJzevXFJkrNS2LvxEquARUH/jeqa6oqKiYpZzQmZCAVgdtjZtpzIiRsgVBOKJz+UdadNRJPVxEcAAosMj9paWX77ebjCbSnNXRYdHMj+ZJCNcIE6OTrjW3xFijuiKioqA2aFbO5VrZ15rqz11/y/+Enjbf/Vy/9VboX+w46owMmpm4gOcziD9QdYcJa8tM/Zpao/+JPC2r6VhYSYhEIg5MfZpXv3+44tpIXgEHOluN/T1KOOTy8vLZzkubhoE4W/sbr7a185hsiWCsCR5YnJMYmykIlIczqQxPg6CAAA4hkkEorK8Qh/h57BYOIYBAIWBw+WwOGy6saE+vVZvNoYY/srLy5VKpaGvZ6S7PURTp3Lhxedud0uZla/MzItQrei+eBYAssp35my5+/r5d668eZLGYBDBzvYMi1E2nPyfBZiBQCCWn+AR0Odx69papPHJVVVVoUdACsBH+H0uu81lN1rHe0f661rP8zi8Xz7zU5lCSbgJiqT8Lp/f7QMKAmlTMQxoLDqdy8RomMVp++mvnuu5qfETfh/h94e8qruqqgoAdG0tge2iS8WO/3c4IjYBAAx9PYHTEd02q8syEVh0TaMzwpTKB393gvD5bGOGjvdO32g8H5dXhGM4i8vf8/3fckUSn8fV13yp8e8vLKFVCARiCbltZoSB1qakNaVqtXoB8yEAQFGUj/D5CJ/L6/6wtVkVr2JzuXArA/Qni2K3/nXoum8O9Vud88iIBQCFhYVqtdpqHB1YxFhAUN76SbVYrojNXpW6bnPpw4+/8vTXNQ3nJk8j66w/4/d6xgf6lJl5aSV3Fezer7/RxQ+LIClyxZrSnkvv6dpbssoqU9ZvHtf1BQ6vQCAQdxq33XRhHhnsb2kEgIMHDy5GgKKoV956zWKzAhbo9GEY/sn/GAYYuNyut945bbaY59t+wLz+lsZP44Bq88hg67tvNL3+V0G4NGnNxqm3bjSe729ptI3pO+vPfHDiT2wePz5/jcUwguO0znNvt777xsTQwIUXn3NaTEFTByIQiDuB2bad9V25ZB4dVKvVlZWVi9EY0Y++9Ldj7ts/olIUdeHSxQ8+vDTfg9IrKyvVarV5dLDvSpBjOpYKt8MGFOW/vf2E30cB+D0eXdsVn9sVeHaexB9ymmsEArHMzJYf0DSk1TTUF+y+v7q6+uzZs5PJshbA66dPpSSmbFGX0+l0AKCA8nq9LCYLACiKuq7peuHEi/p/rJQAAAUuSURBVDa7fV5tcjic6upqANA01C9sGeDtWLWrSqJQjXS3m0cG5ckZyqx8m8nY19Kwoqgku3xn14WznfVn1I8eMvZrDDd7xFExaSVbnBZT4FF3uKstPr/YaZkYut6aun4zi8tH08EIxB3LHBlSNQ3npAkpqpyCZ5555tChQwuW8RP+Xx79DZvNKllbwqDTKZKaMJujpDKSJG/09f741z/r1807hD3zzDNKpVJ7rWlybG6pcFnNbH529l276SwW4fWaRwavnnkFALjCMF5YBFcs4YnDmRxupnoHo4Lj93gs+uHmN08EMhW/99+/KHvsibSSLdnluxzm8Y9Ov7ywGWoEArEMBMmQOg1FRm7R3ocFEdLq6upjx44tRozNYn3z0a/v3r7T7/d39lzPTMvQDmiffPZ7fdq++Ta1f//+w4cP28YMjS//ebAjyKk9CAQCMTs1ndq5008NdlztrD8DAIcPHy4pKVmMntvj+c0fnyMIgiRJ49iY2+0+8vwfFxD+SkpKDh8+DACd9WdQ+EMgEAsmpAR8nfVn2uveAoCjR4/m5OQsRk8oEOI47vF6hoYHcRxfEZ843xZycnKOHj0KAO11bwVCMwKBQCyM0FKQUlT72bc0DeeEQuELL7ywmCC4tnANAHR0dXZpuul0elFBIYfNDr16Tk7OCy+8IBQKNQ3n2s++BaFtGkEgEIighJqE2WWzXHvn9d7LF6RS6cmTJxfwOMxiMpUxyrsrdlEUdfrdt691tE2YzcoY5arcfB6XF/Qo3mmUlJScPHlSKpX2Xr5w7Z3XZ56TjUAgEPOCtrMgI8SiXqfDNDTAYLOjV6Tec889RqOxtbU1lIpMJrNo1epd23fuu/sLSYkrRg36o3/5o8vtjlOq0pJS8nJWxilVIqHYOG6c5XC4/fv3HzlyhMViaRrOXT3zmm0M5YJGIBCLotdomUcEBACv02Hs0wAG0oSUsrIyuVx+8eJFf7AUKVNhs9n377kvXhXvdruaWq688L8v9Wn7SZLs6ulyezwMOiNcIomSRfUP9OuNQU754HA4hw8ffvzxxwGgve6ta2+/uuBTURAIBGKSXqNl7tUwQcCw9NKt6aVbBRFSnU53+PDhU6emHzc+FTqdLuQLGEym3+93u1wOl/PjZjAGg8HjcJlMJklRNpvV7Zm+faKysrK6ulqpVNrGDJ31Zzrrz6CxPwQCsSTUdGoXFAEBAECRkZu8tkyVUwAAdXV1R44cWUAChVkoLCw8ePCgWq0GAO21pp4PatHCFwQCsYQsKgICAIvHT1qzMWlNqThKAQB1dXXHjx8PPZvW7SgvL6+qqgrEPvPooKahXtNwzuOY3545BAKBmJ3FRsAAkhhVfH5xXF6RMDIKAHQ63enTp2tra+fbJSwsLCwrK6uoqFAqlQBgNY72tzT2Xbm0tHt+EQgEIsDSRMAAYrkiNrtAmZUnjb910LDVam1qampra+vp6dFqtXq93mKxuN1uAGCz2SKRSCaTqVSq5OTkrKysgoICoVAYqGjo69G1tQy0Nn0aCa8QCAQiwFJGwAAMFluekilbkSaNT5YmzO/MdcPNHkNfj/7G9ZHu9qXN9oxAIBAzqenUzpEbZr74PO6B1uZATnlJjEqiUIlkMYJImSBcyhYI2XwRjcEAAMLnc9stbpvVNm6wGfUW/ZBpUIuedhEIxDKzxBFwKqahIEENp9EBgAz5DBAEAoH49PgUI2BQUOxDIBB3DqHuC0YgEIj//0AREIFAfH5BERCBQHx+QREQgUB8fvk/oU/HigH/qfEAAAAASUVORK5CYII="},6561:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a02b4022.50e2e98d.js b/build-staging/de/assets/js/a02b4022.50e2e98d.js new file mode 100644 index 00000000..25b1c31d --- /dev/null +++ b/build-staging/de/assets/js/a02b4022.50e2e98d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3492],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(a),u=r,d=m["".concat(s,".").concat(u)]||m[u]||h[u]||i;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:r,o[1]=l;for(var p=2;p<i;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},4889:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"16. Juni 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"release",permalink:"/de/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/de/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/de/blog/cwtch-nightly-v.11-74"}},s={authorsImageUrls:[void 0]},p=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},m="wrapper";function h(e){let{components:t,...i}=e;return(0,r.kt)(m,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(159).Z,width:"1004",height:"480"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(8173).Z},(0,r.kt)("img",{src:a(5726).Z,width:"1388",height:"828"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.12")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Profile Attributes")," - profiles can now be augmented with ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"additional public information")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Availability Status")," - you can now notify contacts that you ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/availability-status"},"are ",(0,r.kt)("strong",{parentName:"a"},"away")," or ",(0,r.kt)("strong",{parentName:"a"},"busy"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Five New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Japanese"),", ",(0,r.kt)("strong",{parentName:"li"},"Korean"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili")," and ",(0,r.kt)("strong",{parentName:"li"},"Swedish")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Support for Tails")," - adds an ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/platforms/tails"},"OnionGrater")," configuration and a new ",(0,r.kt)("inlineCode",{parentName:"li"},"CWTCH_TAILS")," environment variable that enables special Tor behaviour."))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Based on Flutter 3.10"),(0,r.kt)("li",{parentName:"ul"},"Inter is now the main UI font"),(0,r.kt)("li",{parentName:"ul"},"New Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"New Network Management code to better manage Tor on unstable networks"),(0,r.kt)("li",{parentName:"ul"},"File Sharing Experiment Fixes",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Fix performance issues for file bubble"),(0,r.kt)("li",{parentName:"ul"},"Allow restarting of file shares that have timed out"),(0,r.kt)("li",{parentName:"ul"},"Fix NPE in FileBubble caused by deleting the underlying file"),(0,r.kt)("li",{parentName:"ul"},"Move from RetVal to UpdateConversationAttributes to minimze UI thread issues"))),(0,r.kt)("li",{parentName:"ul"},"Updates to Linux install scripts to support more distributions"),(0,r.kt)("li",{parentName:"ul"},"Add a Retry Peer connection to prioritize connection attempts for certain conversations"),(0,r.kt)("li",{parentName:"ul"},"Updates to ",(0,r.kt)("inlineCode",{parentName:"li"},"_FlDartProject")," to allow custom setting of Flutter asset paths"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili"),", ",(0,r.kt)("strong",{parentName:"li"},"Swedish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Japanese")," (29%), ",(0,r.kt)("strong",{parentName:"li"},"Korean")," (23%), ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.12 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"libCwtch-autobindings-2023-06-13-10-50-v0.0.5"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},8173:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},159:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"},5726:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a1dbc401.3390b4c3.js b/build-staging/de/assets/js/a1dbc401.3390b4c3.js new file mode 100644 index 00000000..1ca41349 --- /dev/null +++ b/build-staging/de/assets/js/a1dbc401.3390b4c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[263],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},s=Object.keys(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,s=e.originalType,l=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),d=u(n),f=i,g=d["".concat(l,".").concat(f)]||d[f]||p[f]||s;return n?r.createElement(g,o(o({ref:t},c),{},{components:n})):r.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var s=n.length,o=new Array(s);o[0]=f;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[d]="string"==typeof e?e:i,o[1]=a;for(var u=2;u<s;u++)o[u]=n[u];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}f.displayName="MDXCreateElement"},402:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const s={},o="Entwicklung",a={unversionedId:"development",id:"development",title:"Entwicklung",description:"Der Hauptprozess gegen b\xf6swillige Akteure bei der Entwicklung von Cwtch ist die Offenheit des Prozesses.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/development.md",sourceDirName:".",slug:"/development",permalink:"/de/security/development",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Ver\xf6ffentlichung",permalink:"/de/security/deployment"},next:{title:"Referenzen",permalink:"/de/security/references"}},l={},u=[{value:"Risiko: Entwickler liefert b\xf6sartigen Code direkt aus",id:"risiko-entwickler-liefert-b\xf6sartigen-code-direkt-aus",level:3},{value:"Risiko: Code Regressionen",id:"risiko-code-regressionen",level:3}],c={toc:u},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"entwicklung"},"Entwicklung"),(0,i.kt)("p",null,"Der Hauptprozess gegen b\xf6swillige Akteure bei der Entwicklung von Cwtch ist die Offenheit des Prozesses."),(0,i.kt)("p",null,"Um diese Offenheit zu verst\xe4rken, werden automatisierte buidls, Tests und Paketierungen als Teil der Repositories definiert - Verbesserung der Robustheit der Codebasis in jeder Phase."),(0,i.kt)("p",null,(0,i.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/1.png",alt:null})),(0,i.kt)("p",null,"W\xe4hrend die einzelnen Tests nicht perfekt sind und alle Prozesse L\xfccken haben, sollten wir verpflichtet sein, es so einfach wie m\xf6glich machen, etwas zu Cwtch beizutragen und gleichzeitig Pipelines und Prozesse so erstellen, dass Fehler (unabsichtlich oder b\xf6sartig) so fr\xfch wie m\xf6glich abgefangen werden."),(0,i.kt)("h3",{id:"risiko-entwickler-liefert-b\xf6sartigen-code-direkt-aus"},"Risiko: Entwickler liefert b\xf6sartigen Code direkt aus"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Gemildert")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"trunk")," ist derzeit gesperrt und nur 3 Open Privacy Mitarbeiter haben die Berechtigung um es zu \xfcberschreiben und dar\xfcber hinaus die Verantwortung f\xfcr die \xdcberwachung der \xc4nderungen."),(0,i.kt)("p",null,"Dar\xfcber hinaus l\xf6st jeder neue Pull-Request und Merge automatisierte Builds & Tests aus, die E-Mails und Audit Protokolle ausl\xf6sen."),(0,i.kt)("p",null,"Der Code ist auch Open Source und von jedem \xfcberpr\xfcfbar."),(0,i.kt)("h3",{id:"risiko-code-regressionen"},"Risiko: Code Regressionen"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert")," (Siehe einzelne Projekteintr\xe4ge in diesem Handbuch f\xfcr weitere Informationen)"),(0,i.kt)("p",null,"Unsere automatisierten Pipelines haben die M\xf6glichkeit, Regressionen zu erfassen, wenn dieses Verhalten erkennbar ist."),(0,i.kt)("p",null,"Die gr\xf6\xdfte Herausforderung besteht darin, festzulegen, wie solche Regressionen f\xfcr die ",(0,i.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"UI")," erkannt werden - wo das Verhalten nicht so streng definiert ist wie f\xfcr die einzelnen Bibliotheken."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a65a3c47.a5f7f3c6.js b/build-staging/de/assets/js/a65a3c47.a5f7f3c6.js new file mode 100644 index 00000000..82042b3f --- /dev/null +++ b/build-staging/de/assets/js/a65a3c47.a5f7f3c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7591],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var o=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,o)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,o,n=function(e,t){if(null==e)return{};var a,o,n={},r=Object.keys(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=o.createContext({}),p=function(e){var t=o.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return o.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(a),u=n,m=h["".concat(c,".").concat(u)]||h[u]||d[u]||r;return a?o.createElement(m,i(i({ref:t},s),{},{components:a})):o.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var p=2;p<r;p++)i[p]=a[p];return o.createElement.apply(null,i)}return o.createElement.apply(null,a)}u.displayName="MDXCreateElement"},5432:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=a(7462),n=(a(7294),a(3905));const r={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"28. April 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/de/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/de/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/de/blog/availability-status-profile-attributes"}},c={authorsImageUrls:[void 0]},p=[{value:"Cwtch Development Handbook",id:"cwtch-development-handbook",level:2},{value:"Release and Packaging Process",id:"release-and-packaging-process",level:3},{value:"Cwtch Application Development and Cwtchbot v0.1.0!",id:"cwtch-application-development-and-cwtchbot-v010",level:3},{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(h,(0,o.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(3466).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"cwtch-development-handbook"},"Cwtch Development Handbook"),(0,n.kt)("p",null,"We have created a new documentation section, ",(0,n.kt)("a",{parentName:"p",href:"/developing/intro"},"the developers handbook"),". This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients)."),(0,n.kt)("h3",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"The new handbook features a breakdown of ",(0,n.kt)("a",{parentName:"p",href:"/developing/release"},"Cwtch release processes")," - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created."),(0,n.kt)("h3",{id:"cwtch-application-development-and-cwtchbot-v010"},"Cwtch Application Development and Cwtchbot v0.1.0!"),(0,n.kt)("p",null,"For the first time ever we now have ",(0,n.kt)("a",{parentName:"p",href:"/developing/category/building-a-cwtch-app"},"comprehensive documentation on how to build a Cwtch Application"),". This section of the development handbook covers everything from ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"choosing a Cwtch library"),", to ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot"},"building your first application"),"."),(0,n.kt)("p",null,"Together with this new documentation we have also ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"released version 0.1 of the Cwtchbot framework"),", updating calls to use the ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-api-design"},"new Cwtch Stable API"),"."),(0,n.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,n.kt)("p",null,"There is a ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,n.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/"},"2023-04-26-20-57-v1.11.0-33-gb4371"),"."),(0,n.kt)("p",null,"This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"in-development Tails support"),". "),(0,n.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,n.kt)("p",null,"Please see the contribution documentation for advice on ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,n.kt)("p",null,"Subscribe to our ",(0,n.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,n.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,n.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3466:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a6aa9e1f.8ac198c5.js b/build-staging/de/assets/js/a6aa9e1f.8ac198c5.js new file mode 100644 index 00000000..f9d14373 --- /dev/null +++ b/build-staging/de/assets/js/a6aa9e1f.8ac198c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3089],{46:(e,t,a)=>{a.r(t),a.d(t,{default:()=>u});var n=a(7294),r=a(6010),l=a(2263),i=a(1944),o=a(5281),s=a(9058),m=a(9703),c=a(197),g=a(9985);function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,l.Z)(),{blogDescription:r,blogTitle:o,permalink:s}=t,m="/"===s?a:o;return n.createElement(n.Fragment,null,n.createElement(i.d,{title:m,description:r}),n.createElement(c.Z,{tag:"blog_posts_list"}))}function d(e){const{metadata:t,items:a,sidebar:r}=e;return n.createElement(s.Z,{sidebar:r},n.createElement(g.Z,{items:a}),n.createElement(m.Z,{metadata:t}))}function u(e){return n.createElement(i.FG,{className:(0,r.Z)(o.k.wrapper.blogPages,o.k.page.blogListPage)},n.createElement(p,e),n.createElement(d,e))}},9703:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(5999),l=a(2244);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,r.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(l.Z,{permalink:a,title:n.createElement(r.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),i&&n.createElement(l.Z,{permalink:i,title:n.createElement(r.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(9460),l=a(390);function i(e){let{items:t,component:a=l.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(r.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a79c88c2.011183de.js b/build-staging/de/assets/js/a79c88c2.011183de.js new file mode 100644 index 00000000..076ccaba --- /dev/null +++ b/build-staging/de/assets/js/a79c88c2.011183de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9976],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),u=r,m=h["".concat(c,".").concat(u)]||h[u]||g[u]||i;return a?n.createElement(m,o(o({ref:t},p),{},{components:a})):n.createElement(m,o({ref:t},p))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,o[1]=l;for(var s=2;s<i;s++)o[s]=a[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},8553:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"13. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"},{label:"api",permalink:"/de/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/de/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/de/blog/path-to-cwtch-stable"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...i}=e;return(0,r.kt)(h,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,r.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,r.kt)("p",null,"As we move out of Beta and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,r.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(4867).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},4867:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a85d9f35.4f11e7a8.js b/build-staging/de/assets/js/a85d9f35.4f11e7a8.js new file mode 100644 index 00000000..52e40078 --- /dev/null +++ b/build-staging/de/assets/js/a85d9f35.4f11e7a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2849],{8263:e=>{e.exports=JSON.parse('{"label":"repliqate","permalink":"/de/blog/tags/repliqate","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a8c7fdc6.6b08bc27.js b/build-staging/de/assets/js/a8c7fdc6.6b08bc27.js new file mode 100644 index 00000000..91a35086 --- /dev/null +++ b/build-staging/de/assets/js/a8c7fdc6.6b08bc27.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1602],{6454:e=>{e.exports=JSON.parse('{"pluginId":"docs-security","version":"current","label":"N\xe4chste","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Cwtch Sicherheitshandbuch","href":"/de/security/intro","docId":"intro"},{"type":"link","label":"Risiko-Modell","href":"/de/security/risk","docId":"risk"},{"type":"category","label":"Cwtch Komponenten","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cwtch technische Grundlagen","href":"/de/security/components/intro","docId":"components/intro"},{"type":"link","label":"Komponenten Ecosystem \xdcbersicht","href":"/de/security/components/ecosystem-overview","docId":"components/ecosystem-overview"},{"type":"category","label":"Verbindung & Tor","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Verbindung","href":"/de/security/components/connectivity/intro","docId":"components/connectivity/intro"}],"href":"/de/security/category/connectivity--tor"},{"type":"category","label":"Tapir","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Paketformat","href":"/de/security/components/tapir/packet_format","docId":"components/tapir/packet_format"},{"type":"link","label":"Authentifizierungsprotokoll","href":"/de/security/components/tapir/authentication_protocol","docId":"components/tapir/authentication_protocol"}],"href":"/de/security/category/tapir"},{"type":"category","label":"Cwtch","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Nachrichtenformate","href":"/de/security/components/cwtch/message_formats","docId":"components/cwtch/message_formats"},{"type":"link","label":"Schl\xfcsselb\xfcndel","href":"/de/security/components/cwtch/key_bundles","docId":"components/cwtch/key_bundles"},{"type":"link","label":"Gruppen","href":"/de/security/components/cwtch/groups","docId":"components/cwtch/groups"},{"type":"link","label":"Cwtch Server","href":"/de/security/components/cwtch/server","docId":"components/cwtch/server"}],"href":"/de/security/category/cwtch"},{"type":"category","label":"Cwtch-UI","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Android Dienst","href":"/de/security/components/ui/android","docId":"components/ui/android"},{"type":"link","label":"Bildervorschau","href":"/de/security/components/ui/image_previews","docId":"components/ui/image_previews"},{"type":"link","label":"Eingabe","href":"/de/security/components/ui/input","docId":"components/ui/input"},{"type":"link","label":"Nachrichten Overlays","href":"/de/security/components/ui/overlays","docId":"components/ui/overlays"}],"href":"/de/security/category/cwtch-ui"}],"href":"/de/security/category/cwtch-components"},{"type":"link","label":"Ver\xf6ffentlichung","href":"/de/security/deployment","docId":"deployment"},{"type":"link","label":"Entwicklung","href":"/de/security/development","docId":"development"},{"type":"link","label":"Referenzen","href":"/de/security/references","docId":"references"}]},"docs":{"components/connectivity/intro":{"id":"components/connectivity/intro","title":"Verbindung","description":"Cwtch nutzt Tor Onion Services (v3) f\xfcr die Kommunikation zwischen Knoten.","sidebar":"tutorialSidebar"},"components/cwtch/groups":{"id":"components/cwtch/groups","title":"Gruppen","description":"Das Cwtch Risikomodell f\xfcr Gruppen ist gr\xf6\xdftenteils in zwei unterschiedliche Profile aufgeteilt:","sidebar":"tutorialSidebar"},"components/cwtch/key_bundles":{"id":"components/cwtch/key_bundles","title":"Schl\xfcsselb\xfcndel","description":"Cwtch-Server identifizieren sich mit signierten Schl\xfcsselb\xfcndeln. Diese Schl\xfcsselb\xfcndel enthalten eine Liste der ben\xf6tigten Schl\xfcssel, um die Kommunikation der Cwtch-Gruppe sicher zu machen und Metadaten widerstandsf\xe4hig zu machen.","sidebar":"tutorialSidebar"},"components/cwtch/message_formats":{"id":"components/cwtch/message_formats","title":"Nachrichtenformate","description":"Peer-to-Peer Nachrichten","sidebar":"tutorialSidebar"},"components/cwtch/server":{"id":"components/cwtch/server","title":"Cwtch Server","description":"Ziel des Cwtch-Protokolls ist es, die Gruppenkommunikation \xfcber Nicht vertrauensw\xfcrdige Infrastruktur zu aktivieren.","sidebar":"tutorialSidebar"},"components/ecosystem-overview":{"id":"components/ecosystem-overview","title":"Komponenten Ecosystem \xdcbersicht","description":"Cwtch besteht aus mehreren kleineren Komponenten-Bibliotheken. Dieses Kapitel gibt einen kurzen \xdcberblick \xfcber jede Komponente und wie sie sich auf das gr\xf6\xdfere Cwtch-\xd6kosystem bezieht.","sidebar":"tutorialSidebar"},"components/intro":{"id":"components/intro","title":"Cwtch technische Grundlagen","description":"Diese Seite bietet einen kurzen technischen \xdcberblick \xfcber das Cwtch-Protokoll.","sidebar":"tutorialSidebar"},"components/tapir/authentication_protocol":{"id":"components/tapir/authentication_protocol","title":"Authentifizierungsprotokoll","description":"Jeder Peer erh\xe4lt eine offene Verbindung $C$:","sidebar":"tutorialSidebar"},"components/tapir/packet_format":{"id":"components/tapir/packet_format","title":"Paketformat","description":"Alle Tapir-Pakete haben eine feste L\xe4nge (8192 Bytes) und die ersten 2 Bytes zeigen die tats\xe4chliche L\xe4nge der Nachricht, len Bytes an Daten und der Rest mit null aufgef\xfcllt:","sidebar":"tutorialSidebar"},"components/ui/android":{"id":"components/ui/android","title":"Android Dienst","description":"Angepasst von Integration von FFI-Prozessen mit Android-Diensten","sidebar":"tutorialSidebar"},"components/ui/image_previews":{"id":"components/ui/image_previews","title":"Bildervorschau","description":"Basierend auf dem Filesharing in Cwtch 1.3 werden die Bildvorschauen durch die Erweiterung des vorgeschlagenen Dateinamens (und nein, wir sind nicht daran interessiert, MIME-Typen oder magische Zahlen zu verwenden) und die angezeigte Gr\xf6\xdfe bestimmt. Wenn diese Option aktiviert ist, l\xe4dt das Vorschausystem automatisch freigegebene Bilder in einen konfigurierten Download-Ordner herunter und zeigt sie als Teil der Nachricht selbst an. (Aufgrund von Beschr\xe4nkungen auf Android werden sie im privaten Cache der App gespeichert und Sie haben die M\xf6glichkeit, sie sp\xe4ter an anderer Stelle zu speichern) Die Dateigr\xf6\xdfenbeschr\xe4nkung ist noch nicht festgelegt, wird aber deutlich niedriger sein als die allgemeine Gr\xf6\xdfenbeschr\xe4nkung f\xfcr die gemeinsame Nutzung von Dateien, die derzeit bei 10 Gigabyte liegt.","sidebar":"tutorialSidebar"},"components/ui/input":{"id":"components/ui/input","title":"Eingabe","description":"Risiko: Abfangen von Cwtch-Inhalten oder Metadaten durch eine IME auf mobilen Ger\xe4ten","sidebar":"tutorialSidebar"},"components/ui/overlays":{"id":"components/ui/overlays","title":"Nachrichten Overlays","description":"Angepasst von Anmerkungen zur Cwtch Chat API","sidebar":"tutorialSidebar"},"deployment":{"id":"deployment","title":"Ver\xf6ffentlichung","description":"Risiko: Bin\xe4rdateien werden auf der Website durch b\xf6swillige Versionen ersetzt","sidebar":"tutorialSidebar"},"development":{"id":"development","title":"Entwicklung","description":"Der Hauptprozess gegen b\xf6swillige Akteure bei der Entwicklung von Cwtch ist die Offenheit des Prozesses.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Cwtch Sicherheitshandbuch","description":"Willkommen im Cwtch Sicherheitshandbuch! Der Zweck dieses Handbuchs ist es, eine Anleitung f\xfcr die verschiedenen Komponenten des Cwtch \xd6kosystems zu liefern um die bekannten Risiken und Abschw\xe4chungen zu dokumentieren und Diskussionen \xfcber Verbesserungen und Aktualisierungen f\xfcr Cwtch sichere Entwicklungsprozesse zu erm\xf6glichen.","sidebar":"tutorialSidebar"},"references":{"id":"references","title":"Referenzen","description":"* Atwater, Erinn und Sarah Jamie Lewis. \\"Token Based Services-Differences from Privacy Pass.\\"","sidebar":"tutorialSidebar"},"risk":{"id":"risk","title":"Risiko-Modell","description":"Es ist bekannt, dass Kommunikationsmetadaten von verschiedenen Gegnern ausgenutzt werden, um die Sicherheit von Systemen zu untergraben, Opfer zu verfolgen und gro\xdf angelegte Analysen sozialer Netzwerke durchzuf\xfchren, um die Massen\xfcberwachung zu unterst\xfctzen. Metadaten-resistente Tools stecken noch in den Kinderschuhen und es fehlt an Forschung zur Konstruktion und Benutzererfahrung solcher Tools.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a8d50805.c8607d5f.js b/build-staging/de/assets/js/a8d50805.c8607d5f.js new file mode 100644 index 00000000..dff23e19 --- /dev/null +++ b/build-staging/de/assets/js/a8d50805.c8607d5f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6536],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),h=a,f=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return r?n.createElement(f,o(o({ref:t},p),{},{components:r})):n.createElement(f,o({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l<i;l++)o[l]=r[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}h.displayName="MDXCreateElement"},7591:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const i={sidebar_position:4},o="Gespr\xe4chsverlauf speichern",s={unversionedId:"chat/save-conversation-history",id:"chat/save-conversation-history",title:"Gespr\xe4chsverlauf speichern",description:"Standardm\xe4\xdfig speichert Cwtch aus Gr\xfcnden der Privatsph\xe4re keine Unterhaltungshistorie zwischen den Sitzungen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/save-conversation-history.md",sourceDirName:"chat",slug:"/chat/save-conversation-history",permalink:"/de/docs/chat/save-conversation-history",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/save-conversation-history.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Teilen von Cwtch Adressen",permalink:"/de/docs/chat/share-address-with-friends"},next:{title:"Nachrichtenformatierung",permalink:"/de/docs/chat/message-formatting"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"gespr\xe4chsverlauf-speichern"},"Gespr\xe4chsverlauf speichern"),(0,a.kt)("p",null,"Standardm\xe4\xdfig speichert Cwtch aus Gr\xfcnden der Privatsph\xe4re keine Unterhaltungshistorie zwischen den Sitzungen."),(0,a.kt)("p",null,"Um den Verlauf f\xfcr eine bestimmte Konversation zu aktivieren:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Gehe in einem Konversationsfenster zu Einstellungen"),(0,a.kt)("li",{parentName:"ol"},"Gehe zu Verlauf speichern"),(0,a.kt)("li",{parentName:"ol"},"Klicke das Dropdown-Men\xfc"),(0,a.kt)("li",{parentName:"ol"},"Verlauf speichern ausw\xe4hlen"),(0,a.kt)("li",{parentName:"ol"},"Jetzt wird dein Verlauf gespeichert")),(0,a.kt)("p",null,'Die Konversationshistorie kann an jedem beliebigen Punkt abgeschaltet werden, indem du im Dropdown-Men\xfc "Verlauf l\xf6schen" ausw\xe4hlst.'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/a92fc3a1.799159ae.js b/build-staging/de/assets/js/a92fc3a1.799159ae.js new file mode 100644 index 00000000..015bc5b4 --- /dev/null +++ b/build-staging/de/assets/js/a92fc3a1.799159ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8980],{7215:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/cwtch/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/de/blog/tags/cwtch","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/aa1db8cb.63926186.js b/build-staging/de/assets/js/aa1db8cb.63926186.js new file mode 100644 index 00000000..efb595eb --- /dev/null +++ b/build-staging/de/assets/js/aa1db8cb.63926186.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2628],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>g});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=c(r),m=i,g=l["".concat(s,".").concat(m)]||l[m]||d[m]||o;return r?n.createElement(g,a(a({ref:t},u),{},{components:r})):n.createElement(g,a({ref:t},u))}));function g(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:i,a[1]=p;for(var c=2;c<o;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},6527:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:6},a="Wie man eine Gruppe verl\xe4sst?",p={unversionedId:"groups/leave-group",id:"groups/leave-group",title:"Wie man eine Gruppe verl\xe4sst?",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/leave-group.md",sourceDirName:"groups",slug:"/groups/leave-group",permalink:"/de/docs/groups/leave-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/leave-group.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Eine Gruppeneinladung annehmen",permalink:"/de/docs/groups/accept-group-invite"},next:{title:"Einen Gruppennamen bearbeiten",permalink:"/de/docs/groups/edit-group-name"}},s={},c=[],u={toc:c},l="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"wie-man-eine-gruppe-verl\xe4sst"},"Wie man eine Gruppe verl\xe4sst?"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,i.kt)("admonition",{title:"Warnung",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion wird das Schl\xfcsselmaterial ",(0,i.kt)("strong",{parentName:"p"},"unwiderruflich")," l\xf6schen. Dieses ",(0,i.kt)("strong",{parentName:"p"},"kann nicht r\xfcckg\xe4ngig gemacht werden"),".")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Gehen Sie im Chat-Fenster zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"Im Einstellungsfenster nach unten scrollen"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke auf Konversation verlassen"),(0,i.kt)("li",{parentName:"ol"},"Best\xe4tige, dass du verlassen m\xf6chtest")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Group_Leave.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/ab726e24.9db808a3.js b/build-staging/de/assets/js/ab726e24.9db808a3.js new file mode 100644 index 00000000..ce3afe9e --- /dev/null +++ b/build-staging/de/assets/js/ab726e24.9db808a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1370],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>g});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),u=p(r),d=i,g=u["".concat(c,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(g,s(s({ref:t},l),{},{components:r})):n.createElement(g,s({ref:t},l))}));function g(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,s=new Array(o);s[0]=d;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[u]="string"==typeof e?e:i,s[1]=a;for(var p=2;p<o;p++)s[p]=r[p];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},7420:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>a,toc:()=>p});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:2},s="Server Hosting",a={unversionedId:"settings/experiments/server-hosting",id:"settings/experiments/server-hosting",title:"Server Hosting",description:"Server-Hosting ist derzeit eine experimentelle Funktion in Cwtch, es ist standardm\xe4\xdfig nicht aktiviert.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/server-hosting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/server-hosting",permalink:"/de/docs/settings/experiments/server-hosting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/server-hosting.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"experimentelle Gruppen Funktion",permalink:"/de/docs/settings/experiments/group-experiment"},next:{title:"Dateifreigabe",permalink:"/de/docs/settings/experiments/file-sharing"}},c={},p=[],l={toc:p},u="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"server-hosting"},"Server Hosting"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Server-Hosting ist derzeit eine experimentelle Funktion in Cwtch, es ist standardm\xe4\xdfig nicht aktiviert.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"Experimente aktivieren"),(0,i.kt)("li",{parentName:"ol"},"Server-Hosting-Experiment aktivieren"),(0,i.kt)("li",{parentName:"ol"},"Du wirst wahrscheinlich auch das Gruppenexperiment aktivieren wollen, wenn du an einer Gruppe teilnehmen m\xf6chtest, die auf deinem Server gehostet wird")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/af23c5f9.6408958f.js b/build-staging/de/assets/js/af23c5f9.6408958f.js new file mode 100644 index 00000000..2611319d --- /dev/null +++ b/build-staging/de/assets/js/af23c5f9.6408958f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3218],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){i(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,i=function(e,t){if(null==e)return{};var a,n,i={},r=Object.keys(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),h=p(a),m=i,d=h["".concat(s,".").concat(m)]||h[m]||u[m]||r;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:i,o[1]=l;for(var p=2;p<r;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},4958:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var n=a(7462),i=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"31. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/de/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/de/blog/cwtch-nightly-1-11"}},s={authorsImageUrls:[void 0]},p=[{value:"Update on the January Roadmap",id:"update-on-the-january-roadmap",level:2},{value:"A Timeline for Cwtch Stable",id:"a-timeline-for-cwtch-stable",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},h="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(h,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,i.kt)("strong",{parentName:"p"},"Beta")," to ",(0,i.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,i.kt)("p",null,"This post ",(0,i.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,i.kt)("p",null,(0,i.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,i.kt)("h2",{id:"update-on-the-january-roadmap"},"Update on the January Roadmap"),(0,i.kt)("p",null,"Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:"),(0,i.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"finalized a feature set that defines Cwtch Stable")," and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/security/intro"},"Security and Design Documents")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"Infrastructure and ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"Support")," \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"in addition to a new development blog. \u2705"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a ",(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"style guide for documentation"),", and \u2705"),(0,i.kt)("li",{parentName:"ul"},"have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"with at least one screenshot (where applicable). \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published: ",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"Interface Specification Document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Release Process Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-platform-support"},"Support Plan document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Packaging Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a document describing the ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"Reproducible Builds Process")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)")),(0,i.kt)("p",null,"While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings"},"Cwtch Autobindings")," with ",(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings-ii"},"compile-time optional experiments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-nightly-1-11"},"Cwtch 1.11")," - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.")),(0,i.kt)("h2",{id:"a-timeline-for-cwtch-stable"},"A Timeline for Cwtch Stable"),(0,i.kt)("p",null,"Now for the big news, we plan on releasing a candidate Cwtch Stable release during ",(0,i.kt)("strong",{parentName:"p"},"Summer 2023"),". Here is our plan for getting there:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document"),(0,i.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document"),(0,i.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots."))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries"),(0,i.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"An implementation of ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information"),(0,i.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist."),(0,i.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team"),(0,i.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable."),(0,i.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,i.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,i.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,i.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,i.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,i.kt)("h2",{id:"get-involved"},"Get Involved"),(0,i.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,i.kt)("p",null,"We also also updated our guides on ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,i.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,i.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/afe8c04b.80a41c12.js b/build-staging/de/assets/js/afe8c04b.80a41c12.js new file mode 100644 index 00000000..0b16da0b --- /dev/null +++ b/build-staging/de/assets/js/afe8c04b.80a41c12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6011],{1693:e=>{e.exports=JSON.parse('{"label":"documentation","permalink":"/de/blog/tags/documentation","allTagsPath":"/de/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b0404c31.c233cba7.js b/build-staging/de/assets/js/b0404c31.c233cba7.js new file mode 100644 index 00000000..bfc68de4 --- /dev/null +++ b/build-staging/de/assets/js/b0404c31.c233cba7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7860],{3905:(e,t,a)=>{a.d(t,{Zo:()=>h,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){o(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,o=function(e,t){if(null==e)return{};var a,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},h=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(a),u=o,m=p["".concat(s,".").concat(u)]||p[u]||d[u]||i;return a?n.createElement(m,r(r({ref:t},h),{},{components:a})):n.createElement(m,r({ref:t},h))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=a.length,r=new Array(i);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var c=2;c<i;c++)r[c]=a[c];return n.createElement.apply(null,r)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},3478:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const i={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/de/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"6. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/de/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"Tenets of Cwtch Stable",id:"tenets-of-cwtch-stable",level:3},{value:"Known Problems",id:"known-problems",level:3},{value:"Plan of Action",id:"plan-of-action",level:3},{value:"Goals and Timelines",id:"goals-and-timelines",level:3},{value:"Help us get there!",id:"help-us-get-there",level:3}],h={toc:c},p="wrapper";function d(e){let{components:t,...i}=e;return(0,o.kt)(p,(0,n.Z)({},h,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,o.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,o.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h3",{id:"tenets-of-cwtch-stable"},"Tenets of Cwtch Stable"),(0,o.kt)("p",null,"It is important to state that Cwtch Stable ",(0,o.kt)("strong",{parentName:"p"},"does not mean an end to Cwtch development"),". Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Consistent Interface")," \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Universal Availability and Cohesive Support")," \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Reproducible Builds")," \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Proven Security")," \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.")),(0,o.kt)("h3",{id:"known-problems"},"Known Problems"),(0,o.kt)("p",null,"To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of a Stable API for future feature development")," \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Special functionality in libCwtch-go")," \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"libCwtch-rs partial support")," - we currently do not officially consider ",(0,o.kt)("a",{parentName:"li",href:"https://lib.rs/crates/libcwtch"},"libCwtch-rs")," when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Reproducible Pipelines")," - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of up to date, and translated, Security Documentation")," \u2013 the ",(0,o.kt)("a",{parentName:"li",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Cwtch security handbook")," is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"No Automated UI Tests")," \u2013 we put a lot of work into ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"building out a testing framework for the UI"),", but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Code Signing Provider")," \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Second-class Android Support")," - while we have put ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/27-android-improvements/"},"a lot of effort behind Android support")," across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Fuzzing")," \u2013 while ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Fuzzbot")," sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Formal Release Acceptance Process")," \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Inconsistent Cwtch Information Discovery")," \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Incomplete Documentation")," \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)")),(0,o.kt)("h3",{id:"plan-of-action"},"Plan of Action"),(0,o.kt)("p",null,"Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Interface Specification Documentation")," \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Release Process")," \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Support Document")," - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Packaging Document")," - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Reproducible Builds Document")," \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand the Cwtch Documentation Site")," \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand our Automated Testing to include UI and Fuzzing")," - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Re-evaluate all Issues across all Cwtch related repositories")," \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define a Stable Feature Set")," \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)")),(0,o.kt)("h3",{id:"goals-and-timelines"},"Goals and Timelines"),(0,o.kt)("p",null,"With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.")),(0,o.kt)("p",null,"As these documents are written, and these goals met we will be posting them here! Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, Cwtch development."),(0,o.kt)("h3",{id:"help-us-get-there"},"Help us get there!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b0f5629f.8b4a2916.js b/build-staging/de/assets/js/b0f5629f.8b4a2916.js new file mode 100644 index 00000000..2e0c294c --- /dev/null +++ b/build-staging/de/assets/js/b0f5629f.8b4a2916.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3250],{4255:e=>{e.exports=JSON.parse('{"title":"Experimentelle Funktionen","slug":"/category/experiments","permalink":"/de/docs/category/experiments","navigation":{"previous":{"title":"Benachrichtigungsinhalt","permalink":"/de/docs/settings/behaviour/notification-content"},"next":{"title":"experimentelle Gruppen Funktion","permalink":"/de/docs/settings/experiments/group-experiment"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b125d866.186024b1.js b/build-staging/de/assets/js/b125d866.186024b1.js new file mode 100644 index 00000000..5313d389 --- /dev/null +++ b/build-staging/de/assets/js/b125d866.186024b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8799],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function c(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),p=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(a),u=n,m=h["".concat(l,".").concat(u)]||h[u]||d[u]||o;return a?r.createElement(m,i(i({ref:t},s),{},{components:a})):r.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=a[p];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}u.displayName="MDXCreateElement"},1595:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/de/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"30. Juni 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/de/blog/cwtch-nightly-1-12"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function d(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b17c3fe9.ade4c602.js b/build-staging/de/assets/js/b17c3fe9.ade4c602.js new file mode 100644 index 00000000..658c8035 --- /dev/null +++ b/build-staging/de/assets/js/b17c3fe9.ade4c602.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2096],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},b=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=l(n),b=i,h=d["".concat(c,".").concat(b)]||d[b]||p[b]||a;return n?r.createElement(h,s(s({ref:t},u),{},{components:n})):r.createElement(h,s({ref:t},u))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,s=new Array(a);s[0]=b;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o[d]="string"==typeof e?e:i,s[1]=o;for(var l=2;l<a;l++)s[l]=n[l];return r.createElement.apply(null,s)}return r.createElement.apply(null,n)}b.displayName="MDXCreateElement"},8331:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:1},s="Cwtch testen",o={unversionedId:"contribute/testing",id:"contribute/testing",title:"Cwtch testen",description:"Dieser Abschnitt dokumentiert einige M\xf6glichkeiten, um mit Cwtch-Tests zu beginnen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/testing.md",sourceDirName:"contribute",slug:"/contribute/testing",permalink:"/de/docs/contribute/testing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/testing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Entwicklung von Cwtch",permalink:"/de/docs/contribute/developing"},next:{title:"Cwtch \xfcbersetzen",permalink:"/de/docs/contribute/translate"}},c={},l=[{value:"Laufender Fuzzbot",id:"laufender-fuzzbot",level:3},{value:"Trete der Cwtch Release Candidate Tester Gruppe bei",id:"trete-der-cwtch-release-candidate-tester-gruppe-bei",level:3},{value:"Cwtch Nightlies",id:"cwtch-nightlies",level:3},{value:"Feedback abgeben",id:"feedback-abgeben",level:3}],u={toc:l},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"cwtch-testen"},"Cwtch testen"),(0,i.kt)("p",null,"Dieser Abschnitt dokumentiert einige M\xf6glichkeiten, um mit Cwtch-Tests zu beginnen."),(0,i.kt)("h3",{id:"laufender-fuzzbot"},"Laufender Fuzzbot"),(0,i.kt)("p",null,"FuzzBot ist unser Entwicklungs-Testbot. Du kannst FuzzBot als Kontakt hinzuf\xfcgen: ",(0,i.kt)("inlineCode",{parentName:"p"},"cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad"),"."),(0,i.kt)("admonition",{title:"FuzzBot Hilfe",type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Wenn Du FuzzBot eine ",(0,i.kt)("inlineCode",{parentName:"p"},"Hilfe-")," Nachricht sendest, werden alle derzeit verf\xfcgbaren Testbefehle angezeigt.")),(0,i.kt)("p",null,"Weitere Informationen \xfcber FuzzBot findest Du in unserem ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Discreet Log Development Blog"),"."),(0,i.kt)("h3",{id:"trete-der-cwtch-release-candidate-tester-gruppe-bei"},"Trete der Cwtch Release Candidate Tester Gruppe bei"),(0,i.kt)("p",null,"Wenn Du Fuzzbot den Befehl ",(0,i.kt)("inlineCode",{parentName:"p"},"testgroup-invite")," sendest, l\xe4dt FuzzBot Dich zur ",(0,i.kt)("strong",{parentName:"p"},"Cwtch Testers Group")," ein! Dort kannst du Fragen stellen, Fehlerberichte schreiben und Feedback geben."),(0,i.kt)("h3",{id:"cwtch-nightlies"},"Cwtch Nightlies"),(0,i.kt)("p",null,"Cwtch Nightly Builds sind Entwicklungs-Builds, die neue Features enthalten, die zum Testen bereit sind."),(0,i.kt)("p",null,"Die aktuellsten Entwicklungsversionen von Cwtch sind auf unserem ",(0,i.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"Build-Server")," verf\xfcgbar."),(0,i.kt)("p",null,"Wir empfehlen ",(0,i.kt)("strong",{parentName:"p"},"nicht"),", dass Tester immer auf die neueste Nightly aktualisieren, sondern wir werden eine Nachricht an die Cwtch Release Candidate Testers Gruppe schicken, wenn eine bedeutsame Nightly verf\xfcgbar wird. Eine Nightly wird als bedeutsam angesehen, wenn sie eine neue Funktion oder eine gr\xf6\xdfere Fehlerbehebung enth\xe4lt."),(0,i.kt)("admonition",{title:"Hinweis",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Alle Beitr\xe4ge sind ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"berechtigt f\xfcr Aufkleber"))),(0,i.kt)("h3",{id:"feedback-abgeben"},"Feedback abgeben"),(0,i.kt)("p",null,"Es gibt drei wichtige M\xf6glichkeiten, Test-Feedback an das Team zu \xfcbermitteln:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"\xdcber Cwtch: Entweder \xfcber die Release Candidate Tester Gruppe oder direkt \xfcber ein Cwtch Team-Mitglied."),(0,i.kt)("li",{parentName:"ul"},"Via Gitea: Bitte \xf6ffne ein Problem unter ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"https://git.openprivacy.ca/cwtch. m/cwtch-ui/issues")," - Bitte mache dir keine Gedanken \xfcber doppelte Probleme, wir werden doppelte Probleme als Teil unseres Triage Prozesses entfernen."),(0,i.kt)("li",{parentName:"ul"},"Per E-Mail: E-Mail ",(0,i.kt)("inlineCode",{parentName:"li"},"team@cwtch.im")," mit dem Fehlerbericht und eines unserer Teams wird ihn pr\xfcfen.")),(0,i.kt)("admonition",{title:"Hinweis",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Aufgrund eines Problems mit unserem E-Mail-Provider sind wir derzeit nicht in der Lage, E-Mails von unserer gitea-Instanz zu versenden. Bitte \xfcberpr\xfcfe regelm\xe4\xdfig offene Probleme / Pull-Requests auf Updates (oder abonniere die RSS-Feeds des Projektarchivs)")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b44f0b89.11a8e0bb.js b/build-staging/de/assets/js/b44f0b89.11a8e0bb.js new file mode 100644 index 00000000..462ce8c5 --- /dev/null +++ b/build-staging/de/assets/js/b44f0b89.11a8e0bb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7044],{3905:(e,n,r)=>{r.d(n,{Zo:()=>o,kt:()=>m});var t=r(7294);function i(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?a(Object(r),!0).forEach((function(n){i(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,t,i=function(e,n){if(null==e)return{};var r,t,i={},a=Object.keys(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||(i[r]=e[r]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var u=t.createContext({}),c=function(e){var n=t.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},o=function(e){var n=c(e.components);return t.createElement(u.Provider,{value:n},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,i=e.mdxType,a=e.originalType,u=e.parentName,o=l(e,["components","mdxType","originalType","parentName"]),d=c(r),p=i,m=d["".concat(u,".").concat(p)]||d[p]||h[p]||a;return r?t.createElement(m,s(s({ref:n},o),{},{components:r})):t.createElement(m,s({ref:n},o))}));function m(e,n){var r=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=r.length,s=new Array(a);s[0]=p;var l={};for(var u in n)hasOwnProperty.call(n,u)&&(l[u]=n[u]);l.originalType=e,l[d]="string"==typeof e?e:i,s[1]=l;for(var c=2;c<a;c++)s[c]=r[c];return t.createElement.apply(null,s)}return t.createElement.apply(null,r)}p.displayName="MDXCreateElement"},5810:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var t=r(7462),i=(r(7294),r(3905));const a={},s="Cwtch Server",l={unversionedId:"components/cwtch/server",id:"components/cwtch/server",title:"Cwtch Server",description:"Ziel des Cwtch-Protokolls ist es, die Gruppenkommunikation \xfcber Nicht vertrauensw\xfcrdige Infrastruktur zu aktivieren.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/server.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/server",permalink:"/de/security/components/cwtch/server",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Gruppen",permalink:"/de/security/components/cwtch/groups"},next:{title:"Cwtch UI",permalink:"/de/security/category/cwtch-ui"}},u={},c=[{value:"B\xf6sartige Server",id:"b\xf6sartige-server",level:2},{value:"Erkennbare Fehler",id:"erkennbare-fehler",level:3},{value:"Effizienz",id:"effizienz",level:2}],o={toc:c},d="wrapper";function h(e){let{components:n,...r}=e;return(0,i.kt)(d,(0,t.Z)({},o,r,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"cwtch-server"},"Cwtch Server"),(0,i.kt)("p",null,"Ziel des Cwtch-Protokolls ist es, die Gruppenkommunikation \xfcber ",(0,i.kt)("strong",{parentName:"p"},"Nicht vertrauensw\xfcrdige Infrastruktur")," zu aktivieren."),(0,i.kt)("p",null,"Im Gegensatz zu Relay basierten Schemata, bei denen die Gruppen einen F\xfchrer, einen Satz von F\xfchrern, oder ein vertrauensw\xfcrdiger Server von Drittanbietern zuweisen, um sicherzustellen, dass jedes Mitglied der Gruppe Nachrichten zeitnah senden und empfangen kann (selbst wenn Mitglieder offline sind) - hat die nicht vertrauensw\xfcrdige Infrastruktur das Ziel, diese Eigenschaften zu realisieren ohne Vertrauen anzunehmen."),(0,i.kt)("p",null,"Das urspr\xfcngliche Cwtch-Papier hat eine Reihe von Eigenschaften definiert, die Cwtch-Server erwartbar zur Verf\xfcgung stellen sollten:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Cwtch Server kann von mehreren Gruppen oder nur einer verwendet werden."),(0,i.kt)("li",{parentName:"ul"},"Ein Cwtch Server, ohne Zusammenarbeit mit einem Gruppenmitglied, sollte niemals die Identit\xe4t der Teilnehmer innerhalb einer Gruppe erlernen."),(0,i.kt)("li",{parentName:"ul"},"Ein Cwtch Server sollte niemals den Inhalt einer Kommunikation erlernen."),(0,i.kt)("li",{parentName:"ul"},"Ein Cwtch-Server sollte niemals in der Lage sein, Nachrichten als einer bestimmten Gruppe zugeh\xf6rig unterscheiden zu k\xf6nnen.")),(0,i.kt)("p",null,"Wir stellen hier fest, dass diese Eigenschaften ein Superset der Designziele der privaten Informationsabfrage sind."),(0,i.kt)("h2",{id:"b\xf6sartige-server"},"B\xf6sartige Server"),(0,i.kt)("p",null,"Wir erwarten das Vorhandensein b\xf6sartiger Entit\xe4ten innerhalb des Cwtch-\xd6kosystems."),(0,i.kt)("p",null,"Wir legen auch Wert auf Dezentralisierung und erlaubnisfreien Zugang zum \xd6kosystem und st\xfctzen daher keine Sicherheitsanspr\xfcche auf die folgenden Punkte:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Jede Nicht-Kollusionsannahme zwischen einer Reihe von Cwtch-Servern"),(0,i.kt)("li",{parentName:"ul"},"Jedes von Dritten definierte Pr\xfcfverfahren")),(0,i.kt)("p",null,"Die Peers selbst werden ermutigt, Cwtch-Server einzurichten und zu betreiben, wo sie effizientere Eigenschaften garantieren k\xf6nnen, indem sie die Vertrauens- und Sicherheits Annahmen voraussetzen - standardm\xe4\xdfig ist das Protokoll jedoch so konzipiert, dass es auch ohne diese Annahmen sicher ist - auf Kosten der Effizienz, wo es n\xf6tig ist."),(0,i.kt)("h3",{id:"erkennbare-fehler"},"Erkennbare Fehler"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Wenn ein Cwtch-Server eine bestimmte Nachricht nicht an eine Gruppe von Gruppenmitgliedern weiterleitet, wird es eine erkennbare L\xfccke im Nachrichtenbaum einiger Peers geben, die durch Peer-to-Peer Klatsch entdeckt werden kann."),(0,i.kt)("li",{parentName:"ul"},"Ein Cwtch-Server kann keine Nachricht ohne das Schl\xfcsselmaterial, das der Gruppe bekannt ist, \xe4ndern (jeder Versuch, dies f\xfcr eine Teilmenge von Gruppenmitgliedern zu tun, f\xfchrt dazu, dass es das gleiche Verhalten hat, wie wenn keine Nachricht weitergeleitet wird)."),(0,i.kt)("li",{parentName:"ul"},"W\xe4hrend ein Server Nachrichten duplizieren ",(0,i.kt)("em",{parentName:"li"},"kann"),", haben diese keine Auswirkungen auf den Gruppen-Nachrichtenbaum (aufgrund der Verschl\xfcsselung, Nonces und Nachrichtenidentit\xe4ten) - die Quelle der Vervielf\xe4ltigung ist f\xfcr einen Peer nicht bekannt.")),(0,i.kt)("h2",{id:"effizienz"},"Effizienz"),(0,i.kt)("p",null,'Zum Zeitpunkt des Schreibens dieser Seite ist nur ein Protokoll f\xfcr das Erreichen der gew\xfcnschten Eigenschaften bekannt, naive PIR oder "der Server sendet alles, und die Peers sichten es".'),(0,i.kt)("p",null,"Dies hat einen offensichtlichen Einfluss auf die Effizienz der Bandbreite, insbesondere f\xfcr Peers mit mobilen Ger\xe4ten, als solche entwickeln wir aktiv neue Protokolle, in denen die Datenschutz- und Effizienzgarantien auf unterschiedliche Weise ausgehandelt werden k\xf6nnen."),(0,i.kt)("p",null,"Beim Zeitpunkt des Schreibens dieser Seite erlauben die Server sowohl einen vollst\xe4ndigen Download aller gespeicherten Nachrichten, und eine Anfrage, um Nachrichten von einer bestimmten Nachricht herunterzuladen."),(0,i.kt)("p",null,"Alle Peers, wenn sie einer Gruppe auf einem neuen Server beitreten, laden alle Nachrichten vom Server herunter und von dann an laden sie nur neue Nachrichten."),(0,i.kt)("p",null,(0,i.kt)("em",{parentName:"p"},"Hinweis"),": Dieses Verhalten erlaubt eine milde Form der Metadatenanalyse. Der Server kann neue Nachrichten f\xfcr jedes verd\xe4chtige eindeutige Profil anzeigen und dann diese eindeutigen Signaturen benutzen um eindeutige Sitzungen im Laufe der Zeit zu verfolgen (\xfcber Anfragen f\xfcr neue Nachrichten)."),(0,i.kt)("p",null,"Dies wird durch 2 Verwirrungsfaktoren gemildert:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Profile k\xf6nnen ihre Verbindungen jederzeit aktualisieren - was zu einer neuen Serversitzung f\xfchrt."),(0,i.kt)("li",{parentName:"ol"},'Profile k\xf6nnen jederzeit von einem Server "synchronisieren" - was zu einem neuen Aufruf f\xfchrt, um alle Nachrichten herunterzuladen. Die am meisten verbreitete Benutzungsgrundlage f\xfcr dieses Verhalten ist das Abrufen \xe4lterer Nachrichten aus einer Gruppe.')),(0,i.kt)("p",null,"In Kombination setzen diese 2 Abschw\xe4chungen Grenzen auf das, was der Server herausfinden kann, aber wir k\xf6nnen noch keine vollst\xe4ndige Metadatenresistenz bieten."),(0,i.kt)("p",null,"F\xfcr m\xf6gliche zuk\xfcnftige L\xf6sungen f\xfcr dieses Problem siehe ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/niwl"},"Niwl")),(0,i.kt)("h1",{id:"den-server-wird-vor-b\xf6swilligen-peers-sch\xfctzen"},"Den Server wird vor b\xf6swilligen Peers sch\xfctzen"),(0,i.kt)("p",null,"Das Hauptrisiko f\xfcr Server besteht in Form von Spam, der von Peers erzeugt wird. Im Prototyp von Cwtch wurde ein Spamschutzmechanismus eingef\xfchrt, der von anderen Peers verlangte, einen willk\xfcrlichen Nachweis der Arbeit mit einem server-spezifizierten Parameter durchzuf\xfchren."),(0,i.kt)("p",null,"Dies ist keine robuste L\xf6sung in Anwesenheit eines bestimmten Gegners mit einer betr\xe4chtlichen Menge an Ressourcen und damit wird eines der wichtigsten externen Risiken f\xfcr das Cwtch-System wird Zensur-Via-Ressourcen-Ersch\xf6pfung."),(0,i.kt)("p",null,"Wir haben eine m\xf6gliche L\xf6sung daf\xfcr in ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/research/OPTR2019-01/"},"Token basierten Diensten")," skizziert, aber beachte, dass dies ebenfalls weiterentwickelt werden muss."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b802a7ab.531ba26b.js b/build-staging/de/assets/js/b802a7ab.531ba26b.js new file mode 100644 index 00000000..be2b601d --- /dev/null +++ b/build-staging/de/assets/js/b802a7ab.531ba26b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[716],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(r),d=a,h=p["".concat(s,".").concat(d)]||p[d]||f[d]||o;return r?n.createElement(h,i(i({ref:t},u),{},{components:r})):n.createElement(h,i({ref:t},u))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=r[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},5576:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:5},i="Auf eine Nachricht antworten",c={unversionedId:"chat/reply-to-message",id:"chat/reply-to-message",title:"Auf eine Nachricht antworten",description:"1. W\xe4hle eine Nachricht aus, auf die du antworten m\xf6chtest",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/reply-to-message.md",sourceDirName:"chat",slug:"/chat/reply-to-message",permalink:"/de/docs/chat/reply-to-message",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/reply-to-message.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Konversationseinstellungen aufrufen",permalink:"/de/docs/chat/conversation-settings"},next:{title:"Eine Datei teilen",permalink:"/de/docs/chat/share-file"}},s={},l=[],u={toc:l},p="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"auf-eine-nachricht-antworten"},"Auf eine Nachricht antworten"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"W\xe4hle eine Nachricht aus, auf die du antworten m\xf6chtest"),(0,a.kt)("li",{parentName:"ol"},"Nachricht nach rechts ziehen"),(0,a.kt)("li",{parentName:"ol"},"Eine Antwort auf die zitierte Nachricht schreiben"),(0,a.kt)("li",{parentName:"ol"},"Senden anklicken")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b877509f.c2fadaf5.js b/build-staging/de/assets/js/b877509f.c2fadaf5.js new file mode 100644 index 00000000..ae86225c --- /dev/null +++ b/build-staging/de/assets/js/b877509f.c2fadaf5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[380],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>m});var i=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function c(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){r(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,i,r=function(e,n){if(null==e)return{};var t,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)t=o[i],n.indexOf(t)>=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)t=o[i],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var a=i.createContext({}),l=function(e){var n=i.useContext(a),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},u=function(e){var n=l(e.components);return i.createElement(a.Provider,{value:n},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},d=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,a=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(t),d=r,m=p["".concat(a,".").concat(d)]||p[d]||h[d]||o;return t?i.createElement(m,c(c({ref:n},u),{},{components:t})):i.createElement(m,c({ref:n},u))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,c=new Array(o);c[0]=d;var s={};for(var a in n)hasOwnProperty.call(n,a)&&(s[a]=n[a]);s.originalType=e,s[p]="string"==typeof e?e:r,c[1]=s;for(var l=2;l<o;l++)c[l]=t[l];return i.createElement.apply(null,c)}return i.createElement.apply(null,t)}d.displayName="MDXCreateElement"},1493:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var i=t(7462),r=(t(7294),t(3905));const o={sidebar_position:1.5},c="Komponenten Ecosystem \xdcbersicht",s={unversionedId:"components/ecosystem-overview",id:"components/ecosystem-overview",title:"Komponenten Ecosystem \xdcbersicht",description:"Cwtch besteht aus mehreren kleineren Komponenten-Bibliotheken. Dieses Kapitel gibt einen kurzen \xdcberblick \xfcber jede Komponente und wie sie sich auf das gr\xf6\xdfere Cwtch-\xd6kosystem bezieht.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ecosystem-overview.md",sourceDirName:"components",slug:"/components/ecosystem-overview",permalink:"/de/security/components/ecosystem-overview",draft:!1,tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Cwtch technische Grundlagen",permalink:"/de/security/components/intro"},next:{title:"Connectivity & Tor",permalink:"/de/security/category/connectivity--tor"}},a={},l=[{value:"offene Privatsph\xe4re/Konnektivit\xe4t",id:"offene-privatsph\xe4rekonnektivit\xe4t",level:2},{value:"cwtch.im/tapir",id:"cwtchimtapir",level:2},{value:"cwtch.im/cwtch",id:"cwtchimcwtch",level:2},{value:"cwtch.im/libcwtch-go",id:"cwtchimlibcwtch-go",level:2},{value:"cwtch-ui",id:"cwtch-ui",level:2},{value:"Zus\xe4tzliche Komponenten",id:"zus\xe4tzliche-komponenten",level:2},{value:"openprivacy/log",id:"openprivacylog",level:3}],u={toc:l},p="wrapper";function h(e){let{components:n,...t}=e;return(0,r.kt)(p,(0,i.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"komponenten-ecosystem-\xfcbersicht"},"Komponenten Ecosystem \xdcbersicht"),(0,r.kt)("p",null,"Cwtch besteht aus mehreren kleineren Komponenten-Bibliotheken. Dieses Kapitel gibt einen kurzen \xdcberblick \xfcber jede Komponente und wie sie sich auf das gr\xf6\xdfere Cwtch-\xd6kosystem bezieht."),(0,r.kt)("h2",{id:"offene-privatsph\xe4rekonnektivit\xe4t"},(0,r.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"offene Privatsph\xe4re/Konnektivit\xe4t")),(0,r.kt)("p",null,"Zusammenfassung: Eine Bibliothek, die eine ACN (Anonymous Communication Network ) Netzwerkabstraktion zur Verf\xfcgung stellt."),(0,r.kt)("p",null,"Das Ziel der Konnektivit\xe4t ist es, die zugrunde liegenden Bibliotheken/Software zu abstrahieren, die f\xfcr die Kommunikation mit einer spezifischen ACN ben\xf6tigt wird. Zurzeit unterst\xfctzen wir nur Tor und deshalb ist die Aufgabe der Verbindung folgendes:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Start und Stopp des Tor Prozesses"),(0,r.kt)("li",{parentName:"ul"},"Bereitstellen der Konfiguration des Tor-Prozesses"),(0,r.kt)("li",{parentName:"ul"},"Erlaube unver\xe4nderte Verbindungen zu Endpunkten \xfcber den Tor-Prozess (z.B. Verbindung mit Onion-Diensten)"),(0,r.kt)("li",{parentName:"ul"},"Endpunkte \xfcber den Tor-Prozess zur Verf\xfcgung stellen (z.B. Host-Onion-Dienste)"),(0,r.kt)("li",{parentName:"ul"},"Statusaktualisierungen \xfcber den zugrunde liegenden Tor-Prozess bereitstellen")),(0,r.kt)("p",null,"F\xfcr weitere Informationen siehe ",(0,r.kt)("a",{parentName:"p",href:"/security/components/connectivity/intro"},"Konnektivit\xe4t")),(0,r.kt)("h2",{id:"cwtchimtapir"},(0,r.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/tapir"},"cwtch.im/tapir")),(0,r.kt)("p",null,"Zusammenfassung: Tapir ist eine kleine Bibliothek f\xfcr das Erstellen von p2p Anwendungen \xfcber anonyme Kommunikationssysteme."),(0,r.kt)("p",null,"Das Ziel von Tapir ist es, ",(0,r.kt)("strong",{parentName:"p"},"Anwendungen")," \xfcber eine bestimmte ACN zu abstrahieren. Tapir unterst\xfctzt:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Erstellen einer kryptographischen Identit\xe4t (einschlie\xdflich kurzlebiger Identit\xe4ten)"),(0,r.kt)("li",{parentName:"ul"},"Wartung eines Verbindungspools von eingehenden und ausgehenden Verbindungen zu Diensten"),(0,r.kt)("li",{parentName:"ul"},"Behandlung verschiedener Anwendungsschichten, einschlie\xdflich kryptographischer Transkripte, ",(0,r.kt)("a",{parentName:"li",href:"/security/components/tapir/authentication_protocol"},"Authentifizierungs- und Autorisierungsprotokolle"),"und ",(0,r.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"Token-basierte Dienste \xfcber PrivacyPass"),",")),(0,r.kt)("p",null,"F\xfcr weitere Informationen siehe ",(0,r.kt)("a",{parentName:"p",href:"/security/components/tapir/authentication_protocol"},"Tapir")),(0,r.kt)("h2",{id:"cwtchimcwtch"},(0,r.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"cwtch.im/cwtch")),(0,r.kt)("p",null,"Zusammenfassung: Cwtch ist die Hauptbibliothek f\xfcr die Implementierung des Cwtch-Protokolls / System."),(0,r.kt)("p",null,"Das Ziel von Cwtch ist die Bereitstellung von Implementierungen f\xfcr cwtch-spezifische Anwendungen wie z.B. Nachrichtensendung, Gruppen und Dateifreigabe (implementiert als Tapir Anwendungen), Schnittstellen zur Verwaltung und Speicherung von Cwtch Profilen, bietet neben der Verwaltung anderer Kernfunktionen auch einen Eventbus f\xfcr Subsystem Splitting und das Erstellen von Plugins mit neuen Funktionen."),(0,r.kt)("p",null,"Die Cwtch Bibliothek ist auch f\xfcr die Pflege kanonischer Modelldarstellungen f\xfcr Formate und Overlays zust\xe4ndig."),(0,r.kt)("h2",{id:"cwtchimlibcwtch-go"},(0,r.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"cwtch.im/libcwtch-go")),(0,r.kt)("p",null,"Zusammenfassung: libcwtch-go stellt C (auch f\xfcr Android) Bindungen f\xfcr Cwtch bereit f\xfcr die Benutzung in UI Implementierungen."),(0,r.kt)("p",null,"Das Ziel von libcwtch-go ist es, die L\xfccke zwischen der Backend Cwtch Bibliothek und allen Frontend-Systemen zu \xfcberbr\xfccken, die in einer anderen Sprache geschrieben werden k\xf6nnen."),(0,r.kt)("p",null,"Die von libcwtch bereitgestellte API ist wesentlich eingeschr\xe4nkter als die von Cwtch direkt bereitgestellte API, jede libcwtch API paketiert normalerweise mehrere Aufrufe an Cwtch."),(0,r.kt)("p",null,"libcwtch-go ist auch f\xfcr die Verwaltung der UI-Einstellungen und des experimentellen Gateways zust\xe4ndig. Es wird auch oft als Staging-Boden f\xfcr experimentelle Funktionen und Code verwendet, die m\xf6glicherweise am Ende in Cwtch enden."),(0,r.kt)("h2",{id:"cwtch-ui"},(0,r.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui"},"cwtch-ui")),(0,r.kt)("p",null,"Zusammenfassung: Eine flutterbasierte Oberfl\xe4che (UI) f\xfcr Cwtch."),(0,r.kt)("p",null,"Cwtch UI verwendet libcwtch-go um ein vollst\xe4ndiges UI f\xfcr Cwtch bereitzustellen, das es Leuten erm\xf6glicht, Profile zu erstellen und zu verwalten, Kontakte und Gruppen hinzuzuf\xfcgen, Nachrichten zu versenden, Dateien freizugeben (bald) und vieles mehr."),(0,r.kt)("p",null,"Das UI ist auch f\xfcr die Verwaltung von Lokalisierung und \xdcbersetzungen zust\xe4ndig."),(0,r.kt)("p",null,"F\xfcr weitere Informationen siehe ",(0,r.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"Cwtch UI")),(0,r.kt)("h2",{id:"zus\xe4tzliche-komponenten"},"Zus\xe4tzliche Komponenten"),(0,r.kt)("p",null,"Gelegentlich wird Open Privacy Teile von Cwtch in eigenst\xe4ndige Bibliotheken einbeziehen, die nicht Cwtch spezifisch sind. Diese werden hier kurz zusammengefasst:"),(0,r.kt)("h3",{id:"openprivacylog"},(0,r.kt)("a",{parentName:"h3",href:"https://git.openprivacy.ca/openprivacy/log"},"openprivacy/log")),(0,r.kt)("p",null,"Ein Open Privacy spezifisches Logging-Framework, das in allen Cwtch Paketen verwendet wird."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b95aefa5.eb30a5e8.js b/build-staging/de/assets/js/b95aefa5.eb30a5e8.js new file mode 100644 index 00000000..448e48c2 --- /dev/null +++ b/build-staging/de/assets/js/b95aefa5.eb30a5e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5674],{8474:a=>{a.exports=JSON.parse('{"label":"autobindings","permalink":"/de/blog/tags/autobindings","allTagsPath":"/de/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/b96d814b.8e446437.js b/build-staging/de/assets/js/b96d814b.8e446437.js new file mode 100644 index 00000000..efc1c934 --- /dev/null +++ b/build-staging/de/assets/js/b96d814b.8e446437.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5883],{4331:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/libcwtch","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/bba9d075.462177c6.js b/build-staging/de/assets/js/bba9d075.462177c6.js new file mode 100644 index 00000000..1964159a --- /dev/null +++ b/build-staging/de/assets/js/bba9d075.462177c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[769],{595:e=>{e.exports=JSON.parse('{"title":"Tapir","slug":"/category/tapir","permalink":"/de/security/category/tapir","navigation":{"previous":{"title":"Verbindung","permalink":"/de/security/components/connectivity/intro"},"next":{"title":"Paketformat","permalink":"/de/security/components/tapir/packet_format"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/bf059cf9.2c6d0b26.js b/build-staging/de/assets/js/bf059cf9.2c6d0b26.js new file mode 100644 index 00000000..8c4985b0 --- /dev/null +++ b/build-staging/de/assets/js/bf059cf9.2c6d0b26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5273],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>b});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,i,n=function(e,t){if(null==e)return{};var r,i,n={},a=Object.keys(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=i.createContext({}),s=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=s(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),p=s(r),g=n,b=p["".concat(l,".").concat(g)]||p[g]||u[g]||a;return r?i.createElement(b,o(o({ref:t},d),{},{components:r})):i.createElement(b,o({ref:t},d))}));function b(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=g;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:n,o[1]=c;for(var s=2;s<a;s++)o[s]=r[s];return i.createElement.apply(null,o)}return i.createElement.apply(null,r)}g.displayName="MDXCreateElement"},2626:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/de/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"10. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/de/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"repliqate",permalink:"/de/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/de/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/de/blog/cwtch-testing-i"}},l={authorsImageUrls:[void 0]},s=[],d={toc:s},p="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,i.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(4756).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},4756:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/bfe3d434.1ebf7514.js b/build-staging/de/assets/js/bfe3d434.1ebf7514.js new file mode 100644 index 00000000..2c5e8899 --- /dev/null +++ b/build-staging/de/assets/js/bfe3d434.1ebf7514.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6295],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>v});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),d=l(r),m=i,v=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(v,s(s({ref:t},p),{},{components:r})):n.createElement(v,s({ref:t},p))}));function v(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,s=new Array(o);s[0]=m;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[d]="string"==typeof e?e:i,s[1]=a;for(var l=2;l<o;l++)s[l]=r[l];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8195:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:4},s="Wie man einen Server l\xf6scht",a={unversionedId:"servers/delete-server",id:"servers/delete-server",title:"Wie man einen Server l\xf6scht",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/delete-server.md",sourceDirName:"servers",slug:"/servers/delete-server",permalink:"/de/docs/servers/delete-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/delete-server.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Wie man einen Server bearbeitet",permalink:"/de/docs/servers/edit-server"},next:{title:"Wie du dein Server-Schl\xfcsselpaket teilst",permalink:"/de/docs/servers/share-key"}},c={},l=[],p={toc:l},d="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"wie-man-einen-server-l\xf6scht"},"Wie man einen Server l\xf6scht"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," eingeschaltet ist.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zum Server-Symbol gehen"),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle den Server aus, den du l\xf6schen m\xf6chtest"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke das Stift-Symbol"),(0,i.kt)("li",{parentName:"ol"},"Scrolle nach unten und gib dein Passwort ein"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke L\xf6schen"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke wirklich L\xf6schen"),(0,i.kt)("li",{parentName:"ol"},"Dein Server ist gel\xf6scht")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Server_Delete.mp4"}))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c089f5db.d346cd81.js b/build-staging/de/assets/js/c089f5db.d346cd81.js new file mode 100644 index 00000000..349cd1d7 --- /dev/null +++ b/build-staging/de/assets/js/c089f5db.d346cd81.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4240],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>m});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function l(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function a(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=n.createContext({}),s=function(e){var r=n.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):l(l({},r),e)),t},c=function(e){var r=s(e.components);return n.createElement(p.Provider,{value:r},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),f=s(t),d=i,m=f["".concat(p,".").concat(d)]||f[d]||u[d]||o;return t?n.createElement(m,l(l({ref:r},c),{},{components:t})):n.createElement(m,l({ref:r},c))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,l=new Array(o);l[0]=d;var a={};for(var p in r)hasOwnProperty.call(r,p)&&(a[p]=r[p]);a.originalType=e,a[f]="string"==typeof e?e:i,l[1]=a;for(var s=2;s<o;s++)l[s]=t[s];return n.createElement.apply(null,l)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},9830:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>s});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:10},l="Sicherung oder Export eines Profils",a={unversionedId:"profiles/exporting-profile",id:"profiles/exporting-profile",title:"Sicherung oder Export eines Profils",description:"Auf der Profil-Verwaltungsseite:",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/exporting-profile.md",sourceDirName:"profiles",slug:"/profiles/exporting-profile",permalink:"/de/docs/profiles/exporting-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/exporting-profile.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Ein Profil l\xf6schen",permalink:"/de/docs/profiles/delete-profile"},next:{title:"Profil importieren",permalink:"/de/docs/profiles/importing-a-profile"}},p={},s=[],c={toc:s},f="wrapper";function u(e){let{components:r,...t}=e;return(0,i.kt)(f,(0,n.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"sicherung-oder-export-eines-profils"},"Sicherung oder Export eines Profils"),(0,i.kt)("p",null,"Auf der Profil-Verwaltungsseite:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Klicke auf den Stift neben dem Profil, das du bearbeiten m\xf6chtest"),(0,i.kt)("li",{parentName:"ol"},"Scrolle nach unten zum Ende des Bildschirms"),(0,i.kt)("li",{parentName:"ol"},'W\xe4hle "Export Profil"'),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle einen Ort und einen Dateinamen"),(0,i.kt)("li",{parentName:"ol"},"Best\xe4tigen")),(0,i.kt)("p",null,"Nach der Best\xe4tigung wird Cwtch eine Kopie des Profils an der angegebenen Stelle ablegen. Diese Datei wird auf die gleiche Stufe verschl\xfcsselt wie das Profil. Siehe ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"Eine Notiz \xfcber passwortgesch\xfctzte (verschl\xfcsselte) Profile")," f\xfcr weitere Informationen zu verschl\xfcsselten Profilen."),(0,i.kt)("p",null,"Diese Datei kann in eine andere Cwtch-Instanz auf jedem Ger\xe4t ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/importing-a-profile"},"importiert")," werden."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c1102df1.a3659bd9.js b/build-staging/de/assets/js/c1102df1.a3659bd9.js new file mode 100644 index 00000000..f3f047ba --- /dev/null +++ b/build-staging/de/assets/js/c1102df1.a3659bd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8225],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var u=r.createContext({}),s=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},l=function(e){var t=s(e.components);return r.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,u=e.parentName,l=o(e,["components","mdxType","originalType","parentName"]),d=s(n),h=i,m=d["".concat(u,".").concat(h)]||d[h]||p[h]||a;return n?r.createElement(m,c(c({ref:t},l),{},{components:n})):r.createElement(m,c({ref:t},l))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,c=new Array(a);c[0]=h;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o[d]="string"==typeof e?e:i,c[1]=o;for(var s=2;s<a;s++)c[s]=n[s];return r.createElement.apply(null,c)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},7816:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>o,toc:()=>s});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:2},c="Cwtch \xfcbersetzen",o={unversionedId:"contribute/translate",id:"contribute/translate",title:"Cwtch \xfcbersetzen",description:"Wenn du \xdcbersetzungen zu Cwtch beitragen m\xf6chtest, entweder zur App oder zu diesem Handbuch, kommt hier wie dies m\xf6glich ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/translate.md",sourceDirName:"contribute",slug:"/contribute/translate",permalink:"/de/docs/contribute/translate",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/translate.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch testen",permalink:"/de/docs/contribute/testing"},next:{title:"Stilregeln der Dokumentation",permalink:"/de/docs/contribute/documentation"}},u={},s=[{value:"\xdcbersetzungen zur Cwtch-Anwendung beitragen",id:"\xfcbersetzungen-zur-cwtch-anwendung-beitragen",level:2},{value:"Trete unserem Lokalise-Team bei",id:"trete-unserem-lokalise-team-bei",level:3},{value:"Direkt \xfcber Git",id:"direkt-\xfcber-git",level:3},{value:"Cwtch-Benutzerhandbuch",id:"cwtch-benutzerhandbuch",level:2}],l={toc:s},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"cwtch-\xfcbersetzen"},"Cwtch \xfcbersetzen"),(0,i.kt)("p",null,"Wenn du \xdcbersetzungen zu Cwtch beitragen m\xf6chtest, entweder zur App oder zu diesem Handbuch, kommt hier wie dies m\xf6glich ist."),(0,i.kt)("h2",{id:"\xfcbersetzungen-zur-cwtch-anwendung-beitragen"},"\xdcbersetzungen zur Cwtch-Anwendung beitragen"),(0,i.kt)("p",null,"Es gibt zwei M\xf6glichkeiten, zu Cwtch Anwendungen beizutragen."),(0,i.kt)("h3",{id:"trete-unserem-lokalise-team-bei"},"Trete unserem Lokalise-Team bei"),(0,i.kt)("p",null,"Wir verwenden ",(0,i.kt)("a",{parentName:"p",href:"https://lokalise.com"},"Lokalise")," f\xfcr die Verwaltung von \xdcbersetzungen f\xfcr die Cwtch-Anwendung."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Registriere dich f\xfcr ein Lokalise-Konto"),(0,i.kt)("li",{parentName:"ol"},"Sende eine E-Mail an ",(0,i.kt)("a",{parentName:"li",href:"mailto:team@cwtch.im"},"team@cwtch.im")," mit der Sprache, die du \xfcbersetzen m\xf6chtest und einer E-Mail-Adresse, mit der wir dich in unser Lokalise-Team einladen k\xf6nnen.")),(0,i.kt)("h3",{id:"direkt-\xfcber-git"},"Direkt \xfcber Git"),(0,i.kt)("p",null,"F\xfcr neue \xdcbersetzungen, kannst du eine Kopie von ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb")," erstellen und \xfcbersetzen - Du kannst dann entweder ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/developing#cwtch-pull-request-process"},"Pull-Requests einreichen oder direkt")," Aktualisierungen an uns senden (",(0,i.kt)("a",{parentName:"p",href:"mailto:team@cwtch.im"},"team@cwtch.im"),") und wir werden sie zusammenf\xfchren."),(0,i.kt)("p",null,"Um zu existierenden \xdcbersetzungen hinzuzuf\xfcgen, kannst du Pull-Requests direkt auf jede Datei in ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/")," einstellen und wir werden sie \xfcberpr\xfcfen und zusammenf\xfchren."),(0,i.kt)("h2",{id:"cwtch-benutzerhandbuch"},"Cwtch-Benutzerhandbuch"),(0,i.kt)("p",null,"Dieses Handbuch wird \xfcber ",(0,i.kt)("a",{parentName:"p",href:"https://crowdin.com"},"Crowdin")," \xfcbersetzt."),(0,i.kt)("p",null,"Um unserem Crowdin-Projekt beizutreten:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Registrieren dich f\xfcr ein Konto bei ",(0,i.kt)("a",{parentName:"li",href:"https://crowdin.com"},"Crowdin"),"."),(0,i.kt)("li",{parentName:"ol"},"Treten dem ",(0,i.kt)("a",{parentName:"li",href:"https://crowdin.com/project/cwtch-users-handbook"},"cwtch-users-handbook Projekt")," bei.")),(0,i.kt)("p",null,"Wir b\xfcndeln \xc4nderungen an der Dokumentation in Batches und synchronisieren sie regelm\xe4\xdfig mit dem Crowdin-Projekt."),(0,i.kt)("admonition",{title:"Hinweis",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"Alle Beitr\xe4ge sind ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"berechtigt f\xfcr Aufkleber"))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c14f15fd.0a8c6726.js b/build-staging/de/assets/js/c14f15fd.0a8c6726.js new file mode 100644 index 00000000..f560ea37 --- /dev/null +++ b/build-staging/de/assets/js/c14f15fd.0a8c6726.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7649],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,f=u["".concat(s,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},3071:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:2},i="Core Concepts",c={unversionedId:"building-a-cwtch-app/core-concepts",id:"building-a-cwtch-app/core-concepts",title:"Core Concepts",description:"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.",source:"@site/developing/building-a-cwtch-app/core-concepts.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/core-concepts",permalink:"/de/developing/building-a-cwtch-app/core-concepts",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Getting Started",permalink:"/de/developing/building-a-cwtch-app/intro"},next:{title:"Building a Cwtch Echobot",permalink:"/de/developing/building-a-cwtch-app/building-an-echobot"}},s={},l=[{value:"Cwtch Home Directory",id:"cwtch-home-directory",level:2},{value:"Profiles",id:"profiles",level:2},{value:"The Event Bus",id:"the-event-bus",level:2},{value:"Settings",id:"settings",level:2},{value:"Experiments",id:"experiments",level:3}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"core-concepts"},"Core Concepts"),(0,a.kt)("p",null,"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently."),(0,a.kt)("h2",{id:"cwtch-home-directory"},"Cwtch Home Directory"),(0,a.kt)("p",null,"Often referred to as ",(0,a.kt)("inlineCode",{parentName:"p"},"$CWTCH_HOME"),", the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application."),(0,a.kt)("h2",{id:"profiles"},"Profiles"),(0,a.kt)("p",null,"Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations."),(0,a.kt)("h2",{id:"the-event-bus"},"The Event Bus"),(0,a.kt)("p",null,"Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"NewMessageFromPeer")," and setup an event handler to run code in response to such a message."),(0,a.kt)("p",null,"For an example see the Echo Bot tutorial."),(0,a.kt)("h2",{id:"settings"},"Settings"),(0,a.kt)("p",null,"Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration."),(0,a.kt)("h3",{id:"experiments"},"Experiments"),(0,a.kt)("p",null,"Certain Cwtch features are ",(0,a.kt)("a",{parentName:"p",href:"/docs/category/experiments"},"gated behind experiments"),". These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c2f21224.75b22dc5.js b/build-staging/de/assets/js/c2f21224.75b22dc5.js new file mode 100644 index 00000000..8409f485 --- /dev/null +++ b/build-staging/de/assets/js/c2f21224.75b22dc5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5107],{4167:e=>{e.exports=JSON.parse('{"title":"Cwtch-UI","slug":"/category/cwtch-ui","permalink":"/de/security/category/cwtch-ui","navigation":{"previous":{"title":"Cwtch Server","permalink":"/de/security/components/cwtch/server"},"next":{"title":"Android Dienst","permalink":"/de/security/components/ui/android"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c4f5d8e4.ea3b76f3.js b/build-staging/de/assets/js/c4f5d8e4.ea3b76f3.js new file mode 100644 index 00000000..a46a88c5 --- /dev/null +++ b/build-staging/de/assets/js/c4f5d8e4.ea3b76f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4195],{3261:(e,t,n)=>{n.r(t),n.d(t,{default:()=>m});var a=n(7294),l=n(6010),r=n(7961),o=n(9960),s=n(2263);const c={heroBanner:"heroBanner_qdFl",buttons:"buttons_AeoN",button:"button_JGCe"};var i=n(5999);const u=[{id:1,title:a.createElement(i.Z,null,"The Cwtch Handbook")},{id:2,title:a.createElement(i.Z,null,"Your Guide to setting up, and using, Surveillance Resistant Infrastructure")},{id:3,title:a.createElement(i.Z,null,"Get Started With Cwtch")}];function h(){const{siteConfig:e}=(0,s.Z)();return a.createElement("header",{className:(0,l.Z)("hero hero--primary",c.heroBanner)},a.createElement("div",{className:"container"},a.createElement("h1",{className:"hero__title"},u[0].title),a.createElement("p",{className:"hero__subtitle"},u[1].title),a.createElement("div",{className:c.buttons},a.createElement(o.Z,{className:"button button--secondary button--lg",to:"/docs/intro"},u[2].title))))}function m(){const{siteConfig:e}=(0,s.Z)();return a.createElement(r.Z,{title:`${e.title}`,description:"The Cwtch Handbook"},a.createElement(h,null),a.createElement("main",null))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c5f4eaa1.abb16b7e.js b/build-staging/de/assets/js/c5f4eaa1.abb16b7e.js new file mode 100644 index 00000000..2ca6e047 --- /dev/null +++ b/build-staging/de/assets/js/c5f4eaa1.abb16b7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8943],{3905:(e,n,r)=>{r.d(n,{Zo:()=>p,kt:()=>m});var t=r(7294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function a(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){o(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,t,o=function(e,n){if(null==e)return{};var r,t,o={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=t.createContext({}),l=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):a(a({},n),e)),r},p=function(e){var n=l(e.components);return t.createElement(s.Provider,{value:n},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),d=o,m=u["".concat(s,".").concat(d)]||u[d]||f[d]||i;return r?t.createElement(m,a(a({ref:n},p),{},{components:r})):t.createElement(m,a({ref:n},p))}));function m(e,n){var r=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var c={};for(var s in n)hasOwnProperty.call(n,s)&&(c[s]=n[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l<i;l++)a[l]=r[l];return t.createElement.apply(null,a)}return t.createElement.apply(null,r)}d.displayName="MDXCreateElement"},3401:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=r(7462),o=(r(7294),r(3905));const i={sidebar_position:2},a="\xc4ndern Deines Anzeigenamens",c={unversionedId:"profiles/change-name",id:"profiles/change-name",title:"\xc4ndern Deines Anzeigenamens",description:"1. In der Ansicht Profile verwalten, klicke auf den Stift neben dem Profil, das Du bearbeiten m\xf6chtest",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/change-name.md",sourceDirName:"profiles",slug:"/profiles/change-name",permalink:"/de/docs/profiles/change-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-name.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Ein neues Profil erstellen",permalink:"/de/docs/profiles/create-a-profile"},next:{title:"Passwort \xe4ndern",permalink:"/de/docs/profiles/change-password"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:n,...r}=e;return(0,o.kt)(u,(0,t.Z)({},p,r,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"\xe4ndern-deines-anzeigenamens"},"\xc4ndern Deines Anzeigenamens"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"In der Ansicht Profile verwalten, klicke auf den Stift neben dem Profil, das Du bearbeiten m\xf6chtest"),(0,o.kt)("li",{parentName:"ol"},"\xc4ndere deinen Namen"),(0,o.kt)("li",{parentName:"ol"},"Profil speichern klicken")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c747432f.92e780a0.js b/build-staging/de/assets/js/c747432f.92e780a0.js new file mode 100644 index 00000000..3aa7b480 --- /dev/null +++ b/build-staging/de/assets/js/c747432f.92e780a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8835],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>u});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),p=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(c.Provider,{value:t},e.children)},m="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=p(n),d=a,u=m["".concat(c,".").concat(d)]||m[d]||g[d]||o;return n?i.createElement(u,r(r({ref:t},s),{},{components:n})):i.createElement(u,r({ref:t},s))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[m]="string"==typeof e?e:a,r[1]=l;for(var p=2;p<o;p++)r[p]=n[p];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}d.displayName="MDXCreateElement"},2090:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const o={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/de/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"3. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/de/blog/tags/bindings"},{label:"autobindings",permalink:"/de/blog/tags/autobindings"},{label:"libcwtch",permalink:"/de/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/de/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/de/blog/autobindings"}},c={authorsImageUrls:[void 0]},p=[],s={toc:p},m="wrapper";function g(e){let{components:t,...o}=e;return(0,a.kt)(m,(0,i.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c862d987.cd734824.js b/build-staging/de/assets/js/c862d987.cd734824.js new file mode 100644 index 00000000..3201361e --- /dev/null +++ b/build-staging/de/assets/js/c862d987.cd734824.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3906],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),l=p(r),f=i,d=l["".concat(c,".").concat(f)]||l[f]||m[f]||o;return r?n.createElement(d,a(a({ref:t},u),{},{components:r})):n.createElement(d,a({ref:t},u))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[l]="string"==typeof e?e:i,a[1]=s;for(var p=2;p<o;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},1765:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:6},a="Nachrichtenformatierung",s={unversionedId:"settings/experiments/message-formatting",id:"settings/experiments/message-formatting",title:"Nachrichtenformatierung",description:"Wenn aktiviert, \xe4ndert diese experimentelle Funktion die Konversationsbox um Nachrichtenformatierung UX hinzuzuf\xfcgen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/message-formatting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/message-formatting",permalink:"/de/docs/settings/experiments/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/message-formatting.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Experiment klickbarer Links",permalink:"/de/docs/settings/experiments/clickable-links"},next:{title:"QR Codes",permalink:"/de/docs/settings/experiments/qrcodes"}},c={},p=[],u={toc:p},l="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"nachrichtenformatierung"},"Nachrichtenformatierung"),(0,i.kt)("p",null,"Wenn aktiviert, \xe4ndert diese experimentelle Funktion die Konversationsbox um ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/message-formatting"},"Nachrichtenformatierung")," UX hinzuzuf\xfcgen."),(0,i.kt)("p",null,"Diese experimentelle Funktion ist nun standardm\xe4\xdfig aktiviert."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c94c4dfb.5e3bcaf2.js b/build-staging/de/assets/js/c94c4dfb.5e3bcaf2.js new file mode 100644 index 00000000..2d748b75 --- /dev/null +++ b/build-staging/de/assets/js/c94c4dfb.5e3bcaf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9146],{4469:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c96c5262.e2f3c8a0.js b/build-staging/de/assets/js/c96c5262.e2f3c8a0.js new file mode 100644 index 00000000..606b288a --- /dev/null +++ b/build-staging/de/assets/js/c96c5262.e2f3c8a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3761],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(a),h=r,u=d["".concat(s,".").concat(h)]||d[h]||m[h]||i;return a?n.createElement(u,o(o({ref:t},p),{},{components:a})):n.createElement(u,o({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:r,o[1]=l;for(var c=2;c<i;c++)o[c]=a[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},5426:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/de/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"29. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"release",permalink:"/de/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/de/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/de/blog/cwtch-documentation"}},s={authorsImageUrls:[void 0]},c=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},d="wrapper";function m(e){let{components:t,...i}=e;return(0,r.kt)(d,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(5595).Z},(0,r.kt)("img",{src:a(9573).Z,width:"1341",height:"866"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.11")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Based on new Reproducible Cwtch Stable Autobuilds")," - this is the first release of cwtch based on ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings")," in addition to our new ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Two New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Slovak")," and ",(0,r.kt)("strong",{parentName:"li"},"Korean")))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"When preserving a message draft, quoted messages are now also saved"),(0,r.kt)("li",{parentName:"ul"},"Layout issues caused by pathological unicode are now prevented"),(0,r.kt)("li",{parentName:"ul"},"Improved performance of message row rendering"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Links in replies are now selectable"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Fixed error when highlighting certain URIs "),(0,r.kt)("li",{parentName:"ul"},"File Downloading: Fixes for file downloading and exporting on 32bit Android devices"),(0,r.kt)("li",{parentName:"ul"},"Server Hosting: Fixes for several layout issues"),(0,r.kt)("li",{parentName:"ul"},"Build pipeline now runs automated UI tests"),(0,r.kt)("li",{parentName:"ul"},"Fix issues caused by scrollbar controller overriding"),(0,r.kt)("li",{parentName:"ul"},"Initial support for the Blodeuwedd Assistant (currently compile-time disabled)"),(0,r.kt)("li",{parentName:"ul"},"Cwtch Library:",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"New Stable Cwtch Peer API")),(0,r.kt)("li",{parentName:"ul"},"Ported File Downloading and Image Previews experiments into Cwtch"))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.11 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"2023-03-16-15-07-v0.0.3-1-g50c853a"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}m.isMDXComponent=!0},5595:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},6094:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"},9573:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/c97dce39.f8e42b29.js b/build-staging/de/assets/js/c97dce39.f8e42b29.js new file mode 100644 index 00000000..4fda59d5 --- /dev/null +++ b/build-staging/de/assets/js/c97dce39.f8e42b29.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5843],{992:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/api","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/cc484fa2.2ca9fa40.js b/build-staging/de/assets/js/cc484fa2.2ca9fa40.js new file mode 100644 index 00000000..e7fc1705 --- /dev/null +++ b/build-staging/de/assets/js/cc484fa2.2ca9fa40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2233],{3905:(e,n,r)=>{r.d(n,{Zo:()=>l,kt:()=>f});var t=r(7294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){a(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,t,a=function(e,n){if(null==e)return{};var r,t,a={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=t.createContext({}),s=function(e){var n=t.useContext(p),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},l=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=s(r),d=a,f=u["".concat(p,".").concat(d)]||u[d]||m[d]||i;return r?t.createElement(f,o(o({ref:n},l),{},{components:r})):t.createElement(f,o({ref:n},l))}));function f(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var c={};for(var p in n)hasOwnProperty.call(n,p)&&(c[p]=n[p]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var s=2;s<i;s++)o[s]=r[s];return t.createElement.apply(null,o)}return t.createElement.apply(null,r)}d.displayName="MDXCreateElement"},5155:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var t=r(7462),a=(r(7294),r(3905));const i={},o="Referenzen",c={unversionedId:"references",id:"references",title:"Referenzen",description:'* Atwater, Erinn und Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."',source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/references.md",sourceDirName:".",slug:"/references",permalink:"/de/security/references",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Entwicklung",permalink:"/de/security/development"}},p={},s=[],l={toc:s},u="wrapper";function m(e){let{components:n,...r}=e;return(0,a.kt)(u,(0,t.Z)({},l,r,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"referenzen"},"Referenzen"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Atwater, Erinn und Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Brooks, John. Ricochet: Anonymous instant messaging for real privacy. ",(0,a.kt)("a",{parentName:"p",href:"https://ricochet.im"},"https://ricochet.im")," . Zugriffen: 2018-03-10")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata\u2014New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Langley, Adam. Pond. ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/agl/pond"},"https://github.com/agl/pond"),". Zugriffen: 2018-05-21.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Kalysch, A., Bove, D. and M\xfcller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn\u2019t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Unger, Nik et al. \u201cSoK: secure messaging\u201d. In: Security and Privacy (SP), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232\u2013249 ",(0,a.kt)("a",{parentName:"p",href:"http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf"},"link")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/ccc49370.a9ca1f91.js b/build-staging/de/assets/js/ccc49370.a9ca1f91.js new file mode 100644 index 00000000..455c51ff --- /dev/null +++ b/build-staging/de/assets/js/ccc49370.a9ca1f91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6103],{5203:(e,t,n)=>{n.r(t),n.d(t,{default:()=>h});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),i=n(9460),c=n(9058),s=n(390),m=n(7462),d=n(5999),u=n(2244);function g(e){const{nextItem:t,prevItem:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,d.I)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"})},n&&a.createElement(u.Z,(0,m.Z)({},n,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post"},"Newer Post")})),t&&a.createElement(u.Z,(0,m.Z)({},t,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post"},"Older Post"),isNext:!0})))}function f(){const{assets:e,metadata:t}=(0,i.C)(),{title:n,description:l,date:r,tags:c,authors:s,frontMatter:m}=t,{keywords:d}=m,u=e.image??m.image;return a.createElement(o.d,{title:n,description:l,keywords:d,image:u},a.createElement("meta",{property:"og:type",content:"article"}),a.createElement("meta",{property:"article:published_time",content:r}),s.some((e=>e.url))&&a.createElement("meta",{property:"article:author",content:s.map((e=>e.url)).filter(Boolean).join(",")}),c.length>0&&a.createElement("meta",{property:"article:tag",content:c.map((e=>e.label)).join(",")}))}var v=n(9407);function p(e){let{sidebar:t,children:n}=e;const{metadata:l,toc:o}=(0,i.C)(),{nextItem:r,prevItem:m,frontMatter:d}=l,{hide_table_of_contents:u,toc_min_heading_level:f,toc_max_heading_level:p}=d;return a.createElement(c.Z,{sidebar:t,toc:!u&&o.length>0?a.createElement(v.Z,{toc:o,minHeadingLevel:f,maxHeadingLevel:p}):void 0},a.createElement(s.Z,null,n),(r||m)&&a.createElement(g,{nextItem:r,prevItem:m}))}function h(e){const t=e.content;return a.createElement(i.n,{content:e.content,isBlogPostPage:!0},a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.blogPages,r.k.page.blogPostPage)},a.createElement(f,null),a.createElement(p,{sidebar:e.sidebar},a.createElement(t,null))))}},9407:(e,t,n)=>{n.d(t,{Z:()=>m});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",s="table-of-contents__link--active";function m(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(i.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:s})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>f});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function s(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(c(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function m(){const e=(0,l.useRef)(0),{navbar:{hideOnScroll:t}}=(0,o.L)();return(0,l.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,l.useRef)(void 0),n=m();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function i(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),i=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=s(i,{anchorTopOffset:n.current}),m=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===m)}))}return document.addEventListener("scroll",i),document.addEventListener("resize",i),i(),()=>{document.removeEventListener("scroll",i),document.removeEventListener("resize",i)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const g=l.memo(u);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:s,minHeadingLevel:m,maxHeadingLevel:u,...f}=e;const v=(0,o.L)(),p=m??v.tableOfContents.minHeadingLevel,h=u??v.tableOfContents.maxHeadingLevel,b=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:p,maxHeadingLevel:h});return d((0,l.useMemo)((()=>{if(c&&s)return{linkClassName:c,linkActiveClassName:s,minHeadingLevel:p,maxHeadingLevel:h}}),[c,s,p,h])),l.createElement(g,(0,a.Z)({toc:b,className:n,linkClassName:c},f))}}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/d2095d9b.ce009bc9.js b/build-staging/de/assets/js/d2095d9b.ce009bc9.js new file mode 100644 index 00000000..5493bee9 --- /dev/null +++ b/build-staging/de/assets/js/d2095d9b.ce009bc9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3508],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),p=u(r),b=i,f=p["".concat(s,".").concat(b)]||p[b]||d[b]||o;return r?n.createElement(f,c(c({ref:t},l),{},{components:r})):n.createElement(f,c({ref:t},l))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,c=new Array(o);c[0]=b;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[p]="string"==typeof e?e:i,c[1]=a;for(var u=2;u<o;u++)c[u]=r[u];return n.createElement.apply(null,c)}return n.createElement.apply(null,r)}b.displayName="MDXCreateElement"},8893:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>u});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:10},c="Aufkleber",a={unversionedId:"contribute/stickers",id:"contribute/stickers",title:"Aufkleber",description:"Alle Beitr\xe4ge sind f\xfcr Aufkleber berechtigt. Wenn du zu Bugs, Features, Testen oder Sprache beitr\xe4gst oder in der Vergangenheit einen wesentlichen Beitrag geleistet hast, schreibe bitte eine E-Mail an erinn@openprivacy. mit Details und einer Adresse f\xfcr uns, damit wir die Aufkleber dir schicken k\xf6nnen.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/stickers.md",sourceDirName:"contribute",slug:"/contribute/stickers",permalink:"/de/docs/contribute/stickers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/stickers.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Stilregeln der Dokumentation",permalink:"/de/docs/contribute/documentation"},next:{title:"Platforms",permalink:"/de/docs/category/platforms"}},s={},u=[],l={toc:u},p="wrapper";function d(e){let{components:t,...o}=e;return(0,i.kt)(p,(0,n.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"aufkleber"},"Aufkleber"),(0,i.kt)("p",null,"Alle Beitr\xe4ge sind f\xfcr Aufkleber berechtigt. Wenn du zu Bugs, Features, Testen oder Sprache beitr\xe4gst oder in der Vergangenheit einen wesentlichen Beitrag geleistet hast, schreibe bitte eine E-Mail an erinn@openprivacy. mit Details und einer Adresse f\xfcr uns, damit wir die Aufkleber dir schicken k\xf6nnen."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"Ein Foto von Cwtch-Aufklebern",src:r(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},4515:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/d5f314f9.1dc05f26.js b/build-staging/de/assets/js/d5f314f9.1dc05f26.js new file mode 100644 index 00000000..02f13a12 --- /dev/null +++ b/build-staging/de/assets/js/d5f314f9.1dc05f26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5869],{9317:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-developer"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/d72b1382.95676827.js b/build-staging/de/assets/js/d72b1382.95676827.js new file mode 100644 index 00000000..7f562dd4 --- /dev/null +++ b/build-staging/de/assets/js/d72b1382.95676827.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[171],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),l=u(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},s),{},{components:r})):n.createElement(f,a({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:o,a[1]=p;for(var u=2;u<i;u++)a[u]=r[u];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},3135:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:3},a="Eine neue Gruppe erstellen",p={unversionedId:"groups/create-group",id:"groups/create-group",title:"Eine neue Gruppe erstellen",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/create-group.md",sourceDirName:"groups",slug:"/groups/create-group",permalink:"/de/docs/groups/create-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/create-group.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Eine Einf\xfchrung in die Cwtch Gruppen",permalink:"/de/docs/groups/introduction"},next:{title:"Einladungen an eine Gruppe senden",permalink:"/de/docs/groups/send-invite"}},c={},u=[],s={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"eine-neue-gruppe-erstellen"},"Eine neue Gruppe erstellen"),(0,o.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"In deinem Kontakt-Bereich"),(0,o.kt)("li",{parentName:"ol"},"Dr\xfccke auf die Plus-Schaltfl\xe4che"),(0,o.kt)("li",{parentName:"ol"},"Dr\xfccke auf Gruppe erstellen"),(0,o.kt)("li",{parentName:"ol"},"Gib deiner Gruppe einen Namen"),(0,o.kt)("li",{parentName:"ol"},"Dr\xfccke auf Erstellen")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Create.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/da082baa.9e99cb9e.js b/build-staging/de/assets/js/da082baa.9e99cb9e.js new file mode 100644 index 00000000..e78d502a --- /dev/null +++ b/build-staging/de/assets/js/da082baa.9e99cb9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1865],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>m});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function l(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=n.createContext({}),p=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},c=function(e){var r=p(e.components);return n.createElement(s.Provider,{value:r},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),f=p(t),d=i,m=f["".concat(s,".").concat(d)]||f[d]||u[d]||o;return t?n.createElement(m,a(a({ref:r},c),{},{components:t})):n.createElement(m,a({ref:r},c))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=d;var l={};for(var s in r)hasOwnProperty.call(r,s)&&(l[s]=r[s]);l.originalType=e,l[f]="string"==typeof e?e:i,a[1]=l;for(var p=2;p<o;p++)a[p]=t[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},2276:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:11},a="Profil importieren",l={unversionedId:"profiles/importing-a-profile",id:"profiles/importing-a-profile",title:"Profil importieren",description:'1. Dr\xfccke die + Aktionstaste in der rechten unteren Ecke und w\xe4hle "Importiere Profil"',source:"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/importing-a-profile.md",sourceDirName:"profiles",slug:"/profiles/importing-a-profile",permalink:"/de/docs/profiles/importing-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/importing-a-profile.md",tags:[],version:"current",sidebarPosition:11,frontMatter:{sidebar_position:11},sidebar:"tutorialSidebar",previous:{title:"Sicherung oder Export eines Profils",permalink:"/de/docs/profiles/exporting-profile"},next:{title:"Verf\xfcgbarkeitsstatus einstellen",permalink:"/de/docs/profiles/availability-status"}},s={},p=[],c={toc:p},f="wrapper";function u(e){let{components:r,...t}=e;return(0,i.kt)(f,(0,n.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"profil-importieren"},"Profil importieren"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke die ",(0,i.kt)("inlineCode",{parentName:"li"},"+"),' Aktionstaste in der rechten unteren Ecke und w\xe4hle "Importiere Profil"'),(0,i.kt)("li",{parentName:"ol"},"W\xe4hle eine ",(0,i.kt)("a",{parentName:"li",href:"/docs/profiles/exporting-profile"},"exportierte Cwtch-Profildatei")," zum Importieren"),(0,i.kt)("li",{parentName:"ol"},"Gib das ",(0,i.kt)("a",{parentName:"li",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"Passwort")," ein, das dem Profil zugeordnet ist und best\xe4tige es.")),(0,i.kt)("p",null,"Nach der Best\xe4tigung wird Cwtch versuchen, die angegebene Datei mit einem aus dem angegebenen Passwort abgeleiteten Schl\xfcssel zu entschl\xfcsseln. Wenn es erfolgreich ist, erscheint das Profil auf dem Profilverwaltungs-Seite und kann verwendet werden."),(0,i.kt)("admonition",{title:"Hinweis",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"W\xe4hrend ein Profil auf mehrere Ger\xe4te importiert werden kann zur Zeit nur eine Version des Profils aktiv sein. Ein gleichzeitiger Betrieb auf allen Ger\xe4ten ist nicht m\xf6glich."),(0,i.kt)("p",{parentName:"admonition"},"Versuche, das gleiche Profil auf mehreren Ger\xe4ten gleichzeitig zu verwenden, k\xf6nnen zu Verf\xfcgbarkeitsproblemen und Nachrichtenfehlern f\xfchren.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/dc2bcacd.d9d70268.js b/build-staging/de/assets/js/dc2bcacd.d9d70268.js new file mode 100644 index 00000000..aa5d88af --- /dev/null +++ b/build-staging/de/assets/js/dc2bcacd.d9d70268.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[590],{3905:(e,n,r)=>{r.d(n,{Zo:()=>d,kt:()=>m});var t=r(7294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function l(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){s(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function o(e,n){if(null==e)return{};var r,t,s=function(e,n){if(null==e)return{};var r,t,s={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=t.createContext({}),a=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):l(l({},n),e)),r},d=function(e){var n=a(e.components);return t.createElement(c.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},h=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,i=e.originalType,c=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=a(r),h=s,m=u["".concat(c,".").concat(h)]||u[h]||p[h]||i;return r?t.createElement(m,l(l({ref:n},d),{},{components:r})):t.createElement(m,l({ref:n},d))}));function m(e,n){var r=arguments,s=n&&n.mdxType;if("string"==typeof e||s){var i=r.length,l=new Array(i);l[0]=h;var o={};for(var c in n)hasOwnProperty.call(n,c)&&(o[c]=n[c]);o.originalType=e,o[u]="string"==typeof e?e:s,l[1]=o;for(var a=2;a<i;a++)l[a]=r[a];return t.createElement.apply(null,l)}return t.createElement.apply(null,r)}h.displayName="MDXCreateElement"},3143:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>a});var t=r(7462),s=(r(7294),r(3905));const i={sidebar_position:3},l="Schl\xfcsselb\xfcndel",o={unversionedId:"components/cwtch/key_bundles",id:"components/cwtch/key_bundles",title:"Schl\xfcsselb\xfcndel",description:"Cwtch-Server identifizieren sich mit signierten Schl\xfcsselb\xfcndeln. Diese Schl\xfcsselb\xfcndel enthalten eine Liste der ben\xf6tigten Schl\xfcssel, um die Kommunikation der Cwtch-Gruppe sicher zu machen und Metadaten widerstandsf\xe4hig zu machen.",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/key_bundles.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/key_bundles",permalink:"/de/security/components/cwtch/key_bundles",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Nachrichtenformate",permalink:"/de/security/components/cwtch/message_formats"},next:{title:"Gruppen",permalink:"/de/security/components/cwtch/groups"}},c={},a=[{value:"\xdcberpr\xfcfe Schl\xfcsselb\xfcndel",id:"\xfcberpr\xfcfe-schl\xfcsselb\xfcndel",level:2}],d={toc:a},u="wrapper";function p(e){let{components:n,...r}=e;return(0,s.kt)(u,(0,t.Z)({},d,r,{components:n,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"schl\xfcsselb\xfcndel"},"Schl\xfcsselb\xfcndel"),(0,s.kt)("p",null,"Cwtch-Server identifizieren sich mit signierten Schl\xfcsselb\xfcndeln. Diese Schl\xfcsselb\xfcndel enthalten eine Liste der ben\xf6tigten Schl\xfcssel, um die Kommunikation der Cwtch-Gruppe sicher zu machen und Metadaten widerstandsf\xe4hig zu machen."),(0,s.kt)("p",null,"Zum Zeitpunkt des Schreibens wird erwartet, dass Schl\xfcsselb\xfcndel 3 Schl\xfcssel enthalten:"),(0,s.kt)("ol",null,(0,s.kt)("li",{parentName:"ol"},"Ein \xf6ffentlicher Tor v3 Onion Service Public Key f\xfcr das Token Board (ed25519)- verwendet um sich \xfcber Tor mit dem Dienst zu verbinden und Nachrichten zu empfangen."),(0,s.kt)("li",{parentName:"ol"},"Ein \xf6ffentlicher Schl\xfcssel des Tor-v3-Onion Service f\xfcr den Token Service (ed25519) - der verwendet wird, um Tokens zu erwerben, um \xfcber eine kleine Proof-Work-\xdcbung auf den Dienst zu posten."),(0,s.kt)("li",{parentName:"ol"},"Ein Public Key f\xfcr den Privacy-Pass - verwendet im Token-Akquisitionsprozess (ein ristretto Kurvenpunkt) . Siehe: ",(0,s.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"OPTR2019-01"))),(0,s.kt)("p",null,"Das Schl\xfcsselb\xfcndel ist signiert und kann \xfcber den ersten v3-Onion Service Schl\xfcssel verifiziert werden, so dass es an die onion-Adresse gebunden wird."),(0,s.kt)("h2",{id:"\xfcberpr\xfcfe-schl\xfcsselb\xfcndel"},"\xdcberpr\xfcfe Schl\xfcsselb\xfcndel"),(0,s.kt)("p",null,'Profile, die Server-Schl\xfcsselpakete importieren, \xfcberpr\xfcfen sie anhand des folgenden "trust-on-first-use"-Algorithmus (TOFU):'),(0,s.kt)("ol",null,(0,s.kt)("li",{parentName:"ol"},"\xdcberpr\xfcfung der angeh\xe4ngten Signatur mit der v3-Onion Adresse des Servers. (Wenn dies fehlschl\xe4gt, wird der Importprozess gestoppt)"),(0,s.kt)("li",{parentName:"ol"},"\xdcberpr\xfcfung, ob jeder Schl\xfcsseltyp existiert. (Wenn dies fehlschl\xe4gt, wird der Importprozess gestoppt)"),(0,s.kt)("li",{parentName:"ol"},"Wenn das Profil zuvor das Server-Schl\xfcsselb\xfcndel importiert hat, Sicherstellung, dass alle Schl\xfcssel gleich sind. (Wenn dies fehlschl\xe4gt, wird der Importprozess gestoppt)"),(0,s.kt)("li",{parentName:"ol"},"Speichern der Schl\xfcssel im Kontakt-Eintrag des Servers.")),(0,s.kt)("p",null,"In Zukunft wird dieser Algorithmus wahrscheinlich so ge\xe4ndert, dass neue \xf6ffentliche Schl\xfcssel hinzugef\xfcgt werden k\xf6nnen (z.B. um Tokens \xfcber eine Zcash Adresse zu erwerben.)"),(0,s.kt)("p",null,'Technisch gesehen kann der Server in den Schritten (2) und (3() als b\xf6sartig angesehen werden, weil er ein g\xfcltiges Schl\xfcsselb\xfcndel unterzeichnet hat, das nicht den Spezifikationen entspricht. Wenn Gruppen von "experimentell" in "stable" verschoben werden, f\xfchrt eine solche Aktion dazu, dass eine Warnung an das Profil kommuniziert wird.'))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/dda846b3.81a1bc96.js b/build-staging/de/assets/js/dda846b3.81a1bc96.js new file mode 100644 index 00000000..1cb59a20 --- /dev/null +++ b/build-staging/de/assets/js/dda846b3.81a1bc96.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9338],{3905:(e,n,r)=>{r.d(n,{Zo:()=>c,kt:()=>p});var t=r(7294);function i(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?a(Object(r),!0).forEach((function(n){i(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function o(e,n){if(null==e)return{};var r,t,i=function(e,n){if(null==e)return{};var r,t,i={},a=Object.keys(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||(i[r]=e[r]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var u=t.createContext({}),d=function(e){var n=t.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},c=function(e){var n=d(e.components);return t.createElement(u.Provider,{value:n},e.children)},l="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},g=t.forwardRef((function(e,n){var r=e.components,i=e.mdxType,a=e.originalType,u=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),l=d(r),g=i,p=l["".concat(u,".").concat(g)]||l[g]||h[g]||a;return r?t.createElement(p,s(s({ref:n},c),{},{components:r})):t.createElement(p,s({ref:n},c))}));function p(e,n){var r=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=r.length,s=new Array(a);s[0]=g;var o={};for(var u in n)hasOwnProperty.call(n,u)&&(o[u]=n[u]);o.originalType=e,o[l]="string"==typeof e?e:i,s[1]=o;for(var d=2;d<a;d++)s[d]=r[d];return t.createElement.apply(null,s)}return t.createElement.apply(null,r)}g.displayName="MDXCreateElement"},3504:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var t=r(7462),i=(r(7294),r(3905));const a={},s="Android Dienst",o={unversionedId:"components/ui/android",id:"components/ui/android",title:"Android Dienst",description:"Angepasst von Integration von FFI-Prozessen mit Android-Diensten",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/android.md",sourceDirName:"components/ui",slug:"/components/ui/android",permalink:"/de/security/components/ui/android",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cwtch UI",permalink:"/de/security/category/cwtch-ui"},next:{title:"Bildervorschau",permalink:"/de/security/components/ui/image_previews"}},u={},d=[],c={toc:d},l="wrapper";function h(e){let{components:n,...r}=e;return(0,i.kt)(l,(0,t.Z)({},c,r,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"android-dienst"},"Android Dienst"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/11-android-ffi-service-integration/"},"Angepasst von: Discreet Log #11: Integration von FFI-Prozessen mit Android-Diensten")),(0,i.kt)("p",null,"Zus\xe4tzlich zu der Notwendigkeit, einfache Methodenaufrufe in die Cwtch-Bibliothek zu machen, m\xfcssen wir auch in der Lage sein, mit langlaufenden Cwtch-Go-Routinen zu kommunizieren (und Ereignisse von ihnen zu empfangen), die den Tor-Prozess im Hintergrund laufen lassen, den Verbindungs- und Gespr\xe4chsstatus f\xfcr alle deine Kontakte verwalten und einige andere \xdcberwachungs- und Wartungsaufgaben erledigen. Auf herk\xf6mmlichen Multitasking-Desktop-Betriebssystemen ist dies kein wirkliches Problem, aber auf mobilen Ger\xe4ten mit Android m\xfcssen wir mit k\xfcrzeren Sitzungen, h\xe4ufigen Entladevorg\xe4ngen sowie Netzwerk- und Energiebeschr\xe4nkungen zurechtkommen, die sich im Laufe der Zeit \xe4ndern k\xf6nnen. Da Cwtch metadatenresistent und datenschutzorientiert sein soll, wollen wir auch Benachrichtigungen bereitstellen, ohne den Google-Push-Benachrichtigungsdienst zu nutzen."),(0,i.kt)("p",null,"Die L\xf6sung f\xfcr langlaufende Netzwerkanwendungen wie Cwtch besteht darin, unseren FFI-Code in einen Android Foreground Service zu integrieren. (Und nein, es ist mir nicht entgangen, dass der Code f\xfcr unser Backend in einem sogenannten ForegroundService untergebracht ist) Die WorkManager-API erm\xf6glicht es uns, mit ein wenig Fingerspitzengef\xfchl verschiedene Arten von Diensten zu erstellen und zu verwalten, darunter auch ForegroundServices. Dies erwies sich als eine gute Wahl f\xfcr uns, da unser gomobile FFI-Handler bereits in Kotlin geschrieben war und WorkManager uns erlaubt, eine Kotlin-Coroutine zu spezifizieren, die als Dienst aufgerufen wird."),(0,i.kt)("p",null,"Wenn Sie uns folgen wollen, unsere WorkManager-Spezifikationen werden in der handleCwtch()-Methode von ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt"},"MainActivity.kt")," erstellt, und die Worker selbst sind in ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt"},"FlwtchWorker.kt")," definiert."),(0,i.kt)("p",null,"Unsere einfachen Methodenaufrufe an FFI-Routinen werden auch als WorkManager-Arbeitsanforderungen aktualisiert, so dass wir die R\xfcckgabewerte bequem \xfcber den Ergebnis-Callback zur\xfcckgeben k\xf6nnen."),(0,i.kt)("p",null,"Ein erster Aufruf (passenderweise Start genannt) wird von FlwtchWorker gekapert, um unsere Eventbus-Schleife zu werden. Da es sich bei FlwtchWorker um eine Co-Routine handelt, ist es f\xfcr sie ein Leichtes, bei Bedarf aufzugeben und fortzufahren, w\xe4hrend sie darauf wartet, dass Ereignisse erzeugt werden. Die Goroutinen von Cwtch k\xf6nnen dann Ereignisse ausgeben, die von FlwtchWorker aufgegriffen und entsprechend weitergeleitet werden."),(0,i.kt)("p",null,"Die Eventbus-Schleife von FlwtchWorker ist nicht nur ein langweiliger Forwarder. Es muss auf bestimmte Nachrichtentypen gepr\xfcft werden, die den Android-Status beeinflussen. So sollten beispielsweise bei neuen Nachrichtenereignissen normalerweise Benachrichtigungen angezeigt werden, auf die der Benutzer klicken kann, um das entsprechende Konversationsfenster aufzurufen, auch wenn die App nicht im Vordergrund l\xe4uft. Wenn es an der Zeit ist, das Ereignis an die Anwendung weiterzuleiten, verwenden wir LocalBroadcastManager, um die Benachrichtigung an MainActivity.onIntent zu erhalten. Von dort aus verwenden wir wiederum Flutter MethodChannels, um die Ereignisdaten von Kotlin an die Flutter-Engine des Frontends weiterzuleiten, wo das Ereignis schlie\xdflich von Dart-Code geparst wird, der die Benutzeroberfl\xe4che nach Bedarf aktualisiert."),(0,i.kt)("p",null,"Nachrichten und andere permanente Zust\xe4nde werden vom Dienst auf der Festplatte gespeichert, so dass das Frontend nicht aktualisiert werden muss, wenn die Anwendung nicht ge\xf6ffnet ist. Einige Dinge (wie z. B. Daten und ungelesene Nachrichten) k\xf6nnen dann jedoch zu Desynchronisationen zwischen Front- und Backend f\xfchren, so dass wir dies beim Starten/Fortsetzen der Anwendung \xfcberpr\xfcfen, um zu sehen, ob wir Cwtch neu initialisieren und/oder den UI-Status neu synchronisieren m\xfcssen."),(0,i.kt)("p",null,"Schlie\xdflich haben wir bei der Implementierung dieser Dienste unter Android festgestellt, dass WorkManager sehr gut darin ist, alte Warteschlangen aufrechtzuerhalten, und zwar so gut, dass alte Worker sogar nach einer Neuinstallation der Anwendung wieder aufgenommen wurden! Das Hinzuf\xfcgen von Aufrufen zu pruneWork() hilft, dies abzumildern, solange die Anwendung ordnungsgem\xe4\xdf heruntergefahren wurde und alte Auftr\xe4ge ordnungsgem\xe4\xdf abgebrochen wurden. Dies ist unter Android jedoch h\xe4ufig nicht der Fall, so dass wir es als zus\xe4tzliche Abschw\xe4chung f\xfcr sinnvoll erachten, die Arbeit mit dem Namen des nativen Bibliotheksverzeichnisses zu kennzeichnen:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},'private fun getNativeLibDir(): String {\n val ainfo = this.applicationContext.packageManager.getApplicationInfo(\n "im.cwtch.flwtch", // Must be app name\n PackageManager.GET_SHARED_LIBRARY_FILES)\n return ainfo.nativeLibraryDir\n}\n')),(0,i.kt)("p",null,"... dann brechen wir bei jedem Start der Anwendung alle Auftr\xe4ge ab, die nicht mit dem richtigen aktuellen Bibliotheksverzeichnis gekennzeichnet sind. Da sich der Name dieses Verzeichnisses bei jeder Installation der Anwendung \xe4ndert, verhindert diese Technik, dass wir versehentlich mit einem veralteten Service Worker fortfahren."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/de5e68d7.f9e5a10c.js b/build-staging/de/assets/js/de5e68d7.f9e5a10c.js new file mode 100644 index 00000000..74cf28ec --- /dev/null +++ b/build-staging/de/assets/js/de5e68d7.f9e5a10c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3233],{3905:(e,n,r)=>{r.d(n,{Zo:()=>o,kt:()=>g});var i=r(7294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,i)}return r}function l(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function a(e,n){if(null==e)return{};var r,i,t=function(e,n){if(null==e)return{};var r,i,t={},s=Object.keys(e);for(i=0;i<s.length;i++)r=s[i],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(i=0;i<s.length;i++)r=s[i],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var u=i.createContext({}),c=function(e){var n=i.useContext(u),r=n;return e&&(r="function"==typeof e?e(n):l(l({},n),e)),r},o=function(e){var n=c(e.components);return i.createElement(u.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},h=i.forwardRef((function(e,n){var r=e.components,t=e.mdxType,s=e.originalType,u=e.parentName,o=a(e,["components","mdxType","originalType","parentName"]),d=c(r),h=t,g=d["".concat(u,".").concat(h)]||d[h]||p[h]||s;return r?i.createElement(g,l(l({ref:n},o),{},{components:r})):i.createElement(g,l({ref:n},o))}));function g(e,n){var r=arguments,t=n&&n.mdxType;if("string"==typeof e||t){var s=r.length,l=new Array(s);l[0]=h;var a={};for(var u in n)hasOwnProperty.call(n,u)&&(a[u]=n[u]);a.originalType=e,a[d]="string"==typeof e?e:t,l[1]=a;for(var c=2;c<s;c++)l[c]=r[c];return i.createElement.apply(null,l)}return i.createElement.apply(null,r)}h.displayName="MDXCreateElement"},1644:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>l,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var i=r(7462),t=(r(7294),r(3905));const s={sidebar_position:4},l="Gruppen",a={unversionedId:"components/cwtch/groups",id:"components/cwtch/groups",title:"Gruppen",description:"Das Cwtch Risikomodell f\xfcr Gruppen ist gr\xf6\xdftenteils in zwei unterschiedliche Profile aufgeteilt:",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/groups.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/groups",permalink:"/de/security/components/cwtch/groups",draft:!1,tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Schl\xfcsselb\xfcndel",permalink:"/de/security/components/cwtch/key_bundles"},next:{title:"Cwtch Server",permalink:"/de/security/components/cwtch/server"}},u={},c=[{value:"\xdcberblick \xfcber die Risiken: Schl\xfcssel-Ableitung",id:"\xfcberblick-\xfcber-die-risiken-schl\xfcssel-ableitung",level:2},{value:"Risiko: Sch\xe4dlicher Peer- verr\xe4t Gruppenschl\xfcssel und/oder Unterhaltung",id:"risiko-sch\xe4dlicher-peer--verr\xe4t-gruppenschl\xfcssel-undoder-unterhaltung",level:2},{value:"Risiko: Aktive Angriffe von Gruppenmitgliedern",id:"risiko-aktive-angriffe-von-gruppenmitgliedern",level:2},{value:"Eind\xe4mmung:",id:"eind\xe4mmung",level:3}],o={toc:c},d="wrapper";function p(e){let{components:n,...r}=e;return(0,t.kt)(d,(0,i.Z)({},o,r,{components:n,mdxType:"MDXLayout"}),(0,t.kt)("h1",{id:"gruppen"},"Gruppen"),(0,t.kt)("p",null,"Das Cwtch Risikomodell f\xfcr Gruppen ist gr\xf6\xdftenteils in zwei unterschiedliche Profile aufgeteilt:"),(0,t.kt)("ul",null,(0,t.kt)("li",{parentName:"ul"},"Gruppen aus gegenseitig vertrauensw\xfcrdigen Teilnehmern, in denen Peers als ehrlich angenommen werden."),(0,t.kt)("li",{parentName:"ul"},"Gruppen, die aus Fremden bestehen, in denen von Peers angenommen wird, dass sie potenziell b\xf6sartig sind.")),(0,t.kt)("p",null,"Die meisten der in diesem Abschnitt beschriebenen Eind\xe4mmungen beziehen sich auf den letztgenannten Fall, aber wirken sich nat\xfcrlich auch auf den Ersteren aus. Selbst wenn angenommen wird, dass ehrliche Peers sp\xe4ter b\xf6swillig werden, gibt es Mechanismen, die solches B\xf6se erkennen und verhindern k\xf6nnen, dass es in der Zukunft passiert."),(0,t.kt)("h2",{id:"\xfcberblick-\xfcber-die-risiken-schl\xfcssel-ableitung"},"\xdcberblick \xfcber die Risiken: Schl\xfcssel-Ableitung"),(0,t.kt)("p",null,"Im Idealfall w\xfcrden wir ein Protokoll wie OTR verwenden, die Einschr\xe4nkungen, die uns im Moment daran hindern, sind:"),(0,t.kt)("ul",null,(0,t.kt)("li",{parentName:"ul"},"Offline-Nachrichten sind nicht garantiert, dass sie alle Peers erreichen, und als solche k\xf6nnen alle Metadaten in Bezug auf Schl\xfcsselmaterial verloren gehen. Wir ben\xf6tigen einen Schl\xfcsselableitungs-Prozess, der robust ist f\xfcr fehlende Nachrichten oder unvollst\xe4ndige \xdcbertragungen.")),(0,t.kt)("h2",{id:"risiko-sch\xe4dlicher-peer--verr\xe4t-gruppenschl\xfcssel-undoder-unterhaltung"},"Risiko: Sch\xe4dlicher Peer- verr\xe4t Gruppenschl\xfcssel und/oder Unterhaltung"),(0,t.kt)("p",null,(0,t.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert (aber unm\xf6glich vollst\xe4ndig zu mildern)")),(0,t.kt)("p",null,"Ob mit vertrauensw\xfcrdigen kleineren Gruppen oder partiell \xf6ffentliche gr\xf6\xdferen Gruppen, es gibt ",(0,t.kt)("em",{parentName:"p"},"immer ")," die M\xf6glichkeit, dass ein b\xf6swilliger Akteur Gruppe Nachrichten verraten kann."),(0,t.kt)("p",null,"Wir planen, es den Peers zu erleichtern, ",(0,t.kt)("a",{parentName:"p",href:"#fork"},"Gruppen zu fork"),", den gleichen Schl\xfcssel zu entsch\xe4rfen, der zur Verschl\xfcsselung vieler sensibler Informationen verwendet wird und ein gewisses Ma\xdf an Weiterleitungsgeheimhaltung f\xfcr fr\xfchere Gruppengespr\xe4che bereitzustellen."),(0,t.kt)("h2",{id:"risiko-aktive-angriffe-von-gruppenmitgliedern"},"Risiko: Aktive Angriffe von Gruppenmitgliedern"),(0,t.kt)("p",null,(0,t.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert")),(0,t.kt)("p",null,"Gruppenmitglieder, die Zugang zum Schl\xfcsselmaterial der Gruppe haben, k\xf6nnen sich mit einem Server oder anderen Gruppenmitgliedern verschw\xf6ren, um die Konsistenz des Transkripts zu unterbrechen."),(0,t.kt)("p",null,"W\xe4hrend wir die Zensur angesichts dieser aktiven Absprachen nicht direkt verhindern k\xf6nnen, so verf\xfcgen wir doch \xfcber eine Reihe von Mechanismen, die ehrlichen Gruppen-Mitgliedern das Vorhandensein einer Zensur offenbaren sollten."),(0,t.kt)("h3",{id:"eind\xe4mmung"},"Eind\xe4mmung:"),(0,t.kt)("ul",null,(0,t.kt)("li",{parentName:"ul"},"Weil jede Nachricht vom \xf6ffentlichen Schl\xfcssel der Peers signiert ist, es sollte nicht m\xf6glich sein (innerhalb der kryptographischen Annahmen der zugrunde liegenden Kryptographie) f\xfcr ein Gruppenmitglied ein anderes nachzuahmen."),(0,t.kt)("li",{parentName:"ul"},"Jede Nachricht enth\xe4lt eine eindeutige Identifikation, die aus dem Inhalt abgeleitet wird und den vorherigen Hash der Nachrichten - wodurch es Kollaborateuren unm\xf6glich gemacht wird, Nachrichten von nicht geheimen Mitgliedern einzuf\xfcgen, ohne eine implizite Meldungs-Kette zu enth\xfcllen (die wenn sie versuchen andere Nachrichten zu zensieren w\xfcrde eine solche Zensur offenbaren)")),(0,t.kt)("p",null,"Abschlie\xdfend: Wir arbeiten aktiv daran, den Cwtch-Servern eine Nichtabstreitbarkeit hinzuzuf\xfcgen, so dass dass sie selbst in dem, was sie effizient zensieren k\xf6nnen, eingeschr\xe4nkt sind."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/decd0f12.35f6ebc7.js b/build-staging/de/assets/js/decd0f12.35f6ebc7.js new file mode 100644 index 00000000..e3a2251b --- /dev/null +++ b/build-staging/de/assets/js/decd0f12.35f6ebc7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3577],{8265:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/planning","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e0940a37.88839e56.js b/build-staging/de/assets/js/e0940a37.88839e56.js new file mode 100644 index 00000000..458be56a --- /dev/null +++ b/build-staging/de/assets/js/e0940a37.88839e56.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3887],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var o=r.createContext({}),p=function(e){var t=r.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(o.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,o=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),h=a,m=u["".concat(o,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,s(s({ref:t},l),{},{components:n})):r.createElement(m,s({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,s=new Array(i);s[0]=h;var c={};for(var o in t)hasOwnProperty.call(t,o)&&(c[o]=t[o]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var p=2;p<i;p++)s[p]=n[p];return r.createElement.apply(null,s)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},5254:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const i={sidebar_position:2},s="Nachrichtenformate",c={unversionedId:"components/cwtch/message_formats",id:"components/cwtch/message_formats",title:"Nachrichtenformate",description:"Peer-to-Peer Nachrichten",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/message_formats.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/message_formats",permalink:"/de/security/components/cwtch/message_formats",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch",permalink:"/de/security/category/cwtch"},next:{title:"Schl\xfcsselb\xfcndel",permalink:"/de/security/components/cwtch/key_bundles"}},o={},p=[{value:"Peer-to-Peer Nachrichten",id:"peer-to-peer-nachrichten",level:2},{value:"Kontext-Bezeichner",id:"kontext-bezeichner",level:3},{value:"Klartext / Entschl\xfcsselte Gruppennachrichten",id:"klartext--entschl\xfcsselte-gruppennachrichten",level:2},{value:"Verschl\xfcsselte Gruppennachrichten",id:"verschl\xfcsselte-gruppennachrichten",level:2}],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"nachrichtenformate"},"Nachrichtenformate"),(0,a.kt)("h2",{id:"peer-to-peer-nachrichten"},"Peer-to-Peer Nachrichten"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"PeerMessage {\n ID string // A unique Message ID (primarily used for acknowledgments)\n Context string // A unique context identifier i.e. im.cwtch.chat\n Data []byte // The context-dependent serialized data packet.\n}\n")),(0,a.kt)("h3",{id:"kontext-bezeichner"},"Kontext-Bezeichner"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.raw")," - Daten enthalten eine Klartext-Chat-Nachricht (siehe: ",(0,a.kt)("a",{parentName:"p",href:"/de/security/components/ui/overlays"},"Overlays")," f\xfcr weitere Informationen)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.acknowledgement")," - Daten sind leer und ID verweist auf eine zuvor gesendete Nachricht")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.getVal")," und ",(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.retVal")," - Wird f\xfcr die Abfrage / R\xfcckgabe spezifischer Informationen \xfcber einen Peer verwendet. Daten enthalten eine serialisierte ",(0,a.kt)("inlineCode",{parentName:"p"},"peerGetVal")," und ",(0,a.kt)("inlineCode",{parentName:"p"},"peerRetVal")," Struktur."),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre"}," peerGetVal struct {\n Scope string\n Path string\n }\n\n type peerRetVal struct {\n Val string // Serialized path-dependent value\n Exists bool\n }\n")))),(0,a.kt)("h2",{id:"klartext--entschl\xfcsselte-gruppennachrichten"},"Klartext / Entschl\xfcsselte Gruppennachrichten"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'type DecryptedGroupMessage struct {\n Text string // plaintext of the message\n Onion string // The Cwtch address of the sender\n Timestamp uint64 // A user specified timestamp\n // NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages\n // We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.\n // respect particular group constitutions) can be built on top of group messages, but the underlying groups are\n // now agnostic to those models.\n SignedGroupID []byte \n PreviousMessageSig []byte // A reference to a previous message\n Padding []byte // random bytes of length = 1800 - len(Text)\n}\n')),(0,a.kt)("p",null,"Entschl\xfcsselte Gruppennachrichten enthalten zuf\xe4llige F\xfcllung zu einer festen Gr\xf6\xdfe, die der L\xe4nge aller Felder mit fester L\xe4nge + 1800 entspricht. Dies stellt sicher, dass alle verschl\xfcsselten Gruppen-Nachrichten gleich lang sind."),(0,a.kt)("h2",{id:"verschl\xfcsselte-gruppennachrichten"},"Verschl\xfcsselte Gruppennachrichten"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server\ntype EncryptedGroupMessage struct {\n Ciphertext []byte\n Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key\n}\n")),(0,a.kt)("p",null,"Die Berechnung der Signatur erfordert das Wissen \xfcber die Gruppen-Id der Nachricht, des Servers, mit dem die Gruppe verbunden ist und der entschl\xfcsselten Gruppennachricht (und damit der Gruppenschl\xfcssel). Es ist vom Absender der Nachricht (ed25519) signiert und kann mit ihrem \xf6ffentlichen Cwtch-Adressschl\xfcssel verifiziert werden."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e2df4ad2.abfeee4d.js b/build-staging/de/assets/js/e2df4ad2.abfeee4d.js new file mode 100644 index 00000000..2758ecd8 --- /dev/null +++ b/build-staging/de/assets/js/e2df4ad2.abfeee4d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8268],{983:e=>{e.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/de/blog/tags/cwtch-stable","allTagsPath":"/de/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e3d8cb96.9c9869df.js b/build-staging/de/assets/js/e3d8cb96.9c9869df.js new file mode 100644 index 00000000..9d9b2bc8 --- /dev/null +++ b/build-staging/de/assets/js/e3d8cb96.9c9869df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1194],{675:e=>{e.exports=JSON.parse('{"title":"Mitwirken","slug":"/category/contribute","permalink":"/de/docs/category/contribute","navigation":{"previous":{"title":"Tor","permalink":"/de/docs/tor"},"next":{"title":"Entwicklung von Cwtch","permalink":"/de/docs/contribute/developing"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e445c1ea.b181e62a.js b/build-staging/de/assets/js/e445c1ea.b181e62a.js new file mode 100644 index 00000000..c25fa833 --- /dev/null +++ b/build-staging/de/assets/js/e445c1ea.b181e62a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6105],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),f=a,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||o;return n?r.createElement(m,i(i({ref:t},l),{},{components:n})):r.createElement(m,i({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var p=2;p<o;p++)i[p]=n[p];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}f.displayName="MDXCreateElement"},1593:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1.5},i="Neues Gespr\xe4ch beginnen",c={unversionedId:"chat/add-contact",id:"chat/add-contact",title:"Neues Gespr\xe4ch beginnen",description:"1. Ein Profil ausw\xe4hlen",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/add-contact.md",sourceDirName:"chat",slug:"/chat/add-contact",permalink:"/de/docs/chat/add-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/add-contact.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Eine Einf\xfchrung in die Cwtch P2P Chat",permalink:"/de/docs/chat/introduction"},next:{title:"Neue Konversationen akzeptieren/ablehnen",permalink:"/de/docs/chat/accept-deny-new-conversation"}},s={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"neues-gespr\xe4ch-beginnen"},"Neues Gespr\xe4ch beginnen"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Ein Profil ausw\xe4hlen"),(0,a.kt)("li",{parentName:"ol"},"Klicke auf den Hinzuf\xfcgen Button"),(0,a.kt)("li",{parentName:"ol"},"W\xe4hle 'Kontakt hinzuf\xfcgen'"),(0,a.kt)("li",{parentName:"ol"},"Eine Cwtch-Adresse einf\xfcgen"),(0,a.kt)("li",{parentName:"ol"},"Der Kontakt wird zu deiner Kontaktliste hinzugef\xfcgt")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"du es mit vergr\xf6\xdferst"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e49fb087.590b19a4.js b/build-staging/de/assets/js/e49fb087.590b19a4.js new file mode 100644 index 00000000..f228da9f --- /dev/null +++ b/build-staging/de/assets/js/e49fb087.590b19a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[214],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=u(n),m=i,k=d["".concat(s,".").concat(m)]||d[m]||p[m]||o;return n?r.createElement(k,a(a({ref:t},c),{},{components:n})):r.createElement(k,a({ref:t},c))}));function k(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:i,a[1]=l;for(var u=2;u<o;u++)a[u]=n[u];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},5505:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:6},a="Stilregeln der Dokumentation",l={unversionedId:"contribute/documentation",id:"contribute/documentation",title:"Stilregeln der Dokumentation",description:"Dieser Abschnitt dokumentiert die erwartete Struktur und Qualit\xe4t der Cwtch-Dokumentation.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/documentation.md",sourceDirName:"contribute",slug:"/contribute/documentation",permalink:"/de/docs/contribute/documentation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/documentation.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Cwtch \xfcbersetzen",permalink:"/de/docs/contribute/translate"},next:{title:"Aufkleber",permalink:"/de/docs/contribute/stickers"}},s={},u=[{value:"Screenshots und \xdcbertragung von Zeichen",id:"screenshots-und-\xfcbertragung-von-zeichen",level:2},{value:"Dialog und Inhalt",id:"dialog-und-inhalt",level:2},{value:"Experimente",id:"experimente",level:2},{value:"Risiko",id:"risiko",level:2}],c={toc:u},d="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(d,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"stilregeln-der-dokumentation"},"Stilregeln der Dokumentation"),(0,i.kt)("p",null,"Dieser Abschnitt dokumentiert die erwartete Struktur und Qualit\xe4t der Cwtch-Dokumentation."),(0,i.kt)("h2",{id:"screenshots-und-\xfcbertragung-von-zeichen"},"Screenshots und \xdcbertragung von Zeichen"),(0,i.kt)("p",null,"Die meisten Cwtch-Dokumentationen sollte mindestens einen Screenshot oder ein animiertes Bild enthalten. Screenshots der Cwtch-Anwendung sollten sich auf die in der Dokumentation beschriebene Funktion konzentrieren."),(0,i.kt)("p",null,"Um die Konsistenz zwischen Screenshots zu gew\xe4hrleisten, schlagen wir vor, dass das betreffende Profil besonderen, konstanten und Rollen dienen sollte."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Alice")," - wird verwendet, um das prim\xe4re Profil zu repr\xe4sentieren."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Bob")," - der prim\xe4re Kontakt, n\xfctzlich bei der Darstellung von Peer-to-Peer-Funktionen"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Carol")," - ein sekund\xe4rer Kontakt, n\xfctzlich bei der Darstellung von Gruppenfunktionen"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Mallory")," - stellt einen b\xf6swilligen Partner dar (welcher verwendet wird, um die Blockierfunktionalit\xe4t zu demonstrieren)")),(0,i.kt)("h2",{id:"dialog-und-inhalt"},"Dialog und Inhalt"),(0,i.kt)("p",null,"Wo Screenshots und Demonstrationen Dialog, Gespr\xe4che und/oder Bilder zeigen, halte bitte die Gespr\xe4che kurz zu einem l\xe4ssigen Thema. Beispiele daf\xfcr sind:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Organisieren eines Picknicks"),(0,i.kt)("li",{parentName:"ul"},"Teilen von Fotos aus einem Urlaub"),(0,i.kt)("li",{parentName:"ul"},"Senden des Dokuments zur Pr\xfcfung")),(0,i.kt)("h2",{id:"experimente"},"Experimente"),(0,i.kt)("p",null,"Alle Funktionen, die auf die Aktivierung eines Experiments angewiesen sind, sollten dies alles oben auf der Seite hervorheben z. B.:"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Beispiel Experiment")," eingeschaltet ist.")),(0,i.kt)("h2",{id:"risiko"},"Risiko"),(0,i.kt)("p",null,"Wenn eine Funktion zur Zerst\xf6rung des Schl\xfcsselmaterials oder zur dauerhaften L\xf6schung des Status f\xfchren k\xf6nnte dann sollten diese auch oben in der Dokumentation aufgerufen werden, z. B.:"),(0,i.kt)("admonition",{title:"Warnung",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion wird das Schl\xfcsselmaterial ",(0,i.kt)("strong",{parentName:"p"},"unwiderruflich")," l\xf6schen. Dieses ",(0,i.kt)("strong",{parentName:"p"},"kann nicht r\xfcckg\xe4ngig gemacht werden"),".")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e6b5bfb1.22e467e7.js b/build-staging/de/assets/js/e6b5bfb1.22e467e7.js new file mode 100644 index 00000000..40c0817f --- /dev/null +++ b/build-staging/de/assets/js/e6b5bfb1.22e467e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2591],{6240:e=>{e.exports=JSON.parse('{"title":"Darstellung","slug":"/category/appearance","permalink":"/de/docs/category/appearance","navigation":{"previous":{"title":"Eine Einf\xfchrung in die Cwtch App-Einstellungen","permalink":"/de/docs/settings/introduction"},"next":{"title":"Sprache wechseln","permalink":"/de/docs/settings/appearance/change-language"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e7b1bf29.72210083.js b/build-staging/de/assets/js/e7b1bf29.72210083.js new file mode 100644 index 00000000..e80eb6d6 --- /dev/null +++ b/build-staging/de/assets/js/e7b1bf29.72210083.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3717],{3516:e=>{e.exports=JSON.parse('{"title":"Eine Cwtch App erstellen","slug":"/category/building-a-cwtch-app","permalink":"/de/developing/category/building-a-cwtch-app","navigation":{"previous":{"title":"Release and Packaging Process","permalink":"/de/developing/release"},"next":{"title":"Getting Started","permalink":"/de/developing/building-a-cwtch-app/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e88d32a9.ff20b8ba.js b/build-staging/de/assets/js/e88d32a9.ff20b8ba.js new file mode 100644 index 00000000..e319e33e --- /dev/null +++ b/build-staging/de/assets/js/e88d32a9.ff20b8ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6585],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/e949296e.b3b118aa.js b/build-staging/de/assets/js/e949296e.b3b118aa.js new file mode 100644 index 00000000..b9acf331 --- /dev/null +++ b/build-staging/de/assets/js/e949296e.b3b118aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9149],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>f});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function a(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),u=p(t),m=i,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return t?n.createElement(f,s(s({ref:r},l),{},{components:t})):n.createElement(f,s({ref:r},l))}));function f(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,s=new Array(o);s[0]=m;var a={};for(var c in r)hasOwnProperty.call(r,c)&&(a[c]=r[c]);a.originalType=e,a[u]="string"==typeof e?e:i,s[1]=a;for(var p=2;p<o;p++)s[p]=t[p];return n.createElement.apply(null,s)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},1552:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>p});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:6},s="Wie man einen Server entsperrt",a={unversionedId:"servers/unlock-server",id:"servers/unlock-server",title:"Wie man einen Server entsperrt",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/unlock-server.md",sourceDirName:"servers",slug:"/servers/unlock-server",permalink:"/de/docs/servers/unlock-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/unlock-server.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Wie du dein Server-Schl\xfcsselpaket teilst",permalink:"/de/docs/servers/share-key"},next:{title:"Settings",permalink:"/de/docs/category/settings"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"wie-man-einen-server-entsperrt"},"Wie man einen Server entsperrt"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Server Hosting Experiment")," eingeschaltet ist.")),(0,i.kt)("p",null,"Wenn du deinen Server mit einem Passwort gesch\xfctzt hast, muss er bei jedem Neustart der Anwendung entsperrt werden."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zum Server-Symbol gehen"),(0,i.kt)("li",{parentName:"ol"},"Klicken Sie auf das rosa Entsperr-Symbol"),(0,i.kt)("li",{parentName:"ol"},"Gib das Kennwort deines Servers ein"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke Entsperren")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/ed1907a0.765640b3.js b/build-staging/de/assets/js/ed1907a0.765640b3.js new file mode 100644 index 00000000..98db43ac --- /dev/null +++ b/build-staging/de/assets/js/ed1907a0.765640b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3767],{2167:s=>{s.exports=JSON.parse('{"label":"support","permalink":"/de/blog/tags/support","allTagsPath":"/de/blog/tags","count":3}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/ef78badf.10c4eea9.js b/build-staging/de/assets/js/ef78badf.10c4eea9.js new file mode 100644 index 00000000..e552ca73 --- /dev/null +++ b/build-staging/de/assets/js/ef78badf.10c4eea9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5532],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var a=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,a,o=function(e,t){if(null==e)return{};var r,a,o={},n=Object.keys(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=a.createContext({}),s=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,o=e.mdxType,n=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=s(r),h=o,d=u["".concat(p,".").concat(h)]||u[h]||m[h]||n;return r?a.createElement(d,l(l({ref:t},c),{},{components:r})):a.createElement(d,l({ref:t},c))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=r.length,l=new Array(n);l[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var s=2;s<n;s++)l[s]=r[s];return a.createElement.apply(null,l)}return a.createElement.apply(null,r)}h.displayName="MDXCreateElement"},5481:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>m,frontMatter:()=>n,metadata:()=>i,toc:()=>s});var a=r(7462),o=(r(7294),r(3905));const n={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/de/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"27. Januar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"support",permalink:"/de/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/de/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/de/blog/cwtch-bindings-reproducible"}},p={authorsImageUrls:[void 0]},s=[],c={toc:s},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"One of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,o.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,o.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,o.kt)("p",null,"The questions we aim to answer in this post are: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,o.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,o.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,o.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,o.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(6149).Z,width:"1005",height:"481"})))}m.isMDXComponent=!0},6149:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/efb6a870.5c973c8c.js b/build-staging/de/assets/js/efb6a870.5c973c8c.js new file mode 100644 index 00000000..fb7a3fe9 --- /dev/null +++ b/build-staging/de/assets/js/efb6a870.5c973c8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1778],{8970:e=>{e.exports=JSON.parse('{"title":"Cwtch Komponenten","slug":"/category/cwtch-components","permalink":"/de/security/category/cwtch-components","navigation":{"previous":{"title":"Risiko-Modell","permalink":"/de/security/risk"},"next":{"title":"Cwtch technische Grundlagen","permalink":"/de/security/components/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f041e880.de1fab10.js b/build-staging/de/assets/js/f041e880.de1fab10.js new file mode 100644 index 00000000..69a3d972 --- /dev/null +++ b/build-staging/de/assets/js/f041e880.de1fab10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5226],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=n,d=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return a?r.createElement(d,i(i({ref:t},p),{},{components:a})):r.createElement(d,i({ref:t},p))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s<o;s++)i[s]=a[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},3291:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/de/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"31. M\xe4rz 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"planning",permalink:"/de/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/de/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/de/blog/cwtch-nightly-1-11"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f3be3c38.b0575211.js b/build-staging/de/assets/js/f3be3c38.b0575211.js new file mode 100644 index 00000000..7336d1a7 --- /dev/null +++ b/build-staging/de/assets/js/f3be3c38.b0575211.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4817],{5259:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/reproducible-builds","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f4799792.570b3460.js b/build-staging/de/assets/js/f4799792.570b3460.js new file mode 100644 index 00000000..4df14a76 --- /dev/null +++ b/build-staging/de/assets/js/f4799792.570b3460.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7992],{6719:e=>{e.exports=JSON.parse('{"permalink":"/de/blog/tags/developer-documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f76a3b8e.21fab117.js b/build-staging/de/assets/js/f76a3b8e.21fab117.js new file mode 100644 index 00000000..708d7ada --- /dev/null +++ b/build-staging/de/assets/js/f76a3b8e.21fab117.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2184],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},g="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),g=l(n),m=a,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[g]="string"==typeof e?e:a,o[1]=c;for(var l=2;l<i;l++)o[l]=n[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3103:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/de/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"17. Februar 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"support",permalink:"/de/blog/tags/support"},{label:"testing",permalink:"/de/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/de/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/de/blog/cwtch-android-reproducibility"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},g="wrapper";function u(e){let{components:t,...i}=e;return(0,a.kt)(g,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,a.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(6097).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},6097:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f7e5475a.ad1f9dbe.js b/build-staging/de/assets/js/f7e5475a.ad1f9dbe.js new file mode 100644 index 00000000..2e9f5553 --- /dev/null +++ b/build-staging/de/assets/js/f7e5475a.ad1f9dbe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1814],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>h});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=r.createContext({}),u=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=u(e.components);return r.createElement(l.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},g=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=u(t),g=i,h=d["".concat(l,".").concat(g)]||d[g]||p[g]||a;return t?r.createElement(h,o(o({ref:n},c),{},{components:t})):r.createElement(h,o({ref:n},c))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=g;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[d]="string"==typeof e?e:i,o[1]=s;for(var u=2;u<a;u++)o[u]=t[u];return r.createElement.apply(null,o)}return r.createElement.apply(null,t)}g.displayName="MDXCreateElement"},2984:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const a={sidebar_position:1},o="Eine Einf\xfchrung in die Cwtch App-Einstellungen",s={unversionedId:"settings/introduction",id:"settings/introduction",title:"Eine Einf\xfchrung in die Cwtch App-Einstellungen",description:"Darstellung",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/introduction.md",sourceDirName:"settings",slug:"/settings/introduction",permalink:"/de/docs/settings/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Settings",permalink:"/de/docs/category/settings"},next:{title:"Appearance",permalink:"/de/docs/category/appearance"}},l={},u=[{value:"Darstellung",id:"darstellung",level:2},{value:"Verhalten",id:"verhalten",level:2},{value:"Experimente",id:"experimente",level:2}],c={toc:u},d="wrapper";function p(e){let{components:n,...t}=e;return(0,i.kt)(d,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eine-einf\xfchrung-in-die-cwtch-app-einstellungen"},"Eine Einf\xfchrung in die Cwtch App-Einstellungen"),(0,i.kt)("h2",{id:"darstellung"},"Darstellung"),(0,i.kt)("p",null,"Dies sind Einstellungen, die das Aussehen von Cwtch beeinflussen, einschlie\xdflich Themen und Lokalisierung."),(0,i.kt)("h2",{id:"verhalten"},"Verhalten"),(0,i.kt)("p",null,"Diese Einstellungen beeinflussen die Reaktion von Cwtch auf bestimmte Ereignisse wie z.B. Benachrichtigungen f\xfcr neue Nachrichten oder Anfragen von unbekannten \xf6ffentlichen Adressen."),(0,i.kt)("h2",{id:"experimente"},"Experimente"),(0,i.kt)("p",null,"Es gibt viele Funktionen in Cwtch, die man gerne ausprobieren m\xf6chte, deren Implementierung aber zus\xe4tzliche Metadaten erfordert oder Risiko, \xfcber das Minimum hinaus, das Cwtch f\xfcr grundlegende Operationen ben\xf6tigt, hinausgeht."),(0,i.kt)("p",null,"Unter ",(0,i.kt)("strong",{parentName:"p"},"Experimente")," findest du eine Anzahl von ",(0,i.kt)("strong",{parentName:"p"},"optionalen")," Einstellungen, die, wenn aktiviert, Dir zus\xe4tzliche Funktionen wie Gruppenchat, Dateiaustausch oder Nachrichtenformatierung bieten."),(0,i.kt)("p",null,"Du solltest sorgf\xe4ltig \xfcber die neuen Risiken nachdenken, die damit verbunden sein k\xf6nnten, wenn Du diese Funktionen aktivierst und wenn Du dich damit komfortabel f\xfchlt, kannst du diese aktivieren. F\xfcr viele \xfcberwiegen die Vorteile des Dateiaustauschs, Bildvorschau und Gruppenchat die m\xf6glichen Sch\xe4den bei weitem - aber wir verlangen trotzdem von jedem, dass diese Funktionen selber aktiviert werden m\xfcssen."),(0,i.kt)("p",null,"Du kannst die Funktionen jederzeit wieder deaktivieren, alle Funktionen sind lokal innerhalb der Cwtch-App implementiert."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f83bd450.363d02f2.js b/build-staging/de/assets/js/f83bd450.363d02f2.js new file mode 100644 index 00000000..a7066a1e --- /dev/null +++ b/build-staging/de/assets/js/f83bd450.363d02f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5246],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=l(n),h=i,d=p["".concat(s,".").concat(h)]||p[h]||f[h]||o;return n?r.createElement(d,a(a({ref:t},u),{},{components:n})):r.createElement(d,a({ref:t},u))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:i,a[1]=c;for(var l=2;l<o;l++)a[l]=n[l];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},8185:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:3},a="Benachrichtigungsinhalt",c={unversionedId:"settings/behaviour/notification-content",id:"settings/behaviour/notification-content",title:"Benachrichtigungsinhalt",description:"1. Zu den Einstellungen",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/behaviour/notification-content.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-content",permalink:"/de/docs/settings/behaviour/notification-content",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-content.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Benachrichtigungsrichtlinie",permalink:"/de/docs/settings/behaviour/notification-policy"},next:{title:"Experiments",permalink:"/de/docs/category/experiments"}},s={},l=[],u={toc:l},p="wrapper";function f(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"benachrichtigungsinhalt"},"Benachrichtigungsinhalt"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"Zum Verhalten scrollen"),(0,i.kt)("li",{parentName:"ol"},"Der Benachrichtigungsinhalt steuert den Inhalt von Benachrichtigungen",(0,i.kt)("ol",{parentName:"li"},(0,i.kt)("li",{parentName:"ol"},'Einfaches Event: nur "Neue Nachricht"'),(0,i.kt)("li",{parentName:"ol"},'Konversationsinformation: "Neue Nachricht von XXXXX"')))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f928e8d9.a40cdb9a.js b/build-staging/de/assets/js/f928e8d9.a40cdb9a.js new file mode 100644 index 00000000..556f61a3 --- /dev/null +++ b/build-staging/de/assets/js/f928e8d9.a40cdb9a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8786],{7160:e=>{e.exports=JSON.parse('{"pluginId":"docs-developer","version":"current","label":"N\xe4chste","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Introduction to Cwtch Development","href":"/de/developing/intro","docId":"intro"},{"type":"link","label":"Release and Packaging Process","href":"/de/developing/release","docId":"release"},{"type":"category","label":"Eine Cwtch App erstellen","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/de/developing/building-a-cwtch-app/intro","docId":"building-a-cwtch-app/intro"},{"type":"link","label":"Core Concepts","href":"/de/developing/building-a-cwtch-app/core-concepts","docId":"building-a-cwtch-app/core-concepts"},{"type":"link","label":"Building a Cwtch Echobot","href":"/de/developing/building-a-cwtch-app/building-an-echobot","docId":"building-a-cwtch-app/building-an-echobot"}],"href":"/de/developing/category/building-a-cwtch-app"}]},"docs":{"building-a-cwtch-app/building-an-echobot":{"id":"building-a-cwtch-app/building-an-echobot","title":"Building a Cwtch Echobot","description":"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/core-concepts":{"id":"building-a-cwtch-app/core-concepts","title":"Core Concepts","description":"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/intro":{"id":"building-a-cwtch-app/intro","title":"Getting Started","description":"Choosing A Cwtch Library","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Introduction to Cwtch Development","description":"- Core Concepts","sidebar":"tutorialSidebar"},"release":{"id":"release","title":"Release and Packaging Process","description":"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/f9d690e3.0acf5a91.js b/build-staging/de/assets/js/f9d690e3.0acf5a91.js new file mode 100644 index 00000000..1752ea84 --- /dev/null +++ b/build-staging/de/assets/js/f9d690e3.0acf5a91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2528],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>m});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=r.createContext({}),u=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},l=function(e){var n=u(e.components);return r.createElement(c.Provider,{value:n},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=u(t),h=i,m=d["".concat(c,".").concat(h)]||d[h]||p[h]||o;return t?r.createElement(m,a(a({ref:n},l),{},{components:t})):r.createElement(m,a({ref:n},l))}));function m(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=h;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s[d]="string"==typeof e?e:i,a[1]=s;for(var u=2;u<o;u++)a[u]=t[u];return r.createElement.apply(null,a)}return r.createElement.apply(null,t)}h.displayName="MDXCreateElement"},9029:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var r=t(7462),i=(t(7294),t(3905));const o={},a="Eingabe",s={unversionedId:"components/ui/input",id:"components/ui/input",title:"Eingabe",description:"Risiko: Abfangen von Cwtch-Inhalten oder Metadaten durch eine IME auf mobilen Ger\xe4ten",source:"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/input.md",sourceDirName:"components/ui",slug:"/components/ui/input",permalink:"/de/security/components/ui/input",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Bildervorschau",permalink:"/de/security/components/ui/image_previews"},next:{title:"Nachrichten Overlays",permalink:"/de/security/components/ui/overlays"}},c={},u=[{value:"Risiko: Abfangen von Cwtch-Inhalten oder Metadaten durch eine IME auf mobilen Ger\xe4ten",id:"risiko-abfangen-von-cwtch-inhalten-oder-metadaten-durch-eine-ime-auf-mobilen-ger\xe4ten",level:2}],l={toc:u},d="wrapper";function p(e){let{components:n,...t}=e;return(0,i.kt)(d,(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eingabe"},"Eingabe"),(0,i.kt)("h2",{id:"risiko-abfangen-von-cwtch-inhalten-oder-metadaten-durch-eine-ime-auf-mobilen-ger\xe4ten"},"Risiko: Abfangen von Cwtch-Inhalten oder Metadaten durch eine IME auf mobilen Ger\xe4ten"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Teilweise gemildert")),(0,i.kt)("p",null,"Jede Komponente, die die M\xf6glichkeit hat, Daten zwischen einer Person und der Cwtch-App abzufangen, stellt ein potenzielles Sicherheitsrisiko."),(0,i.kt)("p",null,"Einer der wahrscheinlichsten Abfangj\xe4ger ist ein IME (Input Method Editor) eines Drittanbieters, der h\xe4ufig um Zeichen zu erzeugen, die von ihrem Ger\xe4t nicht unterst\xfctzt werden."),(0,i.kt)("p",null,"Selbst gutartige und standardm\xe4\xdfige IME-Anwendungen k\xf6nnen unbeabsichtigt Informationen \xfcber den Inhalt einer Person preisgeben, z. B. durch Cloud-Synchronisierung, Cloud-\xdcbersetzung oder pers\xf6nliche W\xf6rterb\xfccher."),(0,i.kt)("p",null,"Letztlich kann dieses Problem nicht von Cwtch allein gel\xf6st werden, sondern stellt ein gr\xf6\xdferes Risiko dar, welches auf das gesamte mobile \xd6kosystem auswirkt."),(0,i.kt)("p",null,"Ein \xe4hnliches Risiko besteht auf dem Desktop durch die Verwendung \xe4hnlicher Eingabeanwendungen (zus\xe4tzlich zu den Software-Keyloggern), Wir sind jedoch der Ansicht, dass dies v\xf6llig au\xdferhalb des Rahmens der Cwtch-Risikobewertung liegt (in \xdcbereinstimmung mit anderen Angriffen auf die Sicherheit des zugrunde liegenden Betriebssystems selbst)."),(0,i.kt)("p",null,"Dies wird in Cwtch 1.2 teilweise durch die Verwendung von ",(0,i.kt)("inlineCode",{parentName:"p"},"enableIMEPersonalizedLearning: false")," entsch\xe4rft. Siehe ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/142"},"diesen PR")," f\xfcr weitere Informationen."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/fb3c1916.22eef329.js b/build-staging/de/assets/js/fb3c1916.22eef329.js new file mode 100644 index 00000000..e00b0c19 --- /dev/null +++ b/build-staging/de/assets/js/fb3c1916.22eef329.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[276],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),s=p(r),f=o,b=s["".concat(l,".").concat(f)]||s[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},8886:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},a="Introduction to Cwtch Development",c={unversionedId:"intro",id:"intro",title:"Introduction to Cwtch Development",description:"- Core Concepts",source:"@site/developing/intro.md",sourceDirName:".",slug:"/intro",permalink:"/de/developing/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Release and Packaging Process",permalink:"/de/developing/release"}},l={},p=[{value:"Contributing to Cwtch Core",id:"contributing-to-cwtch-core",level:2},{value:"Building Cwtch Bots",id:"building-cwtch-bots",level:2}],u={toc:p},s="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introduction-to-cwtch-development"},"Introduction to Cwtch Development"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/core-concepts"},"Core Concepts")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/intro"},"Security Handbook"))),(0,o.kt)("h2",{id:"contributing-to-cwtch-core"},"Contributing to Cwtch Core"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/release"},"Release and Packaging Process"))),(0,o.kt)("h2",{id:"building-cwtch-bots"},"Building Cwtch Bots"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"Choosing a Library")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/building-an-echobot"},"Echobot Tutorial"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/fd27e325.0befa4a1.js b/build-staging/de/assets/js/fd27e325.0befa4a1.js new file mode 100644 index 00000000..0ecaf8ab --- /dev/null +++ b/build-staging/de/assets/js/fd27e325.0befa4a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1199],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=r,d=u["".concat(s,".").concat(m)]||u[m]||h[m]||i;return n?o.createElement(d,c(c({ref:t},p),{},{components:n})):o.createElement(d,c({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,c=new Array(i);c[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:r,c[1]=a;for(var l=2;l<i;l++)c[l]=n[l];return o.createElement.apply(null,c)}return o.createElement.apply(null,n)}m.displayName="MDXCreateElement"},9327:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:3},c="Building a Cwtch Echobot",a={unversionedId:"building-a-cwtch-app/building-an-echobot",id:"building-a-cwtch-app/building-an-echobot",title:"Building a Cwtch Echobot",description:"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.",source:"@site/developing/building-a-cwtch-app/building-an-echobot.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/building-an-echobot",permalink:"/de/developing/building-a-cwtch-app/building-an-echobot",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Core Concepts",permalink:"/de/developing/building-a-cwtch-app/core-concepts"}},s={},l=[{value:"Using CwtchBot (Go)",id:"using-cwtchbot-go",level:2},{value:"Using Imp (Rust)",id:"using-imp-rust",level:2}],p={toc:l},u="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"building-a-cwtch-echobot"},"Building a Cwtch Echobot"),(0,r.kt)("p",null,"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent."),(0,r.kt)("p",null,"For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or\nframework."),(0,r.kt)("h2",{id:"using-cwtchbot-go"},"Using CwtchBot (Go)"),(0,r.kt)("admonition",{title:"CwtchBot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the CwtchBot framework.")),(0,r.kt)("p",null,"Start by creating a new Go project, and a file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.go"),". In the ",(0,r.kt)("inlineCode",{parentName:"p"},"main")," function:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "cwtch.im/cwtch/event"\n "cwtch.im/cwtch/model"\n "cwtch.im/cwtch/model/attr"\n "cwtch.im/cwtch/model/constants"\n "fmt"\n "git.openprivacy.ca/sarah/cwtchbot"\n _ "github.com/mutecomm/go-sqlcipher/v4"\n "os/user"\n "path"\n)\n\nfunc main() {\n user, _ := user.Current()\n cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")\n cwtchbot.Launch()\n\n // Set Some Profile Information\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")\n\n fmt.Printf("echobot address: %v\\n", cwtchbot.Peer.GetOnion())\n\n for {\n message := cwtchbot.Queue.Next()\n cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])\n switch message.EventType {\n case event.NewMessageFromPeer:\n msg := cwtchbot.UnpackMessage(message.Data[event.Data])\n fmt.Printf("Message: %v\\n", msg)\n reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n case event.ContactCreated:\n fmt.Printf("Auto approving stranger %v %v\\n", cid, message.Data[event.RemotePeer])\n // accept the stranger as a new contact\n cwtchbot.Peer.AcceptConversation(cid.ID)\n // Send Hello...\n reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n }\n }\n}\n')),(0,r.kt)("h2",{id:"using-imp-rust"},"Using Imp (Rust)"),(0,r.kt)("admonition",{title:"Imp (Rust) Bot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'use std::borrow::BorrowMut;\nuse std::thread;\nuse chrono::{DateTime, FixedOffset};\nuse libcwtch;\nuse libcwtch::CwtchLib;\nuse libcwtch::structs::*;\nuse libcwtch::event::*;\nuse cwtch_imp::imp;\nuse cwtch_imp::behaviour::*;\nuse cwtch_imp::imp::Imp;\n\nconst BOT_HOME: &str = "~/.cwtch/bots/echobot";\nconst BOT_NAME: &str = "echobot";\n\nstruct Echobot {}\n\nfn main() {\n let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();\n let event_loop_handle = thread::spawn(move || {\n let mut echobot = Echobot {};\n let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());\n bot.event_loop::<Echobot>(echobot.borrow_mut());\n });\n event_loop_handle.join().expect("Error running event loop");\n}\n\nimpl imp::EventHandler for Echobot {\n fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {\n let response = Message {\n o: MessageType::TextMessage,\n d: message.d,\n };\n cwtch.send_message(&profile.profile_id, conversation_id, &response);\n }\n\n fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {\n match event {\n Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {\n println!(\n "\\n***** {} at {} *****\\n",\n name, profile_id.as_str()\n );\n }\n _ => (),\n };\n }\n}\n')))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/fe1dd7ae.bb7908e8.js b/build-staging/de/assets/js/fe1dd7ae.bb7908e8.js new file mode 100644 index 00000000..28615466 --- /dev/null +++ b/build-staging/de/assets/js/fe1dd7ae.bb7908e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1979],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>u});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,a,n=function(e,t){if(null==e)return{};var r,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(r),m=n,u=h["".concat(l,".").concat(m)]||h[m]||g[m]||o;return r?a.createElement(u,i(i({ref:t},s),{},{components:r})):a.createElement(u,i({ref:t},s))}));function u(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=r[p];return a.createElement.apply(null,i)}return a.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1501:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/de/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"7. Juni 2023",tags:[{label:"cwtch",permalink:"/de/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/de/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/de/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/de/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/de/blog/cwtch-developer-documentation"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function g(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(9964).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},9964:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/fe6d997b.bf7f26e0.js b/build-staging/de/assets/js/fe6d997b.bf7f26e0.js new file mode 100644 index 00000000..791b3a71 --- /dev/null +++ b/build-staging/de/assets/js/fe6d997b.bf7f26e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2911],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),l=u(n),m=i,f=l["".concat(s,".").concat(m)]||l[m]||d[m]||o;return n?r.createElement(f,a(a({ref:t},c),{},{components:n})):r.createElement(f,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p[l]="string"==typeof e?e:i,a[1]=p;for(var u=2;u<o;u++)a[u]=n[u];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3411:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:7},a="Einen Gruppennamen bearbeiten",p={unversionedId:"groups/edit-group-name",id:"groups/edit-group-name",title:"Einen Gruppennamen bearbeiten",description:"Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.",source:"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/edit-group-name.md",sourceDirName:"groups",slug:"/groups/edit-group-name",permalink:"/de/docs/groups/edit-group-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/edit-group-name.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Wie man eine Gruppe verl\xe4sst?",permalink:"/de/docs/groups/leave-group"},next:{title:"Server verwalten",permalink:"/de/docs/groups/manage-known-servers"}},s={},u=[],c={toc:u},l="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(l,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"einen-gruppennamen-bearbeiten"},"Einen Gruppennamen bearbeiten"),(0,i.kt)("admonition",{title:"Experimentelle Funktionen erforderlich",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Diese Funktion erfordert, dass ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimente aktiviert")," und das ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Gruppen Experiment")," eingeschaltet ist.")),(0,i.kt)("p",null,"Gruppennamen sind privat, sie werden nicht weitergegeben, sie sind Ihr lokaler Name f\xfcr die Gruppe."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Gehe im Chat-Fenster zu den Einstellungen"),(0,i.kt)("li",{parentName:"ol"},"\xc4ndere den Namen der Gruppe"),(0,i.kt)("li",{parentName:"ol"},"Dr\xfccke den Speicherknopf"),(0,i.kt)("li",{parentName:"ol"},"Jetzt hat deine Gruppe einen neuen Namen")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/group_edit.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/main.2f831fc6.js b/build-staging/de/assets/js/main.2f831fc6.js new file mode 100644 index 00000000..1baa833a --- /dev/null +++ b/build-staging/de/assets/js/main.2f831fc6.js @@ -0,0 +1,2 @@ +/*! For license information please see main.2f831fc6.js.LICENSE.txt */ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),l=n(6887);const s={"001a236d":[()=>n.e(3951).then(n.bind(n,9024)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/change-password.md",9024],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"021fdb12":[()=>n.e(8351).then(n.t.bind(n,2596,19)),"~docs/default/category-dedocs-tutorialsidebar-category-einstellungen-12c.json",2596],"03e998ac":[()=>n.e(8581).then(n.t.bind(n,4437,19)),"~blog/default/de-blog-tags-bindings-3b5.json",4437],"0487f903":[()=>n.e(3629).then(n.bind(n,2169)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/share-file.md",2169],"0692a985":[()=>n.e(4228).then(n.bind(n,3076)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/intro.md",3076],"07a1a58f":[()=>n.e(7460).then(n.bind(n,9894)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/intro.md",9894],"0831902b":[()=>n.e(8932).then(n.bind(n,8479)),"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/share-key.md",8479],"0861b93e":[()=>n.e(2287).then(n.t.bind(n,3208,19)),"~blog/default/de-blog-tags-support-e95-list.json",3208],"0bd16fd2":[()=>n.e(6419).then(n.t.bind(n,2738,19)),"~blog/default/de-blog-tags-developer-documentation-1ea.json",2738],"0c915b16":[()=>n.e(2833).then(n.t.bind(n,6317,19)),"~blog/default/de-blog-tags-cwtch-page-2-295.json",6317],"0d64c1d9":[()=>n.e(8710).then(n.bind(n,9133)),"@site/blog/2023-01-20-reproducible-builds-bindings.md",9133],"0eb0d69b":[()=>n.e(1725).then(n.t.bind(n,7483,19)),"~blog/default/de-blog-tags-nightly-422.json",7483],"0f04f840":[()=>n.e(1118).then(n.t.bind(n,3099,19)),"~blog/default/de-blog-tags-repliqate-fb3-list.json",3099],"113ce370":[()=>n.e(7216).then(n.t.bind(n,3279,19)),"~blog/default/de-blog-tags-release-d36-list.json",3279],"12959a59":[()=>n.e(3249).then(n.t.bind(n,7097,19)),"~docs/docs-security/category-desecurity-tutorialsidebar-category-cwtch-fcf.json",7097],"141cdfa9":[()=>n.e(7293).then(n.bind(n,677)),"@site/blog/2023-04-06-availability-and-profile-attributes.md?truncated=true",677],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],"15c93cf0":[()=>n.e(7970).then(n.t.bind(n,9712,19)),"~blog/default/de-blog-tags-cwtch-stable-page-2-8a0.json",9712],16771999:[()=>n.e(3271).then(n.bind(n,2322)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/change-language.md",2322],17896441:[()=>Promise.all([n.e(532),n.e(9785),n.e(7918)]).then(n.bind(n,5154)),"@theme/DocItem",5154],"18aaeea6":[()=>n.e(6354).then(n.bind(n,3728)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/file-sharing.md",3728],"1908c298":[()=>n.e(5578).then(n.t.bind(n,4630,19)),"~blog/default/de-blog-tags-testing-458.json",4630],"1a25c548":[()=>n.e(5732).then(n.bind(n,1202)),"@site/blog/2023-01-06-path-to-cwtch-stable.md?truncated=true",1202],"1a97c86e":[()=>n.e(3727).then(n.t.bind(n,9074,19)),"~blog/default/de-blog-page-2-525.json",9074],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1ebd8798":[()=>n.e(4788).then(n.bind(n,5558)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md?truncated=true",5558],"2114bf44":[()=>n.e(7252).then(n.bind(n,7460)),"@site/i18n/de/docusaurus-plugin-content-docs/current/tor.md",7460],"2250486b":[()=>n.e(7015).then(n.bind(n,7924)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/send-invite.md",7924],"291c70d7":[()=>n.e(725).then(n.t.bind(n,9574,19)),"~blog/default/de-blog-archive-b23.json",9574],"2bb9f32f":[()=>n.e(9162).then(n.bind(n,6852)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/qrcodes.md",6852],"326317af":[()=>n.e(5733).then(n.t.bind(n,5571,19)),"~blog/default/de-blog-tags-libcwtch-15a.json",5571],"373c7d5f":[()=>n.e(9085).then(n.bind(n,3819)),"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/create-server.md",3819],"37c407d1":[()=>n.e(2612).then(n.t.bind(n,4517,19)),"~blog/default/de-blog-tags-nightly-422-list.json",4517],39333829:[()=>n.e(2708).then(n.bind(n,4609)),"@site/i18n/de/docusaurus-plugin-content-docs/current/platforms/tails.md",4609],"3a109bd3":[()=>n.e(7782).then(n.bind(n,877)),"@site/blog/2023-03-10-cwtch-documentation.md?truncated=true",877],"3c1e1d04":[()=>n.e(563).then(n.bind(n,1884)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/unlock-profile.md",1884],"3db42865":[()=>n.e(7139).then(n.t.bind(n,3769,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"3e3471db":[()=>n.e(8510).then(n.bind(n,3018)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/delete-profile.md",3018],"41944db3":[()=>n.e(7495).then(n.t.bind(n,9212,19)),"~blog/default/de-blog-d2f.json",9212],"4350c8c2":[()=>n.e(9369).then(n.bind(n,7019)),"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/introduction.md",7019],"43b107c1":[()=>n.e(9200).then(n.bind(n,1168)),"@site/blog/2023-02-03-cwtch-testing-i.md",1168],"43bdde93":[()=>n.e(1197).then(n.t.bind(n,5369,19)),"~blog/default/de-blog-tags-testing-458-list.json",5369],"4aa555c3":[()=>n.e(7797).then(n.bind(n,3449)),"@site/blog/2023-06-16-cwtch-1.12.md?truncated=true",3449],"4d27f429":[()=>n.e(788).then(n.bind(n,7362)),"@site/blog/2023-01-20-reproducible-builds-bindings.md?truncated=true",7362],"4dde1d77":[()=>n.e(6153).then(n.bind(n,1634)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/connectivity/intro.md",1634],"4f68bcc6":[()=>n.e(3516).then(n.t.bind(n,4289,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-security/plugin-route-context-module-100.json",4289],"4fad3920":[()=>n.e(6862).then(n.t.bind(n,2511,19)),"~blog/default/de-blog-tags-cwtch-stable-c98-list.json",2511],"523378a0":[()=>n.e(9475).then(n.t.bind(n,8264,19)),"~blog/default/de-blog-tags-autobindings-601-list.json",8264],"53cc4802":[()=>n.e(7594).then(n.bind(n,3109)),"@site/blog/2023-02-03-cwtch-testing-i.md?truncated=true",3109],"53f3dc0a":[()=>n.e(4908).then(n.bind(n,9849)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/change-profile-image.md",9849],"549d43e9":[()=>n.e(8959).then(n.t.bind(n,2103,19)),"~blog/default/de-blog-tags-cwtch-stable-page-2-8a0-list.json",2103],"5549e0e2":[()=>n.e(6452).then(n.t.bind(n,642,19)),"~docs/default/category-dedocs-tutorialsidebar-category-konversationen-b6a.json",642],"55bf5a51":[()=>n.e(497).then(n.bind(n,824)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/ui-columns.md",824],"56c80d06":[()=>n.e(1032).then(n.bind(n,7193)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/delete-contact.md",7193],"57fc9be0":[()=>n.e(1091).then(n.t.bind(n,4902,19)),"~docs/default/category-dedocs-tutorialsidebar-category-plattformen-2a6.json",4902],"58b7fc4c":[()=>n.e(6769).then(n.bind(n,9414)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/introduction.md",9414],"5a2a7ed5":[()=>n.e(7432).then(n.bind(n,3645)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/group-experiment.md",3645],"5a84578f":[()=>n.e(5045).then(n.t.bind(n,8415,19)),"~blog/default/de-blog-tags-tags-368.json",8415],"5ab392cd":[()=>n.e(6431).then(n.bind(n,7115)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/availability-status.md",7115],"5bdf583d":[()=>n.e(9978).then(n.t.bind(n,2740,19)),"~blog/default/de-blog-tags-security-handbook-29b-list.json",2740],"5beee875":[()=>n.e(9444).then(n.bind(n,2724)),"@site/blog/2023-06-07-new-nightly.md",2724],"5bfc32c8":[()=>n.e(1280).then(n.bind(n,2194)),"@site/i18n/de/docusaurus-plugin-content-docs/current/intro.md",2194],"5cb298ca":[()=>n.e(2909).then(n.bind(n,4673)),"@site/blog/2023-04-28-developer-docs.md?truncated=true",4673],"5d8d36f7":[()=>n.e(1740).then(n.bind(n,5146)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/manage-known-servers.md",5146],"5dc151e9":[()=>n.e(923).then(n.bind(n,2320)),"@site/developing/release.md",2320],"5e5faacc":[()=>n.e(8192).then(n.bind(n,9655)),"@site/blog/2023-01-27-platform-support.md",9655],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"5f9a9669":[()=>n.e(3278).then(n.bind(n,4962)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/block-contact.md",4962],"5fdc7b06":[()=>n.e(2619).then(n.t.bind(n,2401,19)),"~docs/default/category-dedocs-tutorialsidebar-category-gruppen-548.json",2401],"6036bdcc":[()=>n.e(1745).then(n.bind(n,4611)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/clickable-links.md",4611],61794344:[()=>n.e(6232).then(n.bind(n,4669)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",4669],"6275ceb4":[()=>n.e(6555).then(n.bind(n,248)),"@site/blog/2023-03-10-cwtch-documentation.md",248],63475243:[()=>n.e(6275).then(n.bind(n,6904)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/tapir/authentication_protocol.md",6904],"6875c492":[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"6937af2a":[()=>n.e(4814).then(n.t.bind(n,3986,19)),"~blog/default/de-blog-tags-cwtch-9d5.json",3986],"69baf694":[()=>n.e(6204).then(n.bind(n,3092)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/accept-group-invite.md",3092],"6a78f460":[()=>n.e(439).then(n.bind(n,2982)),"@site/blog/2023-04-06-availability-and-profile-attributes.md",2982],"6e606510":[()=>n.e(764).then(n.bind(n,6841)),"@site/i18n/de/docusaurus-plugin-content-docs/current/getting-started/supported_platforms.md",6841],"6e61466c":[()=>n.e(1756).then(n.t.bind(n,658,19)),"~docs/default/category-dedocs-tutorialsidebar-category-verhalten-13d.json",658],"6f232d8e":[()=>n.e(2738).then(n.bind(n,5491)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/overlays.md",5491],"708a1ab9":[()=>n.e(1020).then(n.t.bind(n,2771,19)),"~docs/docs-security/category-desecurity-tutorialsidebar-category-verbindung-tor-87f.json",2771],"72a13759":[()=>n.e(3642).then(n.bind(n,8346)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/conversation-settings.md",8346],"746f1580":[()=>n.e(9508).then(n.t.bind(n,2849,19)),"~docs/default/category-dedocs-tutorialsidebar-category-erste-schritte-30c.json",2849],"75bff082":[()=>n.e(1132).then(n.t.bind(n,5670,19)),"~docs/default/category-dedocs-tutorialsidebar-category-server-dd4.json",5670],"773ceef9":[()=>n.e(337).then(n.t.bind(n,8362,19)),"~blog/default/de-blog-tags-release-d36.json",8362],"7747f3f6":[()=>n.e(5117).then(n.bind(n,9756)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/unblock-contact.md",9756],"78625d6f":[()=>n.e(3952).then(n.bind(n,8642)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/streamer-mode.md",8642],"787066a3":[()=>n.e(8357).then(n.bind(n,3810)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/create-a-profile.md",3810],"78e4de8f":[()=>n.e(4481).then(n.bind(n,8291)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/message-formatting.md",8291],"7a34d4a9":[()=>n.e(5508).then(n.t.bind(n,3783,19)),"~blog/default/de-blog-tags-reproducible-builds-4e9.json",3783],"7bea1ff1":[()=>n.e(362).then(n.bind(n,6356)),"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/developing.md",6356],"7c7a84a1":[()=>n.e(2979).then(n.bind(n,5501)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/image_previews.md",5501],"803df0d9":[()=>n.e(2112).then(n.bind(n,3020)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/accept-deny-new-conversation.md",3020],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],"824a28c6":[()=>n.e(5905).then(n.bind(n,9347)),"@site/developing/building-a-cwtch-app/intro.md",9347],"85f98c10":[()=>n.e(420).then(n.t.bind(n,2294,19)),"~blog/default/de-blog-tags-security-handbook-29b.json",2294],"8638bedc":[()=>n.e(8493).then(n.bind(n,3637)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/introduction.md",3637],"89504eb8":[()=>n.e(5745).then(n.t.bind(n,5758,19)),"~blog/default/de-blog-tags-documentation-ad6-list.json",5758],"89f86a37":[()=>n.e(9759).then(n.bind(n,9366)),"@site/blog/2023-03-29-cwtch-1.11.md?truncated=true",9366],"8b57ba24":[()=>n.e(3407).then(n.bind(n,546)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/appearance/light-dark-mode.md",546],"8e4780ba":[()=>n.e(2044).then(n.t.bind(n,8895,19)),"~docs/default/category-dedocs-tutorialsidebar-category-profile-356.json",8895],"8fe7a387":[()=>n.e(5233).then(n.bind(n,9667)),"@site/blog/2023-03-03-autobindings-optional-experiments.md",9667],"92123ee2":[()=>n.e(6773).then(n.bind(n,3465)),"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/edit-server.md",3465],"924c44fc":[()=>n.e(3413).then(n.bind(n,9643)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/behaviour/notification-policy.md",9643],"9323a439":[()=>n.e(6395).then(n.bind(n,4643)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/deployment.md",4643],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"940964f5":[()=>n.e(9178).then(n.t.bind(n,7186,19)),"~blog/default/de-blog-tags-cwtch-9d5-list.json",7186],"9428180e":[()=>n.e(9550).then(n.bind(n,3221)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/profile-info.md",3221],"948dc444":[()=>n.e(8851).then(n.bind(n,7159)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/image-previews-and-profile-pictures.md",7159],"979b71b8":[()=>n.e(2543).then(n.t.bind(n,1708,19)),"~blog/default/de-blog-tags-api-85d.json",1708],"980b70df":[()=>n.e(6900).then(n.t.bind(n,4444,19)),"~blog/default/de-blog-tags-bindings-3b5-list.json",4444],98609693:[()=>n.e(9794).then(n.bind(n,7960)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/introduction.md",7960],"995c4a51":[()=>n.e(4582).then(n.bind(n,8492)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/behaviour/block-unknown-connections.md",8492],"9ad9d6dc":[()=>n.e(828).then(n.bind(n,1472)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/tapir/packet_format.md",1472],"9b12a270":[()=>n.e(9249).then(n.bind(n,9816)),"@site/blog/2023-02-10-android-reproducibility.md",9816],"9bd730d3":[()=>n.e(2051).then(n.bind(n,9735)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/share-address-with-friends.md",9735],"9bec89a3":[()=>n.e(8344).then(n.t.bind(n,5294,19)),"~blog/default/de-blog-tags-planning-1f4.json",5294],"9c488c02":[()=>n.e(97).then(n.bind(n,7580)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/risk.md",7580],"9dd8190d":[()=>n.e(2688).then(n.bind(n,7561)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",7561],"9e2a7473":[()=>n.e(1258).then(n.bind(n,8725)),"@site/blog/2023-01-13-cwtch-stable-api-design.md",8725],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],"9f1c7621":[()=>n.e(1312).then(n.bind(n,4387)),"@site/blog/2023-02-17-cwtch-testing-ii.md",4387],a02b4022:[()=>n.e(3492).then(n.bind(n,4889)),"@site/blog/2023-06-16-cwtch-1.12.md",4889],a1dbc401:[()=>n.e(263).then(n.bind(n,402)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/development.md",402],a65a3c47:[()=>n.e(7591).then(n.bind(n,5432)),"@site/blog/2023-04-28-developer-docs.md",5432],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(3089)]).then(n.bind(n,46)),"@theme/BlogListPage",46],a79c88c2:[()=>n.e(9976).then(n.bind(n,8553)),"@site/blog/2023-01-13-cwtch-stable-api-design.md?truncated=true",8553],a85d9f35:[()=>n.e(2849).then(n.t.bind(n,8263,19)),"~blog/default/de-blog-tags-repliqate-fb3.json",8263],a8c7fdc6:[()=>n.e(1602).then(n.t.bind(n,6454,19)),"~docs/docs-security/version-current-metadata-prop-751.json",6454],a8d50805:[()=>n.e(6536).then(n.bind(n,7591)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/save-conversation-history.md",7591],a92fc3a1:[()=>n.e(8980).then(n.t.bind(n,7215,19)),"~blog/default/de-blog-tags-cwtch-page-2-295-list.json",7215],aa1db8cb:[()=>n.e(2628).then(n.bind(n,6527)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/leave-group.md",6527],ab726e24:[()=>n.e(1370).then(n.bind(n,7420)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/server-hosting.md",7420],af23c5f9:[()=>n.e(3218).then(n.bind(n,4958)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",4958],afe8c04b:[()=>n.e(6011).then(n.t.bind(n,1693,19)),"~blog/default/de-blog-tags-documentation-ad6.json",1693],b0404c31:[()=>n.e(7860).then(n.bind(n,3478)),"@site/blog/2023-01-06-path-to-cwtch-stable.md",3478],b0f5629f:[()=>n.e(3250).then(n.t.bind(n,4255,19)),"~docs/default/category-dedocs-tutorialsidebar-category-experimentelle-funktionen-28e.json",4255],b125d866:[()=>n.e(8799).then(n.bind(n,1595)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md?truncated=true",1595],b17c3fe9:[()=>n.e(2096).then(n.bind(n,8331)),"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/testing.md",8331],b44f0b89:[()=>n.e(7044).then(n.bind(n,5810)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/server.md",5810],b802a7ab:[()=>n.e(716).then(n.bind(n,5576)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/reply-to-message.md",5576],b877509f:[()=>n.e(380).then(n.bind(n,1493)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ecosystem-overview.md",1493],b95aefa5:[()=>n.e(5674).then(n.t.bind(n,8474,19)),"~blog/default/de-blog-tags-autobindings-601.json",8474],b96d814b:[()=>n.e(5883).then(n.t.bind(n,4331,19)),"~blog/default/de-blog-tags-libcwtch-15a-list.json",4331],bba9d075:[()=>n.e(769).then(n.t.bind(n,595,19)),"~docs/docs-security/category-desecurity-tutorialsidebar-category-tapir-e05.json",595],bf059cf9:[()=>n.e(5273).then(n.bind(n,2626)),"@site/blog/2023-02-10-android-reproducibility.md?truncated=true",2626],bfe3d434:[()=>n.e(6295).then(n.bind(n,8195)),"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/delete-server.md",8195],c089f5db:[()=>n.e(4240).then(n.bind(n,9830)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/exporting-profile.md",9830],c1102df1:[()=>n.e(8225).then(n.bind(n,7816)),"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/translate.md",7816],c14f15fd:[()=>n.e(7649).then(n.bind(n,3071)),"@site/developing/building-a-cwtch-app/core-concepts.md",3071],c2f21224:[()=>n.e(5107).then(n.t.bind(n,4167,19)),"~docs/docs-security/category-desecurity-tutorialsidebar-category-cwtch-ui-330.json",4167],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,3261)),"@site/src/pages/index.js",3261],c5f4eaa1:[()=>n.e(8943).then(n.bind(n,3401)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/change-name.md",3401],c747432f:[()=>n.e(8835).then(n.bind(n,2090)),"@site/blog/2023-03-03-autobindings-optional-experiments.md?truncated=true",2090],c862d987:[()=>n.e(3906).then(n.bind(n,1765)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/experiments/message-formatting.md",1765],c94c4dfb:[()=>n.e(9146).then(n.t.bind(n,4469,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],c96c5262:[()=>n.e(3761).then(n.bind(n,5426)),"@site/blog/2023-03-29-cwtch-1.11.md",5426],c97dce39:[()=>n.e(5843).then(n.t.bind(n,992,19)),"~blog/default/de-blog-tags-api-85d-list.json",992],cc484fa2:[()=>n.e(2233).then(n.bind(n,5155)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/references.md",5155],ccc49370:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],d2095d9b:[()=>n.e(3508).then(n.bind(n,8893)),"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/stickers.md",8893],d5f314f9:[()=>n.e(5869).then(n.t.bind(n,9317,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-developer/plugin-route-context-module-100.json",9317],d72b1382:[()=>n.e(171).then(n.bind(n,3135)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/create-group.md",3135],da082baa:[()=>n.e(1865).then(n.bind(n,2276)),"@site/i18n/de/docusaurus-plugin-content-docs/current/profiles/importing-a-profile.md",2276],dc2bcacd:[()=>n.e(590).then(n.bind(n,3143)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/key_bundles.md",3143],dda846b3:[()=>n.e(9338).then(n.bind(n,3504)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/android.md",3504],de5e68d7:[()=>n.e(3233).then(n.bind(n,1644)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/groups.md",1644],decd0f12:[()=>n.e(3577).then(n.t.bind(n,8265,19)),"~blog/default/de-blog-tags-planning-1f4-list.json",8265],e0940a37:[()=>n.e(3887).then(n.bind(n,5254)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/message_formats.md",5254],e2df4ad2:[()=>n.e(8268).then(n.t.bind(n,983,19)),"~blog/default/de-blog-tags-cwtch-stable-c98.json",983],e3d8cb96:[()=>n.e(1194).then(n.t.bind(n,675,19)),"~docs/default/category-dedocs-tutorialsidebar-category-mitwirken-3d1.json",675],e445c1ea:[()=>n.e(6105).then(n.bind(n,1593)),"@site/i18n/de/docusaurus-plugin-content-docs/current/chat/add-contact.md",1593],e49fb087:[()=>n.e(214).then(n.bind(n,5505)),"@site/i18n/de/docusaurus-plugin-content-docs/current/contribute/documentation.md",5505],e6b5bfb1:[()=>n.e(2591).then(n.t.bind(n,6240,19)),"~docs/default/category-dedocs-tutorialsidebar-category-darstellung-d8e.json",6240],e7b1bf29:[()=>n.e(3717).then(n.t.bind(n,3516,19)),"~docs/docs-developer/category-dedeveloping-tutorialsidebar-category-eine-cwtch-app-erstellen-120.json",3516],e88d32a9:[()=>n.e(6585).then(n.t.bind(n,5745,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],e949296e:[()=>n.e(9149).then(n.bind(n,1552)),"@site/i18n/de/docusaurus-plugin-content-docs/current/servers/unlock-server.md",1552],ed1907a0:[()=>n.e(3767).then(n.t.bind(n,2167,19)),"~blog/default/de-blog-tags-support-e95.json",2167],ef78badf:[()=>n.e(5532).then(n.bind(n,5481)),"@site/blog/2023-01-27-platform-support.md?truncated=true",5481],efb6a870:[()=>n.e(1778).then(n.t.bind(n,8970,19)),"~docs/docs-security/category-desecurity-tutorialsidebar-category-cwtch-komponenten-6e1.json",8970],f041e880:[()=>n.e(5226).then(n.bind(n,3291)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md?truncated=true",3291],f3be3c38:[()=>n.e(4817).then(n.t.bind(n,5259,19)),"~blog/default/de-blog-tags-reproducible-builds-4e9-list.json",5259],f4799792:[()=>n.e(7992).then(n.t.bind(n,6719,19)),"~blog/default/de-blog-tags-developer-documentation-1ea-list.json",6719],f76a3b8e:[()=>n.e(2184).then(n.bind(n,3103)),"@site/blog/2023-02-17-cwtch-testing-ii.md?truncated=true",3103],f7e5475a:[()=>n.e(1814).then(n.bind(n,2984)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/introduction.md",2984],f83bd450:[()=>n.e(5246).then(n.bind(n,8185)),"@site/i18n/de/docusaurus-plugin-content-docs/current/settings/behaviour/notification-content.md",8185],f928e8d9:[()=>n.e(8786).then(n.t.bind(n,7160,19)),"~docs/docs-developer/version-current-metadata-prop-751.json",7160],f9d690e3:[()=>n.e(2528).then(n.bind(n,9029)),"@site/i18n/de/docusaurus-plugin-content-docs-docs-security/current/components/ui/input.md",9029],fb3c1916:[()=>n.e(276).then(n.bind(n,8886)),"@site/developing/intro.md",8886],fd27e325:[()=>n.e(1199).then(n.bind(n,9327)),"@site/developing/building-a-cwtch-app/building-an-echobot.md",9327],fe1dd7ae:[()=>n.e(1979).then(n.bind(n,1501)),"@site/blog/2023-06-07-new-nightly.md?truncated=true",1501],fe6d997b:[()=>n.e(2911).then(n.bind(n,3411)),"@site/i18n/de/docusaurus-plugin-content-docs/current/groups/edit-group-name.md",3411]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],p={},f=[],m=[],g=(0,u.Z)(o);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=s[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const f=[{path:"/de/blog",component:p("/de/blog","2e8"),exact:!0},{path:"/de/blog/archive",component:p("/de/blog/archive","1a3"),exact:!0},{path:"/de/blog/autobindings",component:p("/de/blog/autobindings","c2b"),exact:!0},{path:"/de/blog/autobindings-ii",component:p("/de/blog/autobindings-ii","1ad"),exact:!0},{path:"/de/blog/availability-status-profile-attributes",component:p("/de/blog/availability-status-profile-attributes","6a7"),exact:!0},{path:"/de/blog/cwtch-android-reproducibility",component:p("/de/blog/cwtch-android-reproducibility","4ca"),exact:!0},{path:"/de/blog/cwtch-bindings-reproducible",component:p("/de/blog/cwtch-bindings-reproducible","ad0"),exact:!0},{path:"/de/blog/cwtch-developer-documentation",component:p("/de/blog/cwtch-developer-documentation","578"),exact:!0},{path:"/de/blog/cwtch-documentation",component:p("/de/blog/cwtch-documentation","6ef"),exact:!0},{path:"/de/blog/cwtch-nightly-1-11",component:p("/de/blog/cwtch-nightly-1-11","785"),exact:!0},{path:"/de/blog/cwtch-nightly-1-12",component:p("/de/blog/cwtch-nightly-1-12","691"),exact:!0},{path:"/de/blog/cwtch-nightly-v.11-74",component:p("/de/blog/cwtch-nightly-v.11-74","cfa"),exact:!0},{path:"/de/blog/cwtch-platform-support",component:p("/de/blog/cwtch-platform-support","9cb"),exact:!0},{path:"/de/blog/cwtch-stable-api-design",component:p("/de/blog/cwtch-stable-api-design","2d7"),exact:!0},{path:"/de/blog/cwtch-stable-roadmap-update",component:p("/de/blog/cwtch-stable-roadmap-update","b9c"),exact:!0},{path:"/de/blog/cwtch-stable-roadmap-update-june",component:p("/de/blog/cwtch-stable-roadmap-update-june","f96"),exact:!0},{path:"/de/blog/cwtch-testing-i",component:p("/de/blog/cwtch-testing-i","6cf"),exact:!0},{path:"/de/blog/cwtch-testing-ii",component:p("/de/blog/cwtch-testing-ii","7bf"),exact:!0},{path:"/de/blog/page/2",component:p("/de/blog/page/2","21e"),exact:!0},{path:"/de/blog/path-to-cwtch-stable",component:p("/de/blog/path-to-cwtch-stable","13e"),exact:!0},{path:"/de/blog/tags",component:p("/de/blog/tags","e73"),exact:!0},{path:"/de/blog/tags/api",component:p("/de/blog/tags/api","6e1"),exact:!0},{path:"/de/blog/tags/autobindings",component:p("/de/blog/tags/autobindings","e5f"),exact:!0},{path:"/de/blog/tags/bindings",component:p("/de/blog/tags/bindings","b9e"),exact:!0},{path:"/de/blog/tags/cwtch",component:p("/de/blog/tags/cwtch","934"),exact:!0},{path:"/de/blog/tags/cwtch-stable",component:p("/de/blog/tags/cwtch-stable","b4f"),exact:!0},{path:"/de/blog/tags/cwtch-stable/page/2",component:p("/de/blog/tags/cwtch-stable/page/2","779"),exact:!0},{path:"/de/blog/tags/cwtch/page/2",component:p("/de/blog/tags/cwtch/page/2","fda"),exact:!0},{path:"/de/blog/tags/developer-documentation",component:p("/de/blog/tags/developer-documentation","6b3"),exact:!0},{path:"/de/blog/tags/documentation",component:p("/de/blog/tags/documentation","eba"),exact:!0},{path:"/de/blog/tags/libcwtch",component:p("/de/blog/tags/libcwtch","56b"),exact:!0},{path:"/de/blog/tags/nightly",component:p("/de/blog/tags/nightly","416"),exact:!0},{path:"/de/blog/tags/planning",component:p("/de/blog/tags/planning","2e8"),exact:!0},{path:"/de/blog/tags/release",component:p("/de/blog/tags/release","414"),exact:!0},{path:"/de/blog/tags/repliqate",component:p("/de/blog/tags/repliqate","54a"),exact:!0},{path:"/de/blog/tags/reproducible-builds",component:p("/de/blog/tags/reproducible-builds","b3d"),exact:!0},{path:"/de/blog/tags/security-handbook",component:p("/de/blog/tags/security-handbook","00f"),exact:!0},{path:"/de/blog/tags/support",component:p("/de/blog/tags/support","234"),exact:!0},{path:"/de/blog/tags/testing",component:p("/de/blog/tags/testing","f12"),exact:!0},{path:"/de/developing",component:p("/de/developing","7da"),routes:[{path:"/de/developing/building-a-cwtch-app/building-an-echobot",component:p("/de/developing/building-a-cwtch-app/building-an-echobot","ea6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/developing/building-a-cwtch-app/core-concepts",component:p("/de/developing/building-a-cwtch-app/core-concepts","19b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/developing/building-a-cwtch-app/intro",component:p("/de/developing/building-a-cwtch-app/intro","157"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/developing/category/building-a-cwtch-app",component:p("/de/developing/category/building-a-cwtch-app","c92"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/developing/intro",component:p("/de/developing/intro","60e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/developing/release",component:p("/de/developing/release","853"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/de/docs",component:p("/de/docs","41a"),routes:[{path:"/de/docs/category/appearance",component:p("/de/docs/category/appearance","d88"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/behaviour",component:p("/de/docs/category/behaviour","f3c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/contribute",component:p("/de/docs/category/contribute","60f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/conversations",component:p("/de/docs/category/conversations","fc8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/experiments",component:p("/de/docs/category/experiments","f3e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/getting-started",component:p("/de/docs/category/getting-started","ddf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/groups",component:p("/de/docs/category/groups","321"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/platforms",component:p("/de/docs/category/platforms","cdb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/profiles",component:p("/de/docs/category/profiles","c71"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/servers",component:p("/de/docs/category/servers","554"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/category/settings",component:p("/de/docs/category/settings","113"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/accept-deny-new-conversation",component:p("/de/docs/chat/accept-deny-new-conversation","486"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/add-contact",component:p("/de/docs/chat/add-contact","718"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/block-contact",component:p("/de/docs/chat/block-contact","494"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/conversation-settings",component:p("/de/docs/chat/conversation-settings","30f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/delete-contact",component:p("/de/docs/chat/delete-contact","2ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/introduction",component:p("/de/docs/chat/introduction","02c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/message-formatting",component:p("/de/docs/chat/message-formatting","c43"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/reply-to-message",component:p("/de/docs/chat/reply-to-message","638"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/save-conversation-history",component:p("/de/docs/chat/save-conversation-history","aaf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/share-address-with-friends",component:p("/de/docs/chat/share-address-with-friends","a0a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/share-file",component:p("/de/docs/chat/share-file","7a5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/chat/unblock-contact",component:p("/de/docs/chat/unblock-contact","4ae"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/contribute/developing",component:p("/de/docs/contribute/developing","9df"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/contribute/documentation",component:p("/de/docs/contribute/documentation","519"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/contribute/stickers",component:p("/de/docs/contribute/stickers","a8d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/contribute/testing",component:p("/de/docs/contribute/testing","5bb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/contribute/translate",component:p("/de/docs/contribute/translate","08b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/getting-started/supported_platforms",component:p("/de/docs/getting-started/supported_platforms","902"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/accept-group-invite",component:p("/de/docs/groups/accept-group-invite","09e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/create-group",component:p("/de/docs/groups/create-group","183"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/edit-group-name",component:p("/de/docs/groups/edit-group-name","f7a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/introduction",component:p("/de/docs/groups/introduction","db2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/leave-group",component:p("/de/docs/groups/leave-group","99e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/manage-known-servers",component:p("/de/docs/groups/manage-known-servers","7f8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/groups/send-invite",component:p("/de/docs/groups/send-invite","0fb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/intro",component:p("/de/docs/intro","22a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/platforms/tails",component:p("/de/docs/platforms/tails","478"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/availability-status",component:p("/de/docs/profiles/availability-status","c91"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/change-name",component:p("/de/docs/profiles/change-name","105"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/change-password",component:p("/de/docs/profiles/change-password","710"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/change-profile-image",component:p("/de/docs/profiles/change-profile-image","9db"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/create-a-profile",component:p("/de/docs/profiles/create-a-profile","ffb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/delete-profile",component:p("/de/docs/profiles/delete-profile","4e1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/exporting-profile",component:p("/de/docs/profiles/exporting-profile","782"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/importing-a-profile",component:p("/de/docs/profiles/importing-a-profile","00b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/introduction",component:p("/de/docs/profiles/introduction","4aa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/profile-info",component:p("/de/docs/profiles/profile-info","864"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/profiles/unlock-profile",component:p("/de/docs/profiles/unlock-profile","fca"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/servers/create-server",component:p("/de/docs/servers/create-server","36f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/servers/delete-server",component:p("/de/docs/servers/delete-server","721"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/servers/edit-server",component:p("/de/docs/servers/edit-server","c82"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/servers/introduction",component:p("/de/docs/servers/introduction","88b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/servers/share-key",component:p("/de/docs/servers/share-key","e79"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/servers/unlock-server",component:p("/de/docs/servers/unlock-server","e87"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/appearance/change-language",component:p("/de/docs/settings/appearance/change-language","92a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/appearance/light-dark-mode",component:p("/de/docs/settings/appearance/light-dark-mode","9b8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/appearance/streamer-mode",component:p("/de/docs/settings/appearance/streamer-mode","66f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/appearance/ui-columns",component:p("/de/docs/settings/appearance/ui-columns","72c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/behaviour/block-unknown-connections",component:p("/de/docs/settings/behaviour/block-unknown-connections","6b6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/behaviour/notification-content",component:p("/de/docs/settings/behaviour/notification-content","a3b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/behaviour/notification-policy",component:p("/de/docs/settings/behaviour/notification-policy","ff8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/clickable-links",component:p("/de/docs/settings/experiments/clickable-links","2ee"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/file-sharing",component:p("/de/docs/settings/experiments/file-sharing","e78"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/group-experiment",component:p("/de/docs/settings/experiments/group-experiment","ca3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/image-previews-and-profile-pictures",component:p("/de/docs/settings/experiments/image-previews-and-profile-pictures","ab5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/message-formatting",component:p("/de/docs/settings/experiments/message-formatting","9ec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/qrcodes",component:p("/de/docs/settings/experiments/qrcodes","0a3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/experiments/server-hosting",component:p("/de/docs/settings/experiments/server-hosting","17e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/settings/introduction",component:p("/de/docs/settings/introduction","b7a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/docs/tor",component:p("/de/docs/tor","8fb"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/de/security",component:p("/de/security","63f"),routes:[{path:"/de/security/category/connectivity--tor",component:p("/de/security/category/connectivity--tor","ae4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/category/cwtch",component:p("/de/security/category/cwtch","087"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/category/cwtch-components",component:p("/de/security/category/cwtch-components","028"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/category/cwtch-ui",component:p("/de/security/category/cwtch-ui","a39"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/category/tapir",component:p("/de/security/category/tapir","db3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/connectivity/intro",component:p("/de/security/components/connectivity/intro","69e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/cwtch/groups",component:p("/de/security/components/cwtch/groups","4ac"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/cwtch/key_bundles",component:p("/de/security/components/cwtch/key_bundles","1c3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/cwtch/message_formats",component:p("/de/security/components/cwtch/message_formats","2a0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/cwtch/server",component:p("/de/security/components/cwtch/server","e86"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/ecosystem-overview",component:p("/de/security/components/ecosystem-overview","f56"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/intro",component:p("/de/security/components/intro","b7e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/tapir/authentication_protocol",component:p("/de/security/components/tapir/authentication_protocol","1d9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/tapir/packet_format",component:p("/de/security/components/tapir/packet_format","81e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/ui/android",component:p("/de/security/components/ui/android","c38"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/ui/image_previews",component:p("/de/security/components/ui/image_previews","38e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/ui/input",component:p("/de/security/components/ui/input","670"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/components/ui/overlays",component:p("/de/security/components/ui/overlays","e2b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/deployment",component:p("/de/security/deployment","ba7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/development",component:p("/de/security/development","a32"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/intro",component:p("/de/security/intro","049"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/references",component:p("/de/security/references","d86"),exact:!0,sidebar:"tutorialSidebar"},{path:"/de/security/risk",component:p("/de/security/risk","311"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/de/",component:p("/de/","5da"),exact:!0},{path:"*",component:p("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),g=n(2263),h=n(4996),b=n(6668),v=n(1944),y=n(4711),w=n(9727),k=n(3320),S=n(197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),a=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,u.TH)();return e+(0,h.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function x(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(_,null),r.createElement(E,null),r.createElement(S.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),A=n(8940);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const a=s.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),P("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function R(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),R(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(N,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const D=O,I="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",j="__docusaurus-base-url-issue-banner-suggestion-container",B="__DOCUSAURUS_INSERT_BASEURL_BANNER";function F(e){return`\nwindow['${B}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${B}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${I}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${j}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n var suggestionContainer = document.getElementById('${j}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function z(){const{siteConfig:{baseUrl:e}}=(0,g.Z)();return(0,r.useLayoutEffect)((()=>{window[B]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,F(e))),r.createElement("div",{id:I}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(z,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,g.Z)(),i=(0,h.Z)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var G=n(4763);function q(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(G.Z,null,r.createElement(A.M,null,r.createElement(L.t,null,r.createElement(p,null,r.createElement($,null),r.createElement(x,null),r.createElement(U,null),r.createElement(D,{location:T(t)},e)))))}var H=n(6887);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var V=n(9670);const W=new Set,Y=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!K()&&!Y.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(H).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!Y.has(e))(e)&&(Y.add(e),R(e))},X=Object.freeze(Q);if(l.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;R(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(q,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"docs-security":{"path":"/de/security","versions":[{"name":"current","label":"N\xe4chste","isLast":true,"path":"/de/security","mainDocId":"intro","docs":[{"id":"components/connectivity/intro","path":"/de/security/components/connectivity/intro","sidebar":"tutorialSidebar"},{"id":"components/cwtch/groups","path":"/de/security/components/cwtch/groups","sidebar":"tutorialSidebar"},{"id":"components/cwtch/key_bundles","path":"/de/security/components/cwtch/key_bundles","sidebar":"tutorialSidebar"},{"id":"components/cwtch/message_formats","path":"/de/security/components/cwtch/message_formats","sidebar":"tutorialSidebar"},{"id":"components/cwtch/server","path":"/de/security/components/cwtch/server","sidebar":"tutorialSidebar"},{"id":"components/ecosystem-overview","path":"/de/security/components/ecosystem-overview","sidebar":"tutorialSidebar"},{"id":"components/intro","path":"/de/security/components/intro","sidebar":"tutorialSidebar"},{"id":"components/tapir/authentication_protocol","path":"/de/security/components/tapir/authentication_protocol","sidebar":"tutorialSidebar"},{"id":"components/tapir/packet_format","path":"/de/security/components/tapir/packet_format","sidebar":"tutorialSidebar"},{"id":"components/ui/android","path":"/de/security/components/ui/android","sidebar":"tutorialSidebar"},{"id":"components/ui/image_previews","path":"/de/security/components/ui/image_previews","sidebar":"tutorialSidebar"},{"id":"components/ui/input","path":"/de/security/components/ui/input","sidebar":"tutorialSidebar"},{"id":"components/ui/overlays","path":"/de/security/components/ui/overlays","sidebar":"tutorialSidebar"},{"id":"deployment","path":"/de/security/deployment","sidebar":"tutorialSidebar"},{"id":"development","path":"/de/security/development","sidebar":"tutorialSidebar"},{"id":"intro","path":"/de/security/intro","sidebar":"tutorialSidebar"},{"id":"references","path":"/de/security/references","sidebar":"tutorialSidebar"},{"id":"risk","path":"/de/security/risk","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-components","path":"/de/security/category/cwtch-components","sidebar":"tutorialSidebar"},{"id":"/category/connectivity--tor","path":"/de/security/category/connectivity--tor","sidebar":"tutorialSidebar"},{"id":"/category/tapir","path":"/de/security/category/tapir","sidebar":"tutorialSidebar"},{"id":"/category/cwtch","path":"/de/security/category/cwtch","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-ui","path":"/de/security/category/cwtch-ui","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/de/security/intro","label":"intro"}}}}],"breadcrumbs":true},"docs-developer":{"path":"/de/developing","versions":[{"name":"current","label":"N\xe4chste","isLast":true,"path":"/de/developing","mainDocId":"intro","docs":[{"id":"building-a-cwtch-app/building-an-echobot","path":"/de/developing/building-a-cwtch-app/building-an-echobot","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/core-concepts","path":"/de/developing/building-a-cwtch-app/core-concepts","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/intro","path":"/de/developing/building-a-cwtch-app/intro","sidebar":"tutorialSidebar"},{"id":"intro","path":"/de/developing/intro","sidebar":"tutorialSidebar"},{"id":"release","path":"/de/developing/release","sidebar":"tutorialSidebar"},{"id":"/category/building-a-cwtch-app","path":"/de/developing/category/building-a-cwtch-app","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/de/developing/intro","label":"intro"}}}}],"breadcrumbs":true},"default":{"path":"/de/docs","versions":[{"name":"current","label":"N\xe4chste","isLast":true,"path":"/de/docs","mainDocId":"intro","docs":[{"id":"chat/accept-deny-new-conversation","path":"/de/docs/chat/accept-deny-new-conversation","sidebar":"tutorialSidebar"},{"id":"chat/add-contact","path":"/de/docs/chat/add-contact","sidebar":"tutorialSidebar"},{"id":"chat/block-contact","path":"/de/docs/chat/block-contact","sidebar":"tutorialSidebar"},{"id":"chat/conversation-settings","path":"/de/docs/chat/conversation-settings","sidebar":"tutorialSidebar"},{"id":"chat/delete-contact","path":"/de/docs/chat/delete-contact","sidebar":"tutorialSidebar"},{"id":"chat/introduction","path":"/de/docs/chat/introduction","sidebar":"tutorialSidebar"},{"id":"chat/message-formatting","path":"/de/docs/chat/message-formatting","sidebar":"tutorialSidebar"},{"id":"chat/reply-to-message","path":"/de/docs/chat/reply-to-message","sidebar":"tutorialSidebar"},{"id":"chat/save-conversation-history","path":"/de/docs/chat/save-conversation-history","sidebar":"tutorialSidebar"},{"id":"chat/share-address-with-friends","path":"/de/docs/chat/share-address-with-friends","sidebar":"tutorialSidebar"},{"id":"chat/share-file","path":"/de/docs/chat/share-file","sidebar":"tutorialSidebar"},{"id":"chat/unblock-contact","path":"/de/docs/chat/unblock-contact","sidebar":"tutorialSidebar"},{"id":"contribute/developing","path":"/de/docs/contribute/developing","sidebar":"tutorialSidebar"},{"id":"contribute/documentation","path":"/de/docs/contribute/documentation","sidebar":"tutorialSidebar"},{"id":"contribute/stickers","path":"/de/docs/contribute/stickers","sidebar":"tutorialSidebar"},{"id":"contribute/testing","path":"/de/docs/contribute/testing","sidebar":"tutorialSidebar"},{"id":"contribute/translate","path":"/de/docs/contribute/translate","sidebar":"tutorialSidebar"},{"id":"getting-started/supported_platforms","path":"/de/docs/getting-started/supported_platforms","sidebar":"tutorialSidebar"},{"id":"groups/accept-group-invite","path":"/de/docs/groups/accept-group-invite","sidebar":"tutorialSidebar"},{"id":"groups/create-group","path":"/de/docs/groups/create-group","sidebar":"tutorialSidebar"},{"id":"groups/edit-group-name","path":"/de/docs/groups/edit-group-name","sidebar":"tutorialSidebar"},{"id":"groups/introduction","path":"/de/docs/groups/introduction","sidebar":"tutorialSidebar"},{"id":"groups/leave-group","path":"/de/docs/groups/leave-group","sidebar":"tutorialSidebar"},{"id":"groups/manage-known-servers","path":"/de/docs/groups/manage-known-servers","sidebar":"tutorialSidebar"},{"id":"groups/send-invite","path":"/de/docs/groups/send-invite","sidebar":"tutorialSidebar"},{"id":"intro","path":"/de/docs/intro","sidebar":"tutorialSidebar"},{"id":"platforms/tails","path":"/de/docs/platforms/tails","sidebar":"tutorialSidebar"},{"id":"profiles/availability-status","path":"/de/docs/profiles/availability-status","sidebar":"tutorialSidebar"},{"id":"profiles/change-name","path":"/de/docs/profiles/change-name","sidebar":"tutorialSidebar"},{"id":"profiles/change-password","path":"/de/docs/profiles/change-password","sidebar":"tutorialSidebar"},{"id":"profiles/change-profile-image","path":"/de/docs/profiles/change-profile-image","sidebar":"tutorialSidebar"},{"id":"profiles/create-a-profile","path":"/de/docs/profiles/create-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/delete-profile","path":"/de/docs/profiles/delete-profile","sidebar":"tutorialSidebar"},{"id":"profiles/exporting-profile","path":"/de/docs/profiles/exporting-profile","sidebar":"tutorialSidebar"},{"id":"profiles/importing-a-profile","path":"/de/docs/profiles/importing-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/introduction","path":"/de/docs/profiles/introduction","sidebar":"tutorialSidebar"},{"id":"profiles/profile-info","path":"/de/docs/profiles/profile-info","sidebar":"tutorialSidebar"},{"id":"profiles/unlock-profile","path":"/de/docs/profiles/unlock-profile","sidebar":"tutorialSidebar"},{"id":"servers/create-server","path":"/de/docs/servers/create-server","sidebar":"tutorialSidebar"},{"id":"servers/delete-server","path":"/de/docs/servers/delete-server","sidebar":"tutorialSidebar"},{"id":"servers/edit-server","path":"/de/docs/servers/edit-server","sidebar":"tutorialSidebar"},{"id":"servers/introduction","path":"/de/docs/servers/introduction","sidebar":"tutorialSidebar"},{"id":"servers/share-key","path":"/de/docs/servers/share-key","sidebar":"tutorialSidebar"},{"id":"servers/unlock-server","path":"/de/docs/servers/unlock-server","sidebar":"tutorialSidebar"},{"id":"settings/appearance/change-language","path":"/de/docs/settings/appearance/change-language","sidebar":"tutorialSidebar"},{"id":"settings/appearance/light-dark-mode","path":"/de/docs/settings/appearance/light-dark-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/streamer-mode","path":"/de/docs/settings/appearance/streamer-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/ui-columns","path":"/de/docs/settings/appearance/ui-columns","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/block-unknown-connections","path":"/de/docs/settings/behaviour/block-unknown-connections","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-content","path":"/de/docs/settings/behaviour/notification-content","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-policy","path":"/de/docs/settings/behaviour/notification-policy","sidebar":"tutorialSidebar"},{"id":"settings/experiments/clickable-links","path":"/de/docs/settings/experiments/clickable-links","sidebar":"tutorialSidebar"},{"id":"settings/experiments/file-sharing","path":"/de/docs/settings/experiments/file-sharing","sidebar":"tutorialSidebar"},{"id":"settings/experiments/group-experiment","path":"/de/docs/settings/experiments/group-experiment","sidebar":"tutorialSidebar"},{"id":"settings/experiments/image-previews-and-profile-pictures","path":"/de/docs/settings/experiments/image-previews-and-profile-pictures","sidebar":"tutorialSidebar"},{"id":"settings/experiments/message-formatting","path":"/de/docs/settings/experiments/message-formatting","sidebar":"tutorialSidebar"},{"id":"settings/experiments/qrcodes","path":"/de/docs/settings/experiments/qrcodes","sidebar":"tutorialSidebar"},{"id":"settings/experiments/server-hosting","path":"/de/docs/settings/experiments/server-hosting","sidebar":"tutorialSidebar"},{"id":"settings/introduction","path":"/de/docs/settings/introduction","sidebar":"tutorialSidebar"},{"id":"tor","path":"/de/docs/tor","sidebar":"tutorialSidebar"},{"id":"/category/getting-started","path":"/de/docs/category/getting-started","sidebar":"tutorialSidebar"},{"id":"/category/profiles","path":"/de/docs/category/profiles","sidebar":"tutorialSidebar"},{"id":"/category/conversations","path":"/de/docs/category/conversations","sidebar":"tutorialSidebar"},{"id":"/category/groups","path":"/de/docs/category/groups","sidebar":"tutorialSidebar"},{"id":"/category/servers","path":"/de/docs/category/servers","sidebar":"tutorialSidebar"},{"id":"/category/settings","path":"/de/docs/category/settings","sidebar":"tutorialSidebar"},{"id":"/category/appearance","path":"/de/docs/category/appearance","sidebar":"tutorialSidebar"},{"id":"/category/behaviour","path":"/de/docs/category/behaviour","sidebar":"tutorialSidebar"},{"id":"/category/experiments","path":"/de/docs/category/experiments","sidebar":"tutorialSidebar"},{"id":"/category/contribute","path":"/de/docs/category/contribute","sidebar":"tutorialSidebar"},{"id":"/category/platforms","path":"/de/docs/category/platforms","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/de/docs/intro","label":"intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en","es","de","it"],"path":"i18n","currentLocale":"de","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"},"es":{"label":"Espa\xf1ol","direction":"ltr","htmlLang":"es","calendar":"gregory","path":"es"},"de":{"label":"Deutsch","direction":"ltr","htmlLang":"de","calendar":"gregory","path":"de"},"it":{"label":"Italiano","direction":"ltr","htmlLang":"it","calendar":"gregory","path":"it"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"}}}'),c={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(412),o=n(5742),i=n(8780),l=n(7961);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(p,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),l=n(2263),s=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,l.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,a.useContext)(u),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const _=p||f;const x=(0,s.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(L=C,b&&(e=>e.startsWith("/"))(L)?k(L):L):void 0;var L;T&&x&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const A=(0,a.useRef)(!1),P=n?o.OL:o.rU,N=c.Z.canUseIntersectionObserver,R=(0,a.useRef)(),O=()=>{A.current||null==T||(window.docusaurus.preload(T),A.current=!0)};(0,a.useEffect)((()=>(!N&&x&&null!=T&&window.docusaurus.prefetch(T),()=>{N&&R.current&&R.current.disconnect()})),[R,T,N,x]);const D=T?.startsWith("#")??!1,I=!T||!x||D;return I||h||S.collectLink(T),I?a.createElement("a",(0,r.Z)({ref:E,href:T},_&&!x&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(P,(0,r.Z)({},v,{onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,N&&e&&x&&(R.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(R.current.unobserve(e),R.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),R.current.observe(e))},to:T},n&&{isActive:g,activeClassName:m}))}const f=a.forwardRef(p)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>g,gA:()=>p,_r:()=>u,Jo:()=>h,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7961:(e,t,n)=>{"use strict";n.d(t,{Z:()=>dt});var r=n(7294),a=n(6010),o=n(4763),i=n(1944),l=n(7462),s=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??m,{containerRef:n,onClick:a}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:`#${d}`,onClick:a}),t))}var h=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(g,{className:v.skipToContent})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...s}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},s),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E={closeButton:"closeButton_CVFx"};function _(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",E.closeButton,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const x={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(x.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(_,{onClick:n,className:T.announcementBarClose}))}var A=n(2961),P=n(2466);var N=n(902),R=n(3102);const O=r.createContext(null);function D(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,R.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,N.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(O.Provider,{value:n},t)}function I(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(O);if(!e)throw new N.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,R.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:I(o)})),[a,o,t])}function j(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var B=n(2949),F=n(2389);function z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function G(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const l=(0,F.Z)(),s=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!l&&$.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const q=r.memo(G),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,B.I)();return a?null:r.createElement(q,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return r.createElement(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,A.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(Y,null))}var Q=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:s,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,X.Z)(a),f=(0,X.Z)(t),m=(0,X.Z)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,J.Z)(o),h=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,g&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(Q.Z,(0,l.Z)({href:u?m:o},d,h)):r.createElement(Q.Z,(0,l.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},d,h))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),le=n(8596),se=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,l.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},s,{onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),s.children??s.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(_e,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(ne,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(_e,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var fe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ge="iconLanguage_nlXk";var he=n(1875);const be={searchBox:"searchBox_ZlJk"};function ve(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,be.searchBox)},t)}var ye=n(143),we=n(2802);var ke=n(373);const Se=e=>e.docs.find((t=>t.id===e.mainDocId));const Ee={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,se.Z)(),p=(0,fe.l)(),{search:f,hash:m}=(0,s.TH)(),g=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(pe,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:ge}),h),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(ve,{className:n},r.createElement(he.Z,null))},dropdown:pe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.vY)(t,a);return null===s?null:r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===s.path||!!i?.sidebar&&i.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,we.lO)(a)[0],s=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,l.Z)({},o,{label:s,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:p}=(0,s.TH)(),f=(0,ye.Iw)(n),m=(0,ye.gB)(n),{savePreferredVersionName:g}=(0,ke.J)(n),h=[...o,...m.map((e=>{const t=f.alternateDocVersions[e.name]??Se(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>g(e.name)}})),...i],b=(0,we.lO)(n)[0],v=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:Se(b).path;return h.length<=1?r.createElement(oe,(0,l.Z)({},u,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(pe,(0,l.Z)({},u,{mobile:t,label:v,to:y,items:h,isActive:a?()=>!1:void 0}))}};function _e(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function xe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(_e,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ce(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Te(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ce,{onClick:()=>t.hide()}),t.content)}function Le(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(j,{header:r.createElement(K,null),primaryMenu:r.createElement(xe,null),secondaryMenu:r.createElement(Te,null)}):null}const Ae={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Ne(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(a.current)return void(a.current=!1);const l=r?.scrollY,s=document.documentElement.scrollHeight-o.current,c=window.innerHeight;l&&i>=l?n(!1):i+c<s&&n(!0)})),(0,u.S)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ae.navbarHideable,!s&&Ae.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Pe,{onClick:i.toggle}),r.createElement(Le,null))}var Re=n(8780);const Oe={errorBoundaryError:"errorBoundaryError_a6uf"};function De(e){return r.createElement("button",(0,l.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function Ie(e){let{error:t}=e;const n=(0,Re.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:Oe.errorBoundaryError},n)}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const je="right";function Be(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Fe(){const{toggle:e,shown:t}=(0,A.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Be,null))}const ze={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Me,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(_e,e)))))}function $e(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function Ge(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??je)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement($e,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Fe,null),r.createElement(W,null),r.createElement(Ue,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ue,{items:a}),r.createElement(Z,{className:ze.colorModeToggle}),!o&&r.createElement(ve,null,r.createElement(he.Z,null)))})}function qe(){return r.createElement(Ne,null,r.createElement(Ge,null))}function He(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...s}=t,c=(0,X.Z)(n),u=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Q.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},s),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function Ze(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(He,{item:t}))}function Ve(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Ze,{key:t,item:e})))))}function We(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Ve,{key:t,column:e}))))}function Ye(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Ke(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(He,{item:t})}function Qe(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Ke,{item:e}),t.length!==n+1&&r.createElement(Ye,null))))))}function Xe(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(We,{columns:t}):r.createElement(Qe,{links:t})}var Je=n(941);const et={footerLogoLink:"footerLogoLink_BH7S"};function tt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Je.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function nt(e){let{logo:t}=e;return t.href?r.createElement(Q.Z,{href:t.href,className:et.footerLogoLink,target:t.target},r.createElement(tt,{logo:t})):r.createElement(tt,{logo:t})}function rt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function ot(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(at,{style:o,links:n&&n.length>0&&r.createElement(Xe,{links:n}),logo:a&&r.createElement(nt,{logo:a}),copyright:t&&r.createElement(rt,{copyright:t})})}const it=r.memo(ot),lt=(0,N.Qc)([B.S,k.pl,P.OC,ke.L5,i.VC,function(e){let{children:t}=e;return r.createElement(R.n2,null,r.createElement(A.M,null,r.createElement(D,null,t)))}]);function st(e){let{children:t}=e;return r.createElement(lt,null,t)}function ct(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(De,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(Ie,{error:t})))))}const ut={mainWrapper:"mainWrapper_z2l0"};function dt(e){const{children:t,noFooter:n,wrapperClassName:l,title:s,description:c}=e;return(0,b.t)(),r.createElement(st,null,r.createElement(i.d,{title:s,description:c}),r.createElement(y,null),r.createElement(L,null),r.createElement(qe,null),r.createElement("div",{id:d,className:(0,a.Z)(h.k.wrapper.main,ut.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(ct,e)},t)),!n&&r.createElement(it,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),l=n(2263),s=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},l=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.Z)(),{navbar:{title:n,logo:c}}=(0,s.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(c?.href||"/"),g=n?"":t,h=c?.alt??g;return a.createElement(o.Z,(0,r.Z)({to:m},f,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:h,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),l=n(2949);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,l.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(s.themedImage,s[`themedImage--${e}`],u)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>h});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const l="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?c:u}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const c=(0,a.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:s?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:l},r)}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:l})):null}function h(e){let{lazy:t,...n}=e;const r=t?g:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),a=n(2389),o=n(12),i=n(902),l=n(6668);const s=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===s.get(),d=e=>s.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),l=n(6668);const s=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>h});var r=n(7294),a=n(143),o=n(9935),i=n(6668),l=n(2802),s=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function h(e){let{children:t}=e;return l.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(f);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(null===e)throw new a.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),l=(n(1688),n(902));function s(e){!function(e){const t=(0,i.k6)(),n=(0,l.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function c(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>x,Wl:()=>m,_F:()=>v,cE:()=>p,jA:()=>g,xz:()=>f,hI:()=>_,lO:()=>k,vY:()=>E,oz:()=>S,s1:()=>w});var r=n(7294),a=n(6550),o=n(8790),i=n(143),l=n(373),s=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!i._r;function f(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,a.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>v(e,t)));function v(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||b(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function w(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function S(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,l=i.find((e=>(0,a.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.H)(i),sidebarName:s,sidebarItems:c}}function x(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),c=n(2263);function u(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),l)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function f(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>s,i6:()=>l,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>s,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&a<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(a-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>s});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function s(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),l=o===n?e:e.replace(`/${o}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(a&&(a+=" "),a+=n);else for(t in e)e[t]&&(a&&(a+=" "),a+=t);return a}n.d(t,{Z:()=>a});const a=function(){for(var e,t,n=0,a="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(a&&(a+=" "),a+=t);return a}},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>L,Ep:()=>p});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r<a;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&a(e),s=t&&a(t),c=l||s;if(e&&a(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=i.length;p>=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(2177);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var g=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",v="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),g||(0,l.Z)(!1);var t,n=window.history,a=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,c=i.forceRefresh,w=void 0!==c&&c,k=i.getUserConfirmation,S=void 0===k?h:k,E=i.keyLength,_=void 0===E?6:E,x=e.basename?d(s(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,a=window.location,o=a.pathname+a.search+a.hash;return x&&(o=u(o,x)),f(o,r,n)}function T(){return Math.random().toString(36).substr(2,_)}var L=m();function A(e){(0,r.Z)(U,e),U.length=n.length,L.notifyListeners(U.location,U.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||O(C(e.state))}function N(){O(C(y()))}var R=!1;function O(e){if(R)R=!1,A();else{L.confirmTransitionTo(e,"POP",S,(function(t){t?A({action:"POP",location:e}):function(e){var t=U.location,n=I.indexOf(t.key);-1===n&&(n=0);var r=I.indexOf(e.key);-1===r&&(r=0);var a=n-r;a&&(R=!0,j(a))}(e)}))}}var D=C(y()),I=[D.key];function M(e){return x+p(e)}function j(e){n.go(e)}var B=0;function F(e){1===(B+=e)&&1===e?(window.addEventListener(b,P),o&&window.addEventListener(v,N)):0===B&&(window.removeEventListener(b,P),o&&window.removeEventListener(v,N))}var z=!1;var U={length:n.length,action:"POP",location:D,createHref:M,push:function(e,t){var r="PUSH",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,l=o.state;if(a)if(n.pushState({key:i,state:l},null,t),w)window.location.href=t;else{var s=I.indexOf(U.location.key),c=I.slice(0,s+1);c.push(o.key),I=c,A({action:r,location:o})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,l=o.state;if(a)if(n.replaceState({key:i,state:l},null,t),w)window.location.replace(t);else{var s=I.indexOf(U.location.key);-1!==s&&(I[s]=o.key),A({action:r,location:o})}else window.location.replace(t)}}))},go:j,goBack:function(){j(-1)},goForward:function(){j(1)},block:function(e){void 0===e&&(e=!1);var t=L.setPrompt(e);return z||(F(1),z=!0),function(){return z&&(z=!1,F(-1)),t()}},listen:function(e){var t=L.appendListener(e);return F(1),function(){F(-1),t()}}};return U}var k="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+c(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:c,decodePath:s},slash:{encodePath:s,decodePath:s}};function E(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function _(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function x(e){window.location.replace(E(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),g||(0,l.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),a=n.getUserConfirmation,o=void 0===a?h:a,i=n.hashType,c=void 0===i?"slash":i,b=e.basename?d(s(e.basename)):"",v=S[c],y=v.encodePath,w=v.decodePath;function C(){var e=w(_());return b&&(e=u(e,b)),f(e)}var T=m();function L(e){(0,r.Z)(z,e),z.length=t.length,T.notifyListeners(z.location,z.action)}var A=!1,P=null;function N(){var e,t,n=_(),r=y(n);if(n!==r)x(r);else{var a=C(),i=z.location;if(!A&&(t=a,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===p(a))return;P=null,function(e){if(A)A=!1,L();else{var t="POP";T.confirmTransitionTo(e,t,o,(function(n){n?L({action:t,location:e}):function(e){var t=z.location,n=I.lastIndexOf(p(t));-1===n&&(n=0);var r=I.lastIndexOf(p(e));-1===r&&(r=0);var a=n-r;a&&(A=!0,M(a))}(e)}))}}(a)}}var R=_(),O=y(R);R!==O&&x(O);var D=C(),I=[p(D)];function M(e){t.go(e)}var j=0;function B(e){1===(j+=e)&&1===e?window.addEventListener(k,N):0===j&&window.removeEventListener(k,N)}var F=!1;var z={length:t.length,action:"POP",location:D,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=E(window.location.href)),n+"#"+y(b+p(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);if(_()!==a){P=t,function(e){window.location.hash=e}(a);var o=I.lastIndexOf(p(z.location)),i=I.slice(0,o+1);i.push(t),I=i,L({action:n,location:r})}else L()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);_()!==a&&(P=t,x(a));var o=I.indexOf(p(z.location));-1!==o&&(I[o]=t),L({action:n,location:r})}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return F||(B(1),F=!0),function(){return F&&(F=!1,B(-1)),t()}},listen:function(e){var t=T.appendListener(e);return B(1),function(){B(-1),t()}}};return z}function T(e,t,n){return Math.min(Math.max(e,t),n)}function L(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,a=t.initialEntries,o=void 0===a?["/"]:a,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,c=void 0===s?6:s,u=m();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function g(){return Math.random().toString(36).substr(2,c)}var h=T(l,0,o.length-1),b=o.map((function(e){return f(e,void 0,"string"==typeof e?g():e.key||g())})),v=p;function y(e){var t=T(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:v,push:function(e,t){var r="PUSH",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),g=s(n),h=0;h<i.length;++h){var b=i[h];if(!(o[b]||r&&r[b]||g&&g[b]||l&&l[b])){var v=p(n,b);try{c(t,b,v)}catch(y){}}}}return t}},1143:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function a(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s<arguments.length;s++){for(var c in o=Object(arguments[s]))n.call(o,c)&&(l[c]=o[c]);if(t){i=t(o);for(var u=0;u<i.length;u++)r.call(o,i[u])&&(l[i[u]]=o[i[u]])}}return l}},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(l+=e.slice(i,f),i=f+d.length,p)l+=p[1];else{var m=e[i],g=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=g&&null!=m&&m!==g,S="+"===y||"*"===y,E="?"===y||"*"===y,_=n[2]||u,x=b||v;r.push({name:h||o++,prefix:g||"",delimiter:_,optional:E,repeat:S,partial:k,asterisk:!!w,pattern:x?c(x):w?".*":"[^"+s(_)+"]+?"})}}return i<e.length&&(l+=e.substr(i)),l&&r.push(l),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function l(e,t){for(var n=new Array(e.length),a=0;a<e.length;a++)"object"==typeof e[a]&&(n[a]=new RegExp("^(?:"+e[a].pattern+")$",d(t)));return function(t,a){for(var o="",l=t||{},s=(a||{}).pretty?i:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=l[u.name];if(null==p){if(u.optional){u.partial&&(o+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(r(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=s(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):s(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');o+=u.prefix+d}}else o+=u}return o}}function s(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var a=(n=n||{}).strict,o=!1!==n.end,i="",l=0;l<e.length;l++){var c=e[l];if("string"==typeof c)i+=s(c);else{var p=s(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),i+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var m=s(n.delimiter||"/"),g=i.slice(-m.length)===m;return a||(i=(g?i.slice(0,-m.length):i)+"(?:"+m+"(?=$))?"),i+=o?"$":a&&g?"":"(?="+m+"|$)",u(new RegExp("^"+i,d(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],a=0;a<e.length;a++)r.push(f(e[a],t,n).source);return u(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},7410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var a,o;switch(n=n||{},r.util.type(t)){case"Object":if(o=r.util.objId(t),n[o])return n[o];for(var i in a={},n[o]=a,t)t.hasOwnProperty(i)&&(a[i]=e(t[i],n));return a;case"Array":return o=r.util.objId(t),n[o]?n[o]:(a=[],n[o]=a,t.forEach((function(t,r){a[r]=e(t,n)})),a);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var a in t)n[a]=t[a];return n},insertBefore:function(e,t,n,a){var o=(a=a||r.languages)[e],i={};for(var l in o)if(o.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=o[l])}var c=a[e];return a[e]=i,r.languages.DFS(r.languages,(function(t,n){n===c&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,a,o){o=o||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],a||l);var s=t[l],c=r.util.type(s);"Object"!==c||o[i(s)]?"Array"!==c||o[i(s)]||(o[i(s)]=!0,e(s,n,l,o)):(o[i(s)]=!0,e(s,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};return r.hooks.run("before-tokenize",o),o.tokens=r.tokenize(o.code,o.grammar),r.hooks.run("after-tokenize",o),a.stringify(r.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var a=new l;return s(a,a.head,e),i(e,a,t,a.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(a)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var a,o=0;a=n[o++];)a(t)}},Token:a};function a(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function o(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var o=a[1].length;a.index+=o,a[0]=a[0].slice(o)}return a}function i(e,t,n,l,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(d&&d.cause==p+","+m)return;var g=f[m],h=g.inside,b=!!g.lookbehind,v=!!g.greedy,y=g.alias;if(v&&!g.pattern.global){var w=g.pattern.toString().match(/[imsuy]*$/)[0];g.pattern=RegExp(g.pattern.source,w+"g")}for(var k=g.pattern||g,S=l.next,E=u;S!==t.tail&&!(d&&E>=d.reach);E+=S.value.length,S=S.next){var _=S.value;if(t.length>e.length)return;if(!(_ instanceof a)){var x,C=1;if(v){if(!(x=o(k,E,e,b))||x.index>=e.length)break;var T=x.index,L=x.index+x[0].length,A=E;for(A+=S.value.length;T>=A;)A+=(S=S.next).value.length;if(E=A-=S.value.length,S.value instanceof a)continue;for(var P=S;P!==t.tail&&(A<L||"string"==typeof P.value);P=P.next)C++,A+=P.value.length;C--,_=e.slice(E,A),x.index-=E}else if(!(x=o(k,0,_,b)))continue;T=x.index;var N=x[0],R=_.slice(0,T),O=_.slice(T+N.length),D=E+_.length;d&&D>d.reach&&(d.reach=D);var I=S.prev;if(R&&(I=s(t,I,R),E+=R.length),c(t,I,C),S=s(t,I,new a(p,h?r.tokenize(N,h):N,y,N)),O&&s(t,S,O),C>1){var M={cause:p+","+m,reach:D};i(e,t,n,S.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}return a.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var a="";return t.forEach((function(t){a+=e(t,n)})),a}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),r.hooks.run("wrap",o);var l="";for(var s in o.attributes)l+=" "+s+'="'+(o.attributes[s]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+l+">"+o.content+"</"+o.tag+">"},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i<a.length;i++)o[a[i]]=e.languages.bash[a[i]];e.languages.shell=e.languages.bash}(a),a.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var a=t[n];if("code"===a.type){var o=a.content[1],i=a.content[3];if(o&&i&&"code-language"===o.type&&"code-block"===i.type&&"string"==typeof o.content){var l=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),s="language-"+(l=(/[a-z][\w-]*/i.exec(l)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,s]:i.alias.push(s):i.alias=[s]}}else e(a.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,a=t.classes.length;r<a;r++){var o=t.classes[r],c=/language-(.+)/.exec(o);if(c){n=c[1];break}}var u,d=e.languages[n];if(d)t.content=e.highlight((u=t.content,u.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n);var r=l[t];return r||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var p="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=p,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(p);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var a=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=p(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),a.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),a.length>0)){var l=p(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s<l;s++){var c=t[s];"variable"===c.type&&a.indexOf(c.content)>=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return!1}return!0}function p(e,r){for(var a=1,o=n;o<t.length;o++){var i=t[o],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))a++;else if(r.test(l)&&0===--a)return o}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),a.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return u[n]=a,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=c(u[a]),f=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),f){var g=[f];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r<a;r++){var o=n[r];if("string"!=typeof o){var i=o.content;if(Array.isArray(i))if("template-string"===o.type){var l=i[1];if(3===i.length&&"string"!=typeof l&&"embedded-code"===l.type){var s=p(l),c=l.alias,d=Array.isArray(c)?c[0]:c,f=e.languages[d];if(!f)continue;i[1]=u(s,f,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(a),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var a=n[r],o=e.languages.javascript[a];"RegExp"===e.util.type(o)&&(o=e.languages.javascript[a]={pattern:o});var i=o.inside||{};o.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(a),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=!1;if("string"!=typeof a&&("tag"===a.type&&a.content[0]&&"tag"===a.content[0].type?"</"===a.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),r>0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(a>=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++a;var g=p.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),v=[];g&&v.push.apply(v,i([g])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function a(r,o){if(!(r in n)){o.push(r);var i=o.indexOf(r);if(i<o.length-1)throw new Error("Circular dependency: "+o.slice(i).join(" -> "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;a(m);){for(var g in p={},m){var h=s[g];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in f(b))if(v in u){p[b]=!0;break}for(var y in m=p)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return l[e]=a}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));var l=new Set,s={};function c(e,t){u(e,t),u(e+"Capture",t)}function u(e,t){for(s[e]=t,e=0;e<t.length;e++)l.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f=Object.prototype.hasOwnProperty,m={},g={};function h(e,t,n,r,a,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=a,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){b[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];b[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){b[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){b[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){b[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){b[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){b[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){b[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){b[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,r){var a=b.hasOwnProperty(t)?b[t]:null;(null!==a?0===a.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,a,r)&&(n=null),r||null===a?function(e){return!!f.call(g,e)||!f.call(m,e)&&(p.test(e)?g[e]=!0:(m[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):a.mustUseProperty?e[a.propertyName]=null===n?3!==a.type&&"":n:(t=a.attributeName,r=a.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(a=a.type)||4===a&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),b.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,S=60103,E=60106,_=60107,x=60108,C=60114,T=60109,L=60110,A=60112,P=60113,N=60120,R=60115,O=60116,D=60121,I=60128,M=60129,j=60130,B=60131;if("function"==typeof Symbol&&Symbol.for){var F=Symbol.for;S=F("react.element"),E=F("react.portal"),_=F("react.fragment"),x=F("react.strict_mode"),C=F("react.profiler"),T=F("react.provider"),L=F("react.context"),A=F("react.forward_ref"),P=F("react.suspense"),N=F("react.suspense_list"),R=F("react.memo"),O=F("react.lazy"),D=F("react.block"),F("react.scope"),I=F("react.opaque.id"),M=F("react.debug_trace_mode"),j=F("react.offscreen"),B=F("react.legacy_hidden")}var z,U="function"==typeof Symbol&&Symbol.iterator;function $(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=U&&e[U]||e["@@iterator"])?e:null}function G(e){if(void 0===z)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);z=t&&t[1]||""}return"\n"+z+e}var q=!1;function H(e,t){if(!e||q)return"";q=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(s){var r=s}Reflect.construct(e,[],t)}else{try{t.call()}catch(s){r=s}e.call(t.prototype)}else{try{throw Error()}catch(s){r=s}e()}}catch(s){if(s&&r&&"string"==typeof s.stack){for(var a=s.stack.split("\n"),o=r.stack.split("\n"),i=a.length-1,l=o.length-1;1<=i&&0<=l&&a[i]!==o[l];)l--;for(;1<=i&&0<=l;i--,l--)if(a[i]!==o[l]){if(1!==i||1!==l)do{if(i--,0>--l||a[i]!==o[l])return"\n"+a[i].replace(" at new "," at ")}while(1<=i&&0<=l);break}}}finally{q=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?G(e):""}function Z(e){switch(e.tag){case 5:return G(e.type);case 16:return G("Lazy");case 13:return G("Suspense");case 19:return G("SuspenseList");case 0:case 2:case 15:return e=H(e.type,!1);case 11:return e=H(e.type.render,!1);case 22:return e=H(e.type._render,!1);case 1:return e=H(e.type,!0);default:return""}}function V(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case E:return"Portal";case C:return"Profiler";case x:return"StrictMode";case P:return"Suspense";case N:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case L:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case A:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case R:return V(e.type);case D:return V(e._render);case O:t=e._payload,e=e._init;try{return V(e(t))}catch(n){}}return null}function W(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function Y(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function K(e){e._valueTracker||(e._valueTracker=function(e){var t=Y(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var a=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Y(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function X(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return a({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=W(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=W(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ae(e,t.type,n):t.hasOwnProperty("defaultValue")&&ae(e,t.type,W(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function re(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ae(e,t,n){"number"===t&&X(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function oe(e,t){return e=a({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a<n.length;a++)t["$"+n[a]]=!0;for(n=0;n<e.length;n++)a=t.hasOwnProperty("$"+e[n].value),e[n].selected!==a&&(e[n].selected=a),a&&r&&(e[n].defaultSelected=!0)}else{for(n=""+W(n),t=null,a=0;a<e.length;a++){if(e[a].value===n)return e[a].selected=!0,void(r&&(e[a].defaultSelected=!0));null!==t||e[a].disabled||(t=e[a])}null!==t&&(t.selected=!0)}}function le(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return a({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function se(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:W(n)}}function ce(e,t){var n=W(t.value),r=W(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ue(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function pe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function fe(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?pe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,ge,he=(ge=function(e,t){if(e.namespaceURI!==de.svg||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ge(e,t)}))}:ge);function be(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ve={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ye=["Webkit","ms","Moz","O"];function we(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ve.hasOwnProperty(e)&&ve[e]?(""+t).trim():t+"px"}function ke(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),a=we(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,a):e[n]=a}}Object.keys(ve).forEach((function(e){ye.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ve[t]=ve[e]}))}));var Se=a({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(Se[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function _e(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Ce=null,Te=null,Le=null;function Ae(e){if(e=na(e)){if("function"!=typeof Ce)throw Error(i(280));var t=e.stateNode;t&&(t=aa(t),Ce(e.stateNode,e.type,t))}}function Pe(e){Te?Le?Le.push(e):Le=[e]:Te=e}function Ne(){if(Te){var e=Te,t=Le;if(Le=Te=null,Ae(e),t)for(e=0;e<t.length;e++)Ae(t[e])}}function Re(e,t){return e(t)}function Oe(e,t,n,r,a){return e(t,n,r,a)}function De(){}var Ie=Re,Me=!1,je=!1;function Be(){null===Te&&null===Le||(De(),Ne())}function Fe(e,t){var n=e.stateNode;if(null===n)return null;var r=aa(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var ze=!1;if(d)try{var Ue={};Object.defineProperty(Ue,"passive",{get:function(){ze=!0}}),window.addEventListener("test",Ue,Ue),window.removeEventListener("test",Ue,Ue)}catch(ge){ze=!1}function $e(e,t,n,r,a,o,i,l,s){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var Ge=!1,qe=null,He=!1,Ze=null,Ve={onError:function(e){Ge=!0,qe=e}};function We(e,t,n,r,a,o,i,l,s){Ge=!1,qe=null,$e.apply(Ve,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ke(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Qe(e){if(Ye(e)!==e)throw Error(i(188))}function Xe(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var a=n.return;if(null===a)break;var o=a.alternate;if(null===o){if(null!==(r=a.return)){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return Qe(a),e;if(o===r)return Qe(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var l=!1,s=a.child;s;){if(s===n){l=!0,n=a,r=o;break}if(s===r){l=!0,r=a,n=o;break}s=s.sibling}if(!l){for(s=o.child;s;){if(s===n){l=!0,n=o,r=a;break}if(s===r){l=!0,r=o,n=a;break}s=s.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function Je(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var et,tt,nt,rt,at=!1,ot=[],it=null,lt=null,st=null,ct=new Map,ut=new Map,dt=[],pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ft(e,t,n,r,a){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:a,targetContainers:[r]}}function mt(e,t){switch(e){case"focusin":case"focusout":it=null;break;case"dragenter":case"dragleave":lt=null;break;case"mouseover":case"mouseout":st=null;break;case"pointerover":case"pointerout":ct.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":ut.delete(t.pointerId)}}function gt(e,t,n,r,a,o){return null===e||e.nativeEvent!==o?(e=ft(t,n,r,a,o),null!==t&&(null!==(t=na(t))&&tt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==a&&-1===t.indexOf(a)&&t.push(a),e)}function ht(e){var t=ta(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ke(n)))return e.blockedOn=t,void rt(e.lanePriority,(function(){o.unstable_runWithPriority(e.priority,(function(){nt(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function bt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=na(n))&&tt(t),e.blockedOn=n,!1;t.shift()}return!0}function vt(e,t,n){bt(e)&&n.delete(t)}function yt(){for(at=!1;0<ot.length;){var e=ot[0];if(null!==e.blockedOn){null!==(e=na(e.blockedOn))&&et(e);break}for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&ot.shift()}null!==it&&bt(it)&&(it=null),null!==lt&&bt(lt)&&(lt=null),null!==st&&bt(st)&&(st=null),ct.forEach(vt),ut.forEach(vt)}function wt(e,t){e.blockedOn===t&&(e.blockedOn=null,at||(at=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,yt)))}function kt(e){function t(t){return wt(t,e)}if(0<ot.length){wt(ot[0],e);for(var n=1;n<ot.length;n++){var r=ot[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==it&&wt(it,e),null!==lt&&wt(lt,e),null!==st&&wt(st,e),ct.forEach(t),ut.forEach(t),n=0;n<dt.length;n++)(r=dt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<dt.length&&null===(n=dt[0]).blockedOn;)ht(n),null===n.blockedOn&&dt.shift()}function St(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:St("Animation","AnimationEnd"),animationiteration:St("Animation","AnimationIteration"),animationstart:St("Animation","AnimationStart"),transitionend:St("Transition","TransitionEnd")},_t={},xt={};function Ct(e){if(_t[e])return _t[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in xt)return _t[e]=n[t];return e}d&&(xt=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var Tt=Ct("animationend"),Lt=Ct("animationiteration"),At=Ct("animationstart"),Pt=Ct("transitionend"),Nt=new Map,Rt=new Map,Ot=["abort","abort",Tt,"animationEnd",Lt,"animationIteration",At,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Pt,"transitionEnd","waiting","waiting"];function Dt(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],a=e[n+1];a="on"+(a[0].toUpperCase()+a.slice(1)),Rt.set(r,t),Nt.set(r,a),c(a,[r])}}(0,o.unstable_now)();var It=8;function Mt(e){if(0!=(1&e))return It=15,1;if(0!=(2&e))return It=14,2;if(0!=(4&e))return It=13,4;var t=24&e;return 0!==t?(It=12,t):0!=(32&e)?(It=11,32):0!==(t=192&e)?(It=10,t):0!=(256&e)?(It=9,256):0!==(t=3584&e)?(It=8,t):0!=(4096&e)?(It=7,4096):0!==(t=4186112&e)?(It=6,t):0!==(t=62914560&e)?(It=5,t):67108864&e?(It=4,67108864):0!=(134217728&e)?(It=3,134217728):0!==(t=805306368&e)?(It=2,t):0!=(1073741824&e)?(It=1,1073741824):(It=8,e)}function jt(e,t){var n=e.pendingLanes;if(0===n)return It=0;var r=0,a=0,o=e.expiredLanes,i=e.suspendedLanes,l=e.pingedLanes;if(0!==o)r=o,a=It=15;else if(0!==(o=134217727&n)){var s=o&~i;0!==s?(r=Mt(s),a=It):0!==(l&=o)&&(r=Mt(l),a=It)}else 0!==(o=n&~i)?(r=Mt(o),a=It):0!==l&&(r=Mt(l),a=It);if(0===r)return 0;if(r=n&((0>(r=31-Gt(r))?0:1<<r)<<1)-1,0!==t&&t!==r&&0==(t&i)){if(Mt(t),a<=It)return t;It=a}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)a=1<<(n=31-Gt(t)),r|=e[n],t&=~a;return r}function Bt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function Ft(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=zt(24&~t))?Ft(10,t):e;case 10:return 0===(e=zt(192&~t))?Ft(8,t):e;case 8:return 0===(e=zt(3584&~t))&&(0===(e=zt(4186112&~t))&&(e=512)),e;case 2:return 0===(t=zt(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function zt(e){return e&-e}function Ut(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function $t(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-Gt(t)]=n}var Gt=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(qt(e)/Ht|0)|0},qt=Math.log,Ht=Math.LN2;var Zt=o.unstable_UserBlockingPriority,Vt=o.unstable_runWithPriority,Wt=!0;function Yt(e,t,n,r){Me||De();var a=Qt,o=Me;Me=!0;try{Oe(a,e,t,n,r)}finally{(Me=o)||Be()}}function Kt(e,t,n,r){Vt(Zt,Qt.bind(null,e,t,n,r))}function Qt(e,t,n,r){var a;if(Wt)if((a=0==(4&t))&&0<ot.length&&-1<pt.indexOf(e))e=ft(null,e,t,n,r),ot.push(e);else{var o=Xt(e,t,n,r);if(null===o)a&&mt(e,r);else{if(a){if(-1<pt.indexOf(e))return e=ft(o,e,t,n,r),void ot.push(e);if(function(e,t,n,r,a){switch(t){case"focusin":return it=gt(it,e,t,n,r,a),!0;case"dragenter":return lt=gt(lt,e,t,n,r,a),!0;case"mouseover":return st=gt(st,e,t,n,r,a),!0;case"pointerover":var o=a.pointerId;return ct.set(o,gt(ct.get(o)||null,e,t,n,r,a)),!0;case"gotpointercapture":return o=a.pointerId,ut.set(o,gt(ut.get(o)||null,e,t,n,r,a)),!0}return!1}(o,e,t,n,r))return;mt(e,r)}Dr(e,t,r,null,n)}}}function Xt(e,t,n,r){var a=xe(r);if(null!==(a=ta(a))){var o=Ye(a);if(null===o)a=null;else{var i=o.tag;if(13===i){if(null!==(a=Ke(o)))return a;a=null}else if(3===i){if(o.stateNode.hydrate)return 3===o.tag?o.stateNode.containerInfo:null;a=null}else o!==a&&(a=null)}}return Dr(e,t,r,a,n),null}var Jt=null,en=null,tn=null;function nn(){if(tn)return tn;var e,t,n=en,r=n.length,a="value"in Jt?Jt.value:Jt.textContent,o=a.length;for(e=0;e<r&&n[e]===a[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===a[o-t];t++);return tn=a.slice(e,1<t?1-t:void 0)}function rn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function an(){return!0}function on(){return!1}function ln(e){function t(t,n,r,a,o){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=a,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(a):a[i]);return this.isDefaultPrevented=(null!=a.defaultPrevented?a.defaultPrevented:!1===a.returnValue)?an:on,this.isPropagationStopped=on,this}return a(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=an)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=an)},persist:function(){},isPersistent:an}),t}var sn,cn,un,dn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},pn=ln(dn),fn=a({},dn,{view:0,detail:0}),mn=ln(fn),gn=a({},fn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Tn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==un&&(un&&"mousemove"===e.type?(sn=e.screenX-un.screenX,cn=e.screenY-un.screenY):cn=sn=0,un=e),sn)},movementY:function(e){return"movementY"in e?e.movementY:cn}}),hn=ln(gn),bn=ln(a({},gn,{dataTransfer:0})),vn=ln(a({},fn,{relatedTarget:0})),yn=ln(a({},dn,{animationName:0,elapsedTime:0,pseudoElement:0})),wn=a({},dn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),kn=ln(wn),Sn=ln(a({},dn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},_n={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},xn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Cn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=xn[e])&&!!t[e]}function Tn(){return Cn}var Ln=a({},fn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=rn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?_n[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Tn,charCode:function(e){return"keypress"===e.type?rn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?rn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),An=ln(Ln),Pn=ln(a({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Nn=ln(a({},fn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Tn})),Rn=ln(a({},dn,{propertyName:0,elapsedTime:0,pseudoElement:0})),On=a({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Dn=ln(On),In=[9,13,27,32],Mn=d&&"CompositionEvent"in window,jn=null;d&&"documentMode"in document&&(jn=document.documentMode);var Bn=d&&"TextEvent"in window&&!jn,Fn=d&&(!Mn||jn&&8<jn&&11>=jn),zn=String.fromCharCode(32),Un=!1;function $n(e,t){switch(e){case"keyup":return-1!==In.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Gn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var qn=!1;var Hn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Zn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Hn[e.type]:"textarea"===t}function Vn(e,t,n,r){Pe(r),0<(t=Mr(t,"onChange")).length&&(n=new pn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Wn=null,Yn=null;function Kn(e){Lr(e,0)}function Qn(e){if(Q(ra(e)))return e}function Xn(e,t){if("change"===e)return t}var Jn=!1;if(d){var er;if(d){var tr="oninput"in document;if(!tr){var nr=document.createElement("div");nr.setAttribute("oninput","return;"),tr="function"==typeof nr.oninput}er=tr}else er=!1;Jn=er&&(!document.documentMode||9<document.documentMode)}function rr(){Wn&&(Wn.detachEvent("onpropertychange",ar),Yn=Wn=null)}function ar(e){if("value"===e.propertyName&&Qn(Yn)){var t=[];if(Vn(t,Yn,e,xe(e)),e=Kn,Me)e(t);else{Me=!0;try{Re(e,t)}finally{Me=!1,Be()}}}}function or(e,t,n){"focusin"===e?(rr(),Yn=n,(Wn=t).attachEvent("onpropertychange",ar)):"focusout"===e&&rr()}function ir(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Qn(Yn)}function lr(e,t){if("click"===e)return Qn(t)}function sr(e,t){if("input"===e||"change"===e)return Qn(t)}var cr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},ur=Object.prototype.hasOwnProperty;function dr(e,t){if(cr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!ur.call(t,n[r])||!cr(e[n[r]],t[n[r]]))return!1;return!0}function pr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function fr(e,t){var n,r=pr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=pr(r)}}function mr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function gr(){for(var e=window,t=X();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=X((e=t.contentWindow).document)}return t}function hr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var br=d&&"documentMode"in document&&11>=document.documentMode,vr=null,yr=null,wr=null,kr=!1;function Sr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;kr||null==vr||vr!==X(r)||("selectionStart"in(r=vr)&&hr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},wr&&dr(wr,r)||(wr=r,0<(r=Mr(yr,"onSelect")).length&&(t=new pn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=vr)))}Dt("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),Dt("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),Dt(Ot,2);for(var Er="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),_r=0;_r<Er.length;_r++)Rt.set(Er[_r],0);u("onMouseEnter",["mouseout","mouseover"]),u("onMouseLeave",["mouseout","mouseover"]),u("onPointerEnter",["pointerout","pointerover"]),u("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var xr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Cr=new Set("cancel close invalid load scroll toggle".split(" ").concat(xr));function Tr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,a,o,l,s,c){if(We.apply(this,arguments),Ge){if(!Ge)throw Error(i(198));var u=qe;Ge=!1,qe=null,He||(He=!0,Ze=u)}}(r,t,void 0,e),e.currentTarget=null}function Lr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],a=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,c=l.currentTarget;if(l=l.listener,s!==o&&a.isPropagationStopped())break e;Tr(a,l,c),o=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,c=l.currentTarget,l=l.listener,s!==o&&a.isPropagationStopped())break e;Tr(a,l,c),o=s}}}if(He)throw e=Ze,He=!1,Ze=null,e}function Ar(e,t){var n=oa(t),r=e+"__bubble";n.has(r)||(Or(t,e,2,!1),n.add(r))}var Pr="_reactListening"+Math.random().toString(36).slice(2);function Nr(e){e[Pr]||(e[Pr]=!0,l.forEach((function(t){Cr.has(t)||Rr(t,!1,e,null),Rr(t,!0,e,null)})))}function Rr(e,t,n,r){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,o=n;if("selectionchange"===e&&9!==n.nodeType&&(o=n.ownerDocument),null!==r&&!t&&Cr.has(e)){if("scroll"!==e)return;a|=2,o=r}var i=oa(o),l=e+"__"+(t?"capture":"bubble");i.has(l)||(t&&(a|=4),Or(o,e,a,t),i.add(l))}function Or(e,t,n,r){var a=Rt.get(t);switch(void 0===a?2:a){case 0:a=Yt;break;case 1:a=Kt;break;default:a=Qt}n=a.bind(null,t,n,e),a=void 0,!ze||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(a=!0),r?void 0!==a?e.addEventListener(t,n,{capture:!0,passive:a}):e.addEventListener(t,n,!0):void 0!==a?e.addEventListener(t,n,{passive:a}):e.addEventListener(t,n,!1)}function Dr(e,t,n,r,a){var o=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===a||8===l.nodeType&&l.parentNode===a)break;if(4===i)for(i=r.return;null!==i;){var s=i.tag;if((3===s||4===s)&&((s=i.stateNode.containerInfo)===a||8===s.nodeType&&s.parentNode===a))return;i=i.return}for(;null!==l;){if(null===(i=ta(l)))return;if(5===(s=i.tag)||6===s){r=o=i;continue e}l=l.parentNode}}r=r.return}!function(e,t,n){if(je)return e(t,n);je=!0;try{return Ie(e,t,n)}finally{je=!1,Be()}}((function(){var r=o,a=xe(n),i=[];e:{var l=Nt.get(e);if(void 0!==l){var s=pn,c=e;switch(e){case"keypress":if(0===rn(n))break e;case"keydown":case"keyup":s=An;break;case"focusin":c="focus",s=vn;break;case"focusout":c="blur",s=vn;break;case"beforeblur":case"afterblur":s=vn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":s=hn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":s=bn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":s=Nn;break;case Tt:case Lt:case At:s=yn;break;case Pt:s=Rn;break;case"scroll":s=mn;break;case"wheel":s=Dn;break;case"copy":case"cut":case"paste":s=kn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":s=Pn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==l?l+"Capture":null:l;u=[];for(var f,m=r;null!==m;){var g=(f=m).stateNode;if(5===f.tag&&null!==g&&(f=g,null!==p&&(null!=(g=Fe(m,p))&&u.push(Ir(m,g,f)))),d)break;m=m.return}0<u.length&&(l=new s(l,c,null,n,a),i.push({event:l,listeners:u}))}}if(0==(7&t)){if(s="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(c=n.relatedTarget||n.fromElement)||!ta(c)&&!c[Jr])&&(s||l)&&(l=a.window===a?a:(l=a.ownerDocument)?l.defaultView||l.parentWindow:window,s?(s=r,null!==(c=(c=n.relatedTarget||n.toElement)?ta(c):null)&&(c!==(d=Ye(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(s=null,c=r),s!==c)){if(u=hn,g="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Pn,g="onPointerLeave",p="onPointerEnter",m="pointer"),d=null==s?l:ra(s),f=null==c?l:ra(c),(l=new u(g,m+"leave",s,n,a)).target=d,l.relatedTarget=f,g=null,ta(a)===r&&((u=new u(p,m+"enter",c,n,a)).target=f,u.relatedTarget=d,g=u),d=g,s&&c)e:{for(p=c,m=0,f=u=s;f;f=jr(f))m++;for(f=0,g=p;g;g=jr(g))f++;for(;0<m-f;)u=jr(u),m--;for(;0<f-m;)p=jr(p),f--;for(;m--;){if(u===p||null!==p&&u===p.alternate)break e;u=jr(u),p=jr(p)}u=null}else u=null;null!==s&&Br(i,l,s,u,!1),null!==c&&null!==d&&Br(i,d,c,u,!0)}if("select"===(s=(l=r?ra(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===s&&"file"===l.type)var h=Xn;else if(Zn(l))if(Jn)h=sr;else{h=ir;var b=or}else(s=l.nodeName)&&"input"===s.toLowerCase()&&("checkbox"===l.type||"radio"===l.type)&&(h=lr);switch(h&&(h=h(e,r))?Vn(i,h,n,a):(b&&b(e,l,r),"focusout"===e&&(b=l._wrapperState)&&b.controlled&&"number"===l.type&&ae(l,"number",l.value)),b=r?ra(r):window,e){case"focusin":(Zn(b)||"true"===b.contentEditable)&&(vr=b,yr=r,wr=null);break;case"focusout":wr=yr=vr=null;break;case"mousedown":kr=!0;break;case"contextmenu":case"mouseup":case"dragend":kr=!1,Sr(i,n,a);break;case"selectionchange":if(br)break;case"keydown":case"keyup":Sr(i,n,a)}var v;if(Mn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else qn?$n(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Fn&&"ko"!==n.locale&&(qn||"onCompositionStart"!==y?"onCompositionEnd"===y&&qn&&(v=nn()):(en="value"in(Jt=a)?Jt.value:Jt.textContent,qn=!0)),0<(b=Mr(r,y)).length&&(y=new Sn(y,e,null,n,a),i.push({event:y,listeners:b}),v?y.data=v:null!==(v=Gn(n))&&(y.data=v))),(v=Bn?function(e,t){switch(e){case"compositionend":return Gn(t);case"keypress":return 32!==t.which?null:(Un=!0,zn);case"textInput":return(e=t.data)===zn&&Un?null:e;default:return null}}(e,n):function(e,t){if(qn)return"compositionend"===e||!Mn&&$n(e,t)?(e=nn(),tn=en=Jt=null,qn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Fn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Mr(r,"onBeforeInput")).length&&(a=new Sn("onBeforeInput","beforeinput",null,n,a),i.push({event:a,listeners:r}),a.data=v))}Lr(i,t)}))}function Ir(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Mr(e,t){for(var n=t+"Capture",r=[];null!==e;){var a=e,o=a.stateNode;5===a.tag&&null!==o&&(a=o,null!=(o=Fe(e,n))&&r.unshift(Ir(e,o,a)),null!=(o=Fe(e,t))&&r.push(Ir(e,o,a))),e=e.return}return r}function jr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Br(e,t,n,r,a){for(var o=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,c=l.stateNode;if(null!==s&&s===r)break;5===l.tag&&null!==c&&(l=c,a?null!=(s=Fe(n,o))&&i.unshift(Ir(n,s,l)):a||null!=(s=Fe(n,o))&&i.push(Ir(n,s,l))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function Fr(){}var zr=null,Ur=null;function $r(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function Gr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var qr="function"==typeof setTimeout?setTimeout:void 0,Hr="function"==typeof clearTimeout?clearTimeout:void 0;function Zr(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Vr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Wr(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Yr=0;var Kr=Math.random().toString(36).slice(2),Qr="__reactFiber$"+Kr,Xr="__reactProps$"+Kr,Jr="__reactContainer$"+Kr,ea="__reactEvents$"+Kr;function ta(e){var t=e[Qr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Jr]||n[Qr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Wr(e);null!==e;){if(n=e[Qr])return n;e=Wr(e)}return t}n=(e=n).parentNode}return null}function na(e){return!(e=e[Qr]||e[Jr])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function ra(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function aa(e){return e[Xr]||null}function oa(e){var t=e[ea];return void 0===t&&(t=e[ea]=new Set),t}var ia=[],la=-1;function sa(e){return{current:e}}function ca(e){0>la||(e.current=ia[la],ia[la]=null,la--)}function ua(e,t){la++,ia[la]=e.current,e.current=t}var da={},pa=sa(da),fa=sa(!1),ma=da;function ga(e,t){var n=e.type.contextTypes;if(!n)return da;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var a,o={};for(a in n)o[a]=t[a];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function ha(e){return null!=(e=e.childContextTypes)}function ba(){ca(fa),ca(pa)}function va(e,t,n){if(pa.current!==da)throw Error(i(168));ua(pa,t),ua(fa,n)}function ya(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(i(108,V(t)||"Unknown",o));return a({},n,r)}function wa(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||da,ma=pa.current,ua(pa,e),ua(fa,fa.current),!0}function ka(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=ya(e,t,ma),r.__reactInternalMemoizedMergedChildContext=e,ca(fa),ca(pa),ua(pa,e)):ca(fa),ua(fa,n)}var Sa=null,Ea=null,_a=o.unstable_runWithPriority,xa=o.unstable_scheduleCallback,Ca=o.unstable_cancelCallback,Ta=o.unstable_shouldYield,La=o.unstable_requestPaint,Aa=o.unstable_now,Pa=o.unstable_getCurrentPriorityLevel,Na=o.unstable_ImmediatePriority,Ra=o.unstable_UserBlockingPriority,Oa=o.unstable_NormalPriority,Da=o.unstable_LowPriority,Ia=o.unstable_IdlePriority,Ma={},ja=void 0!==La?La:function(){},Ba=null,Fa=null,za=!1,Ua=Aa(),$a=1e4>Ua?Aa:function(){return Aa()-Ua};function Ga(){switch(Pa()){case Na:return 99;case Ra:return 98;case Oa:return 97;case Da:return 96;case Ia:return 95;default:throw Error(i(332))}}function qa(e){switch(e){case 99:return Na;case 98:return Ra;case 97:return Oa;case 96:return Da;case 95:return Ia;default:throw Error(i(332))}}function Ha(e,t){return e=qa(e),_a(e,t)}function Za(e,t,n){return e=qa(e),xa(e,t,n)}function Va(){if(null!==Fa){var e=Fa;Fa=null,Ca(e)}Wa()}function Wa(){if(!za&&null!==Ba){za=!0;var e=0;try{var t=Ba;Ha(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),Ba=null}catch(n){throw null!==Ba&&(Ba=Ba.slice(e+1)),xa(Na,Va),n}finally{za=!1}}}var Ya=k.ReactCurrentBatchConfig;function Ka(e,t){if(e&&e.defaultProps){for(var n in t=a({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Qa=sa(null),Xa=null,Ja=null,eo=null;function to(){eo=Ja=Xa=null}function no(e){var t=Qa.current;ca(Qa),e.type._context._currentValue=t}function ro(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function ao(e,t){Xa=e,eo=Ja=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Mi=!0),e.firstContext=null)}function oo(e,t){if(eo!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(eo=e,t=1073741823),t={context:e,observedBits:t,next:null},null===Ja){if(null===Xa)throw Error(i(308));Ja=t,Xa.dependencies={lanes:0,firstContext:t,responders:null}}else Ja=Ja.next=t;return e._currentValue}var io=!1;function lo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function so(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function co(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function uo(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function po(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var a=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===o?a=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?a=o=t:o=o.next=t}else a=o=t;return n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:o,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function fo(e,t,n,r){var o=e.updateQueue;io=!1;var i=o.firstBaseUpdate,l=o.lastBaseUpdate,s=o.shared.pending;if(null!==s){o.shared.pending=null;var c=s,u=c.next;c.next=null,null===l?i=u:l.next=u,l=c;var d=e.alternate;if(null!==d){var p=(d=d.updateQueue).lastBaseUpdate;p!==l&&(null===p?d.firstBaseUpdate=u:p.next=u,d.lastBaseUpdate=c)}}if(null!==i){for(p=o.baseState,l=0,d=u=c=null;;){s=i.lane;var f=i.eventTime;if((r&s)===s){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var m=e,g=i;switch(s=t,f=n,g.tag){case 1:if("function"==typeof(m=g.payload)){p=m.call(f,p,s);break e}p=m;break e;case 3:m.flags=-4097&m.flags|64;case 0:if(null==(s="function"==typeof(m=g.payload)?m.call(f,p,s):m))break e;p=a({},p,s);break e;case 2:io=!0}}null!==i.callback&&(e.flags|=32,null===(s=o.effects)?o.effects=[i]:s.push(i))}else f={eventTime:f,lane:s,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(u=d=f,c=p):d=d.next=f,l|=s;if(null===(i=i.next)){if(null===(s=o.shared.pending))break;i=s.next,s.next=null,o.lastBaseUpdate=s,o.shared.pending=null}}null===d&&(c=p),o.baseState=c,o.firstBaseUpdate=u,o.lastBaseUpdate=d,Ul|=l,e.lanes=l,e.memoizedState=p}}function mo(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],a=r.callback;if(null!==a){if(r.callback=null,r=n,"function"!=typeof a)throw Error(i(191,a));a.call(r)}}}var go=(new r.Component).refs;function ho(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:a({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var bo={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=ps(),a=fs(e),o=co(r,a);o.payload=t,null!=n&&(o.callback=n),uo(e,o),ms(e,a,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=ps(),a=fs(e),o=co(r,a);o.tag=1,o.payload=t,null!=n&&(o.callback=n),uo(e,o),ms(e,a,r)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=ps(),r=fs(e),a=co(n,r);a.tag=2,null!=t&&(a.callback=t),uo(e,a),ms(e,r,n)}};function vo(e,t,n,r,a,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!dr(n,r)||!dr(a,o))}function yo(e,t,n){var r=!1,a=da,o=t.contextType;return"object"==typeof o&&null!==o?o=oo(o):(a=ha(t)?ma:pa.current,o=(r=null!=(r=t.contextTypes))?ga(e,a):da),t=new t(n,o),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=bo,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=a,e.__reactInternalMemoizedMaskedChildContext=o),t}function wo(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&bo.enqueueReplaceState(t,t.state,null)}function ko(e,t,n,r){var a=e.stateNode;a.props=n,a.state=e.memoizedState,a.refs=go,lo(e);var o=t.contextType;"object"==typeof o&&null!==o?a.context=oo(o):(o=ha(t)?ma:pa.current,a.context=ga(e,o)),fo(e,n,a,r),a.state=e.memoizedState,"function"==typeof(o=t.getDerivedStateFromProps)&&(ho(e,t,o,n),a.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof a.getSnapshotBeforeUpdate||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||(t=a.state,"function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount(),t!==a.state&&bo.enqueueReplaceState(a,a.state,null),fo(e,n,a,r),a.state=e.memoizedState),"function"==typeof a.componentDidMount&&(e.flags|=4)}var So=Array.isArray;function Eo(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=r.refs;t===go&&(t=r.refs={}),null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function _o(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function xo(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function a(e,t){return(e=Zs(e,t)).index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags=2,n):r:(t.flags=2,n):n}function l(t){return e&&null===t.alternate&&(t.flags=2),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ks(n,e.mode,r)).return=e,t):((t=a(t,n)).return=e,t)}function c(e,t,n,r){return null!==t&&t.elementType===n.type?((r=a(t,n.props)).ref=Eo(e,t,n),r.return=e,r):((r=Vs(n.type,n.key,n.props,null,e.mode,r)).ref=Eo(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Qs(n,e.mode,r)).return=e,t):((t=a(t,n.children||[])).return=e,t)}function d(e,t,n,r,o){return null===t||7!==t.tag?((t=Ws(n,e.mode,r,o)).return=e,t):((t=a(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Ks(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case S:return(n=Vs(t.type,t.key,t.props,null,e.mode,n)).ref=Eo(e,null,t),n.return=e,n;case E:return(t=Qs(t,e.mode,n)).return=e,t}if(So(t)||$(t))return(t=Ws(t,e.mode,n,null)).return=e,t;_o(e,t)}return null}function f(e,t,n,r){var a=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==a?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case S:return n.key===a?n.type===_?d(e,t,n.props.children,r,a):c(e,t,n,r):null;case E:return n.key===a?u(e,t,n,r):null}if(So(n)||$(n))return null!==a?null:d(e,t,n,r,null);_o(e,n)}return null}function m(e,t,n,r,a){if("string"==typeof r||"number"==typeof r)return s(t,e=e.get(n)||null,""+r,a);if("object"==typeof r&&null!==r){switch(r.$$typeof){case S:return e=e.get(null===r.key?n:r.key)||null,r.type===_?d(t,e,r.props.children,a,r.key):c(t,e,r,a);case E:return u(t,e=e.get(null===r.key?n:r.key)||null,r,a)}if(So(r)||$(r))return d(t,e=e.get(n)||null,r,a,null);_o(t,r)}return null}function g(a,i,l,s){for(var c=null,u=null,d=i,g=i=0,h=null;null!==d&&g<l.length;g++){d.index>g?(h=d,d=null):h=d.sibling;var b=f(a,d,l[g],s);if(null===b){null===d&&(d=h);break}e&&d&&null===b.alternate&&t(a,d),i=o(b,i,g),null===u?c=b:u.sibling=b,u=b,d=h}if(g===l.length)return n(a,d),c;if(null===d){for(;g<l.length;g++)null!==(d=p(a,l[g],s))&&(i=o(d,i,g),null===u?c=d:u.sibling=d,u=d);return c}for(d=r(a,d);g<l.length;g++)null!==(h=m(d,a,g,l[g],s))&&(e&&null!==h.alternate&&d.delete(null===h.key?g:h.key),i=o(h,i,g),null===u?c=h:u.sibling=h,u=h);return e&&d.forEach((function(e){return t(a,e)})),c}function h(a,l,s,c){var u=$(s);if("function"!=typeof u)throw Error(i(150));if(null==(s=u.call(s)))throw Error(i(151));for(var d=u=null,g=l,h=l=0,b=null,v=s.next();null!==g&&!v.done;h++,v=s.next()){g.index>h?(b=g,g=null):b=g.sibling;var y=f(a,g,v.value,c);if(null===y){null===g&&(g=b);break}e&&g&&null===y.alternate&&t(a,g),l=o(y,l,h),null===d?u=y:d.sibling=y,d=y,g=b}if(v.done)return n(a,g),u;if(null===g){for(;!v.done;h++,v=s.next())null!==(v=p(a,v.value,c))&&(l=o(v,l,h),null===d?u=v:d.sibling=v,d=v);return u}for(g=r(a,g);!v.done;h++,v=s.next())null!==(v=m(g,a,h,v.value,c))&&(e&&null!==v.alternate&&g.delete(null===v.key?h:v.key),l=o(v,l,h),null===d?u=v:d.sibling=v,d=v);return e&&g.forEach((function(e){return t(a,e)})),u}return function(e,r,o,s){var c="object"==typeof o&&null!==o&&o.type===_&&null===o.key;c&&(o=o.props.children);var u="object"==typeof o&&null!==o;if(u)switch(o.$$typeof){case S:e:{for(u=o.key,c=r;null!==c;){if(c.key===u){if(7===c.tag){if(o.type===_){n(e,c.sibling),(r=a(c,o.props.children)).return=e,e=r;break e}}else if(c.elementType===o.type){n(e,c.sibling),(r=a(c,o.props)).ref=Eo(e,c,o),r.return=e,e=r;break e}n(e,c);break}t(e,c),c=c.sibling}o.type===_?((r=Ws(o.props.children,e.mode,s,o.key)).return=e,e=r):((s=Vs(o.type,o.key,o.props,null,e.mode,s)).ref=Eo(e,r,o),s.return=e,e=s)}return l(e);case E:e:{for(c=o.key;null!==r;){if(r.key===c){if(4===r.tag&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),(r=a(r,o.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Qs(o,e.mode,s)).return=e,e=r}return l(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==r&&6===r.tag?(n(e,r.sibling),(r=a(r,o)).return=e,e=r):(n(e,r),(r=Ks(o,e.mode,s)).return=e,e=r),l(e);if(So(o))return g(e,r,o,s);if($(o))return h(e,r,o,s);if(u&&_o(e,o),void 0===o&&!c)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,V(e.type)||"Component"))}return n(e,r)}}var Co=xo(!0),To=xo(!1),Lo={},Ao=sa(Lo),Po=sa(Lo),No=sa(Lo);function Ro(e){if(e===Lo)throw Error(i(174));return e}function Oo(e,t){switch(ua(No,t),ua(Po,e),ua(Ao,Lo),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:fe(null,"");break;default:t=fe(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}ca(Ao),ua(Ao,t)}function Do(){ca(Ao),ca(Po),ca(No)}function Io(e){Ro(No.current);var t=Ro(Ao.current),n=fe(t,e.type);t!==n&&(ua(Po,e),ua(Ao,n))}function Mo(e){Po.current===e&&(ca(Ao),ca(Po))}var jo=sa(0);function Bo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Fo=null,zo=null,Uo=!1;function $o(e,t){var n=qs(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function Go(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function qo(e){if(Uo){var t=zo;if(t){var n=t;if(!Go(e,t)){if(!(t=Vr(n.nextSibling))||!Go(e,t))return e.flags=-1025&e.flags|2,Uo=!1,void(Fo=e);$o(Fo,n)}Fo=e,zo=Vr(t.firstChild)}else e.flags=-1025&e.flags|2,Uo=!1,Fo=e}}function Ho(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;Fo=e}function Zo(e){if(e!==Fo)return!1;if(!Uo)return Ho(e),Uo=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!Gr(t,e.memoizedProps))for(t=zo;t;)$o(e,t),t=Vr(t.nextSibling);if(Ho(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){zo=Vr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}zo=null}}else zo=Fo?Vr(e.stateNode.nextSibling):null;return!0}function Vo(){zo=Fo=null,Uo=!1}var Wo=[];function Yo(){for(var e=0;e<Wo.length;e++)Wo[e]._workInProgressVersionPrimary=null;Wo.length=0}var Ko=k.ReactCurrentDispatcher,Qo=k.ReactCurrentBatchConfig,Xo=0,Jo=null,ei=null,ti=null,ni=!1,ri=!1;function ai(){throw Error(i(321))}function oi(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!cr(e[n],t[n]))return!1;return!0}function ii(e,t,n,r,a,o){if(Xo=o,Jo=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Ko.current=null===e||null===e.memoizedState?Ri:Oi,e=n(r,a),ri){o=0;do{if(ri=!1,!(25>o))throw Error(i(301));o+=1,ti=ei=null,t.updateQueue=null,Ko.current=Di,e=n(r,a)}while(ri)}if(Ko.current=Ni,t=null!==ei&&null!==ei.next,Xo=0,ti=ei=Jo=null,ni=!1,t)throw Error(i(300));return e}function li(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ti?Jo.memoizedState=ti=e:ti=ti.next=e,ti}function si(){if(null===ei){var e=Jo.alternate;e=null!==e?e.memoizedState:null}else e=ei.next;var t=null===ti?Jo.memoizedState:ti.next;if(null!==t)ti=t,ei=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ei=e).memoizedState,baseState:ei.baseState,baseQueue:ei.baseQueue,queue:ei.queue,next:null},null===ti?Jo.memoizedState=ti=e:ti=ti.next=e}return ti}function ci(e,t){return"function"==typeof t?t(e):t}function ui(e){var t=si(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=ei,a=r.baseQueue,o=n.pending;if(null!==o){if(null!==a){var l=a.next;a.next=o.next,o.next=l}r.baseQueue=a=o,n.pending=null}if(null!==a){a=a.next,r=r.baseState;var s=l=o=null,c=a;do{var u=c.lane;if((Xo&u)===u)null!==s&&(s=s.next={lane:0,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null}),r=c.eagerReducer===e?c.eagerState:e(r,c.action);else{var d={lane:u,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null};null===s?(l=s=d,o=r):s=s.next=d,Jo.lanes|=u,Ul|=u}c=c.next}while(null!==c&&c!==a);null===s?o=r:s.next=l,cr(r,t.memoizedState)||(Mi=!0),t.memoizedState=r,t.baseState=o,t.baseQueue=s,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function di(e){var t=si(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(null!==a){n.pending=null;var l=a=a.next;do{o=e(o,l.action),l=l.next}while(l!==a);cr(o,t.memoizedState)||(Mi=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function pi(e,t,n){var r=t._getVersion;r=r(t._source);var a=t._workInProgressVersionPrimary;if(null!==a?e=a===r:(e=e.mutableReadLanes,(e=(Xo&e)===e)&&(t._workInProgressVersionPrimary=r,Wo.push(t))),e)return n(t._source);throw Wo.push(t),Error(i(350))}function fi(e,t,n,r){var a=Ol;if(null===a)throw Error(i(349));var o=t._getVersion,l=o(t._source),s=Ko.current,c=s.useState((function(){return pi(a,t,n)})),u=c[1],d=c[0];c=ti;var p=e.memoizedState,f=p.refs,m=f.getSnapshot,g=p.source;p=p.subscribe;var h=Jo;return e.memoizedState={refs:f,source:t,subscribe:r},s.useEffect((function(){f.getSnapshot=n,f.setSnapshot=u;var e=o(t._source);if(!cr(l,e)){e=n(t._source),cr(d,e)||(u(e),e=fs(h),a.mutableReadLanes|=e&a.pendingLanes),e=a.mutableReadLanes,a.entangledLanes|=e;for(var r=a.entanglements,i=e;0<i;){var s=31-Gt(i),c=1<<s;r[s]|=e,i&=~c}}}),[n,t,r]),s.useEffect((function(){return r(t._source,(function(){var e=f.getSnapshot,n=f.setSnapshot;try{n(e(t._source));var r=fs(h);a.mutableReadLanes|=r&a.pendingLanes}catch(o){n((function(){throw o}))}}))}),[t,r]),cr(m,n)&&cr(g,t)&&cr(p,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:d}).dispatch=u=Pi.bind(null,Jo,e),c.queue=e,c.baseQueue=null,d=pi(a,t,n),c.memoizedState=c.baseState=d),d}function mi(e,t,n){return fi(si(),e,t,n)}function gi(e){var t=li();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:e}).dispatch=Pi.bind(null,Jo,e),[t.memoizedState,e]}function hi(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=Jo.updateQueue)?(t={lastEffect:null},Jo.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function bi(e){return e={current:e},li().memoizedState=e}function vi(){return si().memoizedState}function yi(e,t,n,r){var a=li();Jo.flags|=e,a.memoizedState=hi(1|t,n,void 0,void 0===r?null:r)}function wi(e,t,n,r){var a=si();r=void 0===r?null:r;var o=void 0;if(null!==ei){var i=ei.memoizedState;if(o=i.destroy,null!==r&&oi(r,i.deps))return void hi(t,n,o,r)}Jo.flags|=e,a.memoizedState=hi(1|t,n,o,r)}function ki(e,t){return yi(516,4,e,t)}function Si(e,t){return wi(516,4,e,t)}function Ei(e,t){return wi(4,2,e,t)}function _i(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function xi(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,_i.bind(null,t,e),n)}function Ci(){}function Ti(e,t){var n=si();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Li(e,t){var n=si();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Ai(e,t){var n=Ga();Ha(98>n?98:n,(function(){e(!0)})),Ha(97<n?97:n,(function(){var n=Qo.transition;Qo.transition=1;try{e(!1),t()}finally{Qo.transition=n}}))}function Pi(e,t,n){var r=ps(),a=fs(e),o={lane:a,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?o.next=o:(o.next=i.next,i.next=o),t.pending=o,i=e.alternate,e===Jo||null!==i&&i===Jo)ri=ni=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var l=t.lastRenderedState,s=i(l,n);if(o.eagerReducer=i,o.eagerState=s,cr(s,l))return}catch(c){}ms(e,a,r)}}var Ni={readContext:oo,useCallback:ai,useContext:ai,useEffect:ai,useImperativeHandle:ai,useLayoutEffect:ai,useMemo:ai,useReducer:ai,useRef:ai,useState:ai,useDebugValue:ai,useDeferredValue:ai,useTransition:ai,useMutableSource:ai,useOpaqueIdentifier:ai,unstable_isNewReconciler:!1},Ri={readContext:oo,useCallback:function(e,t){return li().memoizedState=[e,void 0===t?null:t],e},useContext:oo,useEffect:ki,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,yi(4,2,_i.bind(null,t,e),n)},useLayoutEffect:function(e,t){return yi(4,2,e,t)},useMemo:function(e,t){var n=li();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=li();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Pi.bind(null,Jo,e),[r.memoizedState,e]},useRef:bi,useState:gi,useDebugValue:Ci,useDeferredValue:function(e){var t=gi(e),n=t[0],r=t[1];return ki((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=gi(!1),t=e[0];return bi(e=Ai.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var r=li();return r.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},fi(r,e,t,n)},useOpaqueIdentifier:function(){if(Uo){var e=!1,t=function(e){return{$$typeof:I,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Yr++).toString(36))),Error(i(355))})),n=gi(t)[1];return 0==(2&Jo.mode)&&(Jo.flags|=516,hi(5,(function(){n("r:"+(Yr++).toString(36))}),void 0,null)),t}return gi(t="r:"+(Yr++).toString(36)),t},unstable_isNewReconciler:!1},Oi={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:ui,useRef:vi,useState:function(){return ui(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=ui(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=ui(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return ui(ci)[0]},unstable_isNewReconciler:!1},Di={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:di,useRef:vi,useState:function(){return di(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=di(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=di(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ci)[0]},unstable_isNewReconciler:!1},Ii=k.ReactCurrentOwner,Mi=!1;function ji(e,t,n,r){t.child=null===e?To(t,null,n,r):Co(t,e.child,n,r)}function Bi(e,t,n,r,a){n=n.render;var o=t.ref;return ao(t,a),r=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,r,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,ol(e,t,a))}function Fi(e,t,n,r,a,o){if(null===e){var i=n.type;return"function"!=typeof i||Hs(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Vs(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,zi(e,t,i,r,a,o))}return i=e.child,0==(a&o)&&(a=i.memoizedProps,(n=null!==(n=n.compare)?n:dr)(a,r)&&e.ref===t.ref)?ol(e,t,o):(t.flags|=1,(e=Zs(i,r)).ref=t.ref,e.return=t,t.child=e)}function zi(e,t,n,r,a,o){if(null!==e&&dr(e.memoizedProps,r)&&e.ref===t.ref){if(Mi=!1,0==(o&a))return t.lanes=e.lanes,ol(e,t,o);0!=(16384&e.flags)&&(Mi=!0)}return Gi(e,t,n,r,o)}function Ui(e,t,n){var r=t.pendingProps,a=r.children,o=null!==e?e.memoizedState:null;if("hidden"===r.mode||"unstable-defer-without-hiding"===r.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},Ss(t,n);else{if(0==(1073741824&n))return e=null!==o?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},Ss(t,e),null;t.memoizedState={baseLanes:0},Ss(t,null!==o?o.baseLanes:n)}else null!==o?(r=o.baseLanes|n,t.memoizedState=null):r=n,Ss(t,r);return ji(e,t,a,n),t.child}function $i(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function Gi(e,t,n,r,a){var o=ha(n)?ma:pa.current;return o=ga(t,o),ao(t,a),n=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,n,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,ol(e,t,a))}function qi(e,t,n,r,a){if(ha(n)){var o=!0;wa(t)}else o=!1;if(ao(t,a),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),yo(t,n,r),ko(t,n,r,a),r=!0;else if(null===e){var i=t.stateNode,l=t.memoizedProps;i.props=l;var s=i.context,c=n.contextType;"object"==typeof c&&null!==c?c=oo(c):c=ga(t,c=ha(n)?ma:pa.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==r||s!==c)&&wo(t,i,r,c),io=!1;var p=t.memoizedState;i.state=p,fo(t,r,i,a),s=t.memoizedState,l!==r||p!==s||fa.current||io?("function"==typeof u&&(ho(t,n,u,r),s=t.memoizedState),(l=io||vo(t,n,l,r,p,s,c))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=r,t.memoizedState=s),i.props=r,i.state=s,i.context=c,r=l):("function"==typeof i.componentDidMount&&(t.flags|=4),r=!1)}else{i=t.stateNode,so(e,t),l=t.memoizedProps,c=t.type===t.elementType?l:Ka(t.type,l),i.props=c,d=t.pendingProps,p=i.context,"object"==typeof(s=n.contextType)&&null!==s?s=oo(s):s=ga(t,s=ha(n)?ma:pa.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==d||p!==s)&&wo(t,i,r,s),io=!1,p=t.memoizedState,i.state=p,fo(t,r,i,a);var m=t.memoizedState;l!==d||p!==m||fa.current||io?("function"==typeof f&&(ho(t,n,f,r),m=t.memoizedState),(c=io||vo(t,n,c,r,p,m,s))?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,m,s),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,m,s)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),t.memoizedProps=r,t.memoizedState=m),i.props=r,i.state=m,i.context=s,r=c):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),r=!1)}return Hi(e,t,n,r,o,a)}function Hi(e,t,n,r,a,o){$i(e,t);var i=0!=(64&t.flags);if(!r&&!i)return a&&ka(t,n,!1),ol(e,t,o);r=t.stateNode,Ii.current=t;var l=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=Co(t,e.child,null,o),t.child=Co(t,null,l,o)):ji(e,t,l,o),t.memoizedState=r.state,a&&ka(t,n,!0),t.child}function Zi(e){var t=e.stateNode;t.pendingContext?va(0,t.pendingContext,t.pendingContext!==t.context):t.context&&va(0,t.context,!1),Oo(e,t.containerInfo)}var Vi,Wi,Yi,Ki,Qi={dehydrated:null,retryLane:0};function Xi(e,t,n){var r,a=t.pendingProps,o=jo.current,i=!1;return(r=0!=(64&t.flags))||(r=(null===e||null!==e.memoizedState)&&0!=(2&o)),r?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===a.fallback||!0===a.unstable_avoidThisFallback||(o|=1),ua(jo,1&o),null===e?(void 0!==a.fallback&&qo(t),e=a.children,o=a.fallback,i?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,e):"number"==typeof a.unstable_expectedLoadTime?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,t.lanes=33554432,e):((n=Ys({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(a=tl(e,t,a.children,a.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=null===o?{baseLanes:n}:{baseLanes:o.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Qi,a):(n=el(e,t,a.children,n),t.memoizedState=null,n))}function Ji(e,t,n,r){var a=e.mode,o=e.child;return t={mode:"hidden",children:t},0==(2&a)&&null!==o?(o.childLanes=0,o.pendingProps=t):o=Ys(t,a,0,null),n=Ws(n,a,r,null),o.return=e,n.return=e,o.sibling=n,e.child=o,n}function el(e,t,n,r){var a=e.child;return e=a.sibling,n=Zs(a,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=r),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function tl(e,t,n,r,a){var o=t.mode,i=e.child;e=i.sibling;var l={mode:"hidden",children:n};return 0==(2&o)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=l,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=Zs(i,l),null!==e?r=Zs(e,r):(r=Ws(r,o,a,null)).flags|=2,r.return=t,n.return=t,n.sibling=r,t.child=n,r}function nl(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),ro(e.return,t)}function rl(e,t,n,r,a,o){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:a,lastEffect:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=a,i.lastEffect=o)}function al(e,t,n){var r=t.pendingProps,a=r.revealOrder,o=r.tail;if(ji(e,t,r.children,n),0!=(2&(r=jo.current)))r=1&r|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&nl(e,n);else if(19===e.tag)nl(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(ua(jo,r),0==(2&t.mode))t.memoizedState=null;else switch(a){case"forwards":for(n=t.child,a=null;null!==n;)null!==(e=n.alternate)&&null===Bo(e)&&(a=n),n=n.sibling;null===(n=a)?(a=t.child,t.child=null):(a=n.sibling,n.sibling=null),rl(t,!1,a,n,o,t.lastEffect);break;case"backwards":for(n=null,a=t.child,t.child=null;null!==a;){if(null!==(e=a.alternate)&&null===Bo(e)){t.child=a;break}e=a.sibling,a.sibling=n,n=a,a=e}rl(t,!0,n,null,o,t.lastEffect);break;case"together":rl(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function ol(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Ul|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Zs(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Zs(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function il(e,t){if(!Uo)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ll(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return ha(t.type)&&ba(),null;case 3:return Do(),ca(fa),ca(pa),Yo(),(r=t.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Zo(t)?t.flags|=4:r.hydrate||(t.flags|=256)),Wi(t),null;case 5:Mo(t);var o=Ro(No.current);if(n=t.type,null!==e&&null!=t.stateNode)Yi(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=128);else{if(!r){if(null===t.stateNode)throw Error(i(166));return null}if(e=Ro(Ao.current),Zo(t)){r=t.stateNode,n=t.type;var l=t.memoizedProps;switch(r[Qr]=t,r[Xr]=l,n){case"dialog":Ar("cancel",r),Ar("close",r);break;case"iframe":case"object":case"embed":Ar("load",r);break;case"video":case"audio":for(e=0;e<xr.length;e++)Ar(xr[e],r);break;case"source":Ar("error",r);break;case"img":case"image":case"link":Ar("error",r),Ar("load",r);break;case"details":Ar("toggle",r);break;case"input":ee(r,l),Ar("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!l.multiple},Ar("invalid",r);break;case"textarea":se(r,l),Ar("invalid",r)}for(var c in Ee(n,l),e=null,l)l.hasOwnProperty(c)&&(o=l[c],"children"===c?"string"==typeof o?r.textContent!==o&&(e=["children",o]):"number"==typeof o&&r.textContent!==""+o&&(e=["children",""+o]):s.hasOwnProperty(c)&&null!=o&&"onScroll"===c&&Ar("scroll",r));switch(n){case"input":K(r),re(r,l,!0);break;case"textarea":K(r),ue(r);break;case"select":case"option":break;default:"function"==typeof l.onClick&&(r.onclick=Fr)}r=e,t.updateQueue=r,null!==r&&(t.flags|=4)}else{switch(c=9===o.nodeType?o:o.ownerDocument,e===de.html&&(e=pe(n)),e===de.html?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[Qr]=t,e[Xr]=r,Vi(e,t,!1,!1),t.stateNode=e,c=_e(n,r),n){case"dialog":Ar("cancel",e),Ar("close",e),o=r;break;case"iframe":case"object":case"embed":Ar("load",e),o=r;break;case"video":case"audio":for(o=0;o<xr.length;o++)Ar(xr[o],e);o=r;break;case"source":Ar("error",e),o=r;break;case"img":case"image":case"link":Ar("error",e),Ar("load",e),o=r;break;case"details":Ar("toggle",e),o=r;break;case"input":ee(e,r),o=J(e,r),Ar("invalid",e);break;case"option":o=oe(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=a({},r,{value:void 0}),Ar("invalid",e);break;case"textarea":se(e,r),o=le(e,r),Ar("invalid",e);break;default:o=r}Ee(n,o);var u=o;for(l in u)if(u.hasOwnProperty(l)){var d=u[l];"style"===l?ke(e,d):"dangerouslySetInnerHTML"===l?null!=(d=d?d.__html:void 0)&&he(e,d):"children"===l?"string"==typeof d?("textarea"!==n||""!==d)&&be(e,d):"number"==typeof d&&be(e,""+d):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(s.hasOwnProperty(l)?null!=d&&"onScroll"===l&&Ar("scroll",e):null!=d&&w(e,l,d,c))}switch(n){case"input":K(e),re(e,r,!1);break;case"textarea":K(e),ue(e);break;case"option":null!=r.value&&e.setAttribute("value",""+W(r.value));break;case"select":e.multiple=!!r.multiple,null!=(l=r.value)?ie(e,!!r.multiple,l,!1):null!=r.defaultValue&&ie(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Fr)}$r(n,r)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Ki(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));n=Ro(No.current),Ro(Ao.current),Zo(t)?(r=t.stateNode,n=t.memoizedProps,r[Qr]=t,r.nodeValue!==n&&(t.flags|=4)):((r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[Qr]=t,t.stateNode=r)}return null;case 13:return ca(jo),r=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(r=null!==r,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Zo(t):n=null!==e.memoizedState,r&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&jo.current)?0===Bl&&(Bl=3):(0!==Bl&&3!==Bl||(Bl=4),null===Ol||0==(134217727&Ul)&&0==(134217727&$l)||vs(Ol,Il))),(r||n)&&(t.flags|=4),null);case 4:return Do(),Wi(t),null===e&&Nr(t.stateNode.containerInfo),null;case 10:return no(t),null;case 19:if(ca(jo),null===(r=t.memoizedState))return null;if(l=0!=(64&t.flags),null===(c=r.rendering))if(l)il(r,!1);else{if(0!==Bl||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(c=Bo(e))){for(t.flags|=64,il(r,!1),null!==(l=c.updateQueue)&&(t.updateQueue=l,t.flags|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=n,n=t.child;null!==n;)e=r,(l=n).flags&=2,l.nextEffect=null,l.firstEffect=null,l.lastEffect=null,null===(c=l.alternate)?(l.childLanes=0,l.lanes=e,l.child=null,l.memoizedProps=null,l.memoizedState=null,l.updateQueue=null,l.dependencies=null,l.stateNode=null):(l.childLanes=c.childLanes,l.lanes=c.lanes,l.child=c.child,l.memoizedProps=c.memoizedProps,l.memoizedState=c.memoizedState,l.updateQueue=c.updateQueue,l.type=c.type,e=c.dependencies,l.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return ua(jo,1&jo.current|2),t.child}e=e.sibling}null!==r.tail&&$a()>Zl&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432)}else{if(!l)if(null!==(e=Bo(c))){if(t.flags|=64,l=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),il(r,!0),null===r.tail&&"hidden"===r.tailMode&&!c.alternate&&!Uo)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*$a()-r.renderingStartTime>Zl&&1073741824!==n&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432);r.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=r.last)?n.sibling=c:t.child=c,r.last=c)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=$a(),n.sibling=null,t=jo.current,ua(jo,l?1&t|2:1&t),n):null;case 23:case 24:return Es(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function sl(e){switch(e.tag){case 1:ha(e.type)&&ba();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Do(),ca(fa),ca(pa),Yo(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Mo(e),null;case 13:return ca(jo),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return ca(jo),null;case 4:return Do(),null;case 10:return no(e),null;case 23:case 24:return Es(),null;default:return null}}function cl(e,t){try{var n="",r=t;do{n+=Z(r),r=r.return}while(r);var a=n}catch(o){a="\nError generating stack: "+o.message+"\n"+o.stack}return{value:e,source:t,stack:a}}function ul(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Vi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Wi=function(){},Yi=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,Ro(Ao.current);var i,l=null;switch(n){case"input":o=J(e,o),r=J(e,r),l=[];break;case"option":o=oe(e,o),r=oe(e,r),l=[];break;case"select":o=a({},o,{value:void 0}),r=a({},r,{value:void 0}),l=[];break;case"textarea":o=le(e,o),r=le(e,r),l=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Fr)}for(d in Ee(n,r),n=null,o)if(!r.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(i in c)c.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(s.hasOwnProperty(d)?l||(l=[]):(l=l||[]).push(d,null));for(d in r){var u=r[d];if(c=null!=o?o[d]:void 0,r.hasOwnProperty(d)&&u!==c&&(null!=u||null!=c))if("style"===d)if(c){for(i in c)!c.hasOwnProperty(i)||u&&u.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in u)u.hasOwnProperty(i)&&c[i]!==u[i]&&(n||(n={}),n[i]=u[i])}else n||(l||(l=[]),l.push(d,n)),n=u;else"dangerouslySetInnerHTML"===d?(u=u?u.__html:void 0,c=c?c.__html:void 0,null!=u&&c!==u&&(l=l||[]).push(d,u)):"children"===d?"string"!=typeof u&&"number"!=typeof u||(l=l||[]).push(d,""+u):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(s.hasOwnProperty(d)?(null!=u&&"onScroll"===d&&Ar("scroll",e),l||c===u||(l=[])):"object"==typeof u&&null!==u&&u.$$typeof===I?u.toString():(l=l||[]).push(d,u))}n&&(l=l||[]).push("style",n);var d=l;(t.updateQueue=d)&&(t.flags|=4)}},Ki=function(e,t,n,r){n!==r&&(t.flags|=4)};var dl="function"==typeof WeakMap?WeakMap:Map;function pl(e,t,n){(n=co(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Kl||(Kl=!0,Ql=r),ul(0,t)},n}function fl(e,t,n){(n=co(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var a=t.value;n.payload=function(){return ul(0,t),r(a)}}var o=e.stateNode;return null!==o&&"function"==typeof o.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Xl?Xl=new Set([this]):Xl.add(this),ul(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var ml="function"==typeof WeakSet?WeakSet:Set;function gl(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){zs(e,n)}else t.current=null}function hl(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ka(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Zr(t.stateNode.containerInfo))}throw Error(i(163))}function bl(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var a=e;r=a.next,0!=(4&(a=a.tag))&&0!=(1&a)&&(js(n,e),Ms(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ka(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&mo(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}mo(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&$r(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&kt(n)))))}throw Error(i(163))}function vl(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var a=n.memoizedProps.style;a=null!=a&&a.hasOwnProperty("display")?a.display:null,r.style.display=we("display",a)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function yl(e,t){if(Ea&&"function"==typeof Ea.onCommitFiberUnmount)try{Ea.onCommitFiberUnmount(Sa,t)}catch(o){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,a=r.destroy;if(r=r.tag,void 0!==a)if(0!=(4&r))js(t,n);else{r=t;try{a()}catch(o){zs(r,o)}}n=n.next}while(n!==e)}break;case 1:if(gl(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(o){zs(t,o)}break;case 5:gl(t);break;case 4:xl(e,t)}}function wl(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function kl(e){return 5===e.tag||3===e.tag||4===e.tag}function Sl(e){e:{for(var t=e.return;null!==t;){if(kl(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(i(161))}16&n.flags&&(be(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||kl(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?El(e,n,t):_l(e,n,t)}function El(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Fr));else if(4!==r&&null!==(e=e.child))for(El(e,t,n),e=e.sibling;null!==e;)El(e,t,n),e=e.sibling}function _l(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(_l(e,t,n),e=e.sibling;null!==e;)_l(e,t,n),e=e.sibling}function xl(e,t){for(var n,r,a=t,o=!1;;){if(!o){o=a.return;e:for(;;){if(null===o)throw Error(i(160));switch(n=o.stateNode,o.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}o=o.return}o=!0}if(5===a.tag||6===a.tag){e:for(var l=e,s=a,c=s;;)if(yl(l,c),null!==c.child&&4!==c.tag)c.child.return=c,c=c.child;else{if(c===s)break e;for(;null===c.sibling;){if(null===c.return||c.return===s)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}r?(l=n,s=a.stateNode,8===l.nodeType?l.parentNode.removeChild(s):l.removeChild(s)):n.removeChild(a.stateNode)}else if(4===a.tag){if(null!==a.child){n=a.stateNode.containerInfo,r=!0,a.child.return=a,a=a.child;continue}}else if(yl(e,a),null!==a.child){a.child.return=a,a=a.child;continue}if(a===t)break;for(;null===a.sibling;){if(null===a.return||a.return===t)return;4===(a=a.return).tag&&(o=!1)}a.sibling.return=a.return,a=a.sibling}}function Cl(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var a=null!==e?e.memoizedProps:r;e=t.type;var o=t.updateQueue;if(t.updateQueue=null,null!==o){for(n[Xr]=r,"input"===e&&"radio"===r.type&&null!=r.name&&te(n,r),_e(e,a),t=_e(e,r),a=0;a<o.length;a+=2){var l=o[a],s=o[a+1];"style"===l?ke(n,s):"dangerouslySetInnerHTML"===l?he(n,s):"children"===l?be(n,s):w(n,l,s,t)}switch(e){case"input":ne(n,r);break;case"textarea":ce(n,r);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(o=r.value)?ie(n,!!r.multiple,o,!1):e!==!!r.multiple&&(null!=r.defaultValue?ie(n,!!r.multiple,r.defaultValue,!0):ie(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,kt(n.containerInfo)));case 13:return null!==t.memoizedState&&(Hl=$a(),vl(t.child,!0)),void Tl(t);case 19:return void Tl(t);case 23:case 24:return void vl(t,null!==t.memoizedState)}throw Error(i(163))}function Tl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new ml),t.forEach((function(t){var r=$s.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function Ll(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var Al=Math.ceil,Pl=k.ReactCurrentDispatcher,Nl=k.ReactCurrentOwner,Rl=0,Ol=null,Dl=null,Il=0,Ml=0,jl=sa(0),Bl=0,Fl=null,zl=0,Ul=0,$l=0,Gl=0,ql=null,Hl=0,Zl=1/0;function Vl(){Zl=$a()+500}var Wl,Yl=null,Kl=!1,Ql=null,Xl=null,Jl=!1,es=null,ts=90,ns=[],rs=[],as=null,os=0,is=null,ls=-1,ss=0,cs=0,us=null,ds=!1;function ps(){return 0!=(48&Rl)?$a():-1!==ls?ls:ls=$a()}function fs(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===Ga()?1:2;if(0===ss&&(ss=zl),0!==Ya.transition){0!==cs&&(cs=null!==ql?ql.pendingLanes:0),e=ss;var t=4186112&~cs;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=Ga(),0!=(4&Rl)&&98===e?e=Ft(12,ss):e=Ft(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ss),e}function ms(e,t,n){if(50<os)throw os=0,is=null,Error(i(185));if(null===(e=gs(e,t)))return null;$t(e,t,n),e===Ol&&($l|=t,4===Bl&&vs(e,Il));var r=Ga();1===t?0!=(8&Rl)&&0==(48&Rl)?ys(e):(hs(e,n),0===Rl&&(Vl(),Va())):(0==(4&Rl)||98!==r&&99!==r||(null===as?as=new Set([e]):as.add(e)),hs(e,n)),ql=e}function gs(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function hs(e,t){for(var n=e.callbackNode,r=e.suspendedLanes,a=e.pingedLanes,o=e.expirationTimes,l=e.pendingLanes;0<l;){var s=31-Gt(l),c=1<<s,u=o[s];if(-1===u){if(0==(c&r)||0!=(c&a)){u=t,Mt(c);var d=It;o[s]=10<=d?u+250:6<=d?u+5e3:-1}}else u<=t&&(e.expiredLanes|=c);l&=~c}if(r=jt(e,e===Ol?Il:0),t=It,0===r)null!==n&&(n!==Ma&&Ca(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Ma&&Ca(n)}15===t?(n=ys.bind(null,e),null===Ba?(Ba=[n],Fa=xa(Na,Wa)):Ba.push(n),n=Ma):14===t?n=Za(99,ys.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Za(n,bs.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function bs(e){if(ls=-1,cs=ss=0,0!=(48&Rl))throw Error(i(327));var t=e.callbackNode;if(Is()&&e.callbackNode!==t)return null;var n=jt(e,e===Ol?Il:0);if(0===n)return null;var r=n,a=Rl;Rl|=16;var o=Cs();for(Ol===e&&Il===r||(Vl(),_s(e,r));;)try{As();break}catch(s){xs(e,s)}if(to(),Pl.current=o,Rl=a,null!==Dl?r=0:(Ol=null,Il=0,r=Bl),0!=(zl&$l))_s(e,0);else if(0!==r){if(2===r&&(Rl|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(n=Bt(e))&&(r=Ts(e,n))),1===r)throw t=Fl,_s(e,0),vs(e,n),hs(e,$a()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,r){case 0:case 1:throw Error(i(345));case 2:case 5:Rs(e);break;case 3:if(vs(e,n),(62914560&n)===n&&10<(r=Hl+500-$a())){if(0!==jt(e,0))break;if(((a=e.suspendedLanes)&n)!==n){ps(),e.pingedLanes|=e.suspendedLanes&a;break}e.timeoutHandle=qr(Rs.bind(null,e),r);break}Rs(e);break;case 4:if(vs(e,n),(4186112&n)===n)break;for(r=e.eventTimes,a=-1;0<n;){var l=31-Gt(n);o=1<<l,(l=r[l])>a&&(a=l),n&=~o}if(n=a,10<(n=(120>(n=$a()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Al(n/1960))-n)){e.timeoutHandle=qr(Rs.bind(null,e),n);break}Rs(e);break;default:throw Error(i(329))}}return hs(e,$a()),e.callbackNode===t?bs.bind(null,e):null}function vs(e,t){for(t&=~Gl,t&=~$l,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-Gt(t),r=1<<n;e[n]=-1,t&=~r}}function ys(e){if(0!=(48&Rl))throw Error(i(327));if(Is(),e===Ol&&0!=(e.expiredLanes&Il)){var t=Il,n=Ts(e,t);0!=(zl&$l)&&(n=Ts(e,t=jt(e,t)))}else n=Ts(e,t=jt(e,0));if(0!==e.tag&&2===n&&(Rl|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(t=Bt(e))&&(n=Ts(e,t))),1===n)throw n=Fl,_s(e,0),vs(e,t),hs(e,$a()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,Rs(e),hs(e,$a()),null}function ws(e,t){var n=Rl;Rl|=1;try{return e(t)}finally{0===(Rl=n)&&(Vl(),Va())}}function ks(e,t){var n=Rl;Rl&=-2,Rl|=8;try{return e(t)}finally{0===(Rl=n)&&(Vl(),Va())}}function Ss(e,t){ua(jl,Ml),Ml|=t,zl|=t}function Es(){Ml=jl.current,ca(jl)}function _s(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,Hr(n)),null!==Dl)for(n=Dl.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&ba();break;case 3:Do(),ca(fa),ca(pa),Yo();break;case 5:Mo(r);break;case 4:Do();break;case 13:case 19:ca(jo);break;case 10:no(r);break;case 23:case 24:Es()}n=n.return}Ol=e,Dl=Zs(e.current,null),Il=Ml=zl=t,Bl=0,Fl=null,Gl=$l=Ul=0}function xs(e,t){for(;;){var n=Dl;try{if(to(),Ko.current=Ni,ni){for(var r=Jo.memoizedState;null!==r;){var a=r.queue;null!==a&&(a.pending=null),r=r.next}ni=!1}if(Xo=0,ti=ei=Jo=null,ri=!1,Nl.current=null,null===n||null===n.return){Bl=1,Fl=t,Dl=null;break}e:{var o=e,i=n.return,l=n,s=t;if(t=Il,l.flags|=2048,l.firstEffect=l.lastEffect=null,null!==s&&"object"==typeof s&&"function"==typeof s.then){var c=s;if(0==(2&l.mode)){var u=l.alternate;u?(l.updateQueue=u.updateQueue,l.memoizedState=u.memoizedState,l.lanes=u.lanes):(l.updateQueue=null,l.memoizedState=null)}var d=0!=(1&jo.current),p=i;do{var f;if(f=13===p.tag){var m=p.memoizedState;if(null!==m)f=null!==m.dehydrated;else{var g=p.memoizedProps;f=void 0!==g.fallback&&(!0!==g.unstable_avoidThisFallback||!d)}}if(f){var h=p.updateQueue;if(null===h){var b=new Set;b.add(c),p.updateQueue=b}else h.add(c);if(0==(2&p.mode)){if(p.flags|=64,l.flags|=16384,l.flags&=-2981,1===l.tag)if(null===l.alternate)l.tag=17;else{var v=co(-1,1);v.tag=2,uo(l,v)}l.lanes|=1;break e}s=void 0,l=t;var y=o.pingCache;if(null===y?(y=o.pingCache=new dl,s=new Set,y.set(c,s)):void 0===(s=y.get(c))&&(s=new Set,y.set(c,s)),!s.has(l)){s.add(l);var w=Us.bind(null,o,c,l);c.then(w,w)}p.flags|=4096,p.lanes=t;break e}p=p.return}while(null!==p);s=Error((V(l.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Bl&&(Bl=2),s=cl(s,l),p=i;do{switch(p.tag){case 3:o=s,p.flags|=4096,t&=-t,p.lanes|=t,po(p,pl(0,o,t));break e;case 1:o=s;var k=p.type,S=p.stateNode;if(0==(64&p.flags)&&("function"==typeof k.getDerivedStateFromError||null!==S&&"function"==typeof S.componentDidCatch&&(null===Xl||!Xl.has(S)))){p.flags|=4096,t&=-t,p.lanes|=t,po(p,fl(p,o,t));break e}}p=p.return}while(null!==p)}Ns(n)}catch(E){t=E,Dl===n&&null!==n&&(Dl=n=n.return);continue}break}}function Cs(){var e=Pl.current;return Pl.current=Ni,null===e?Ni:e}function Ts(e,t){var n=Rl;Rl|=16;var r=Cs();for(Ol===e&&Il===t||_s(e,t);;)try{Ls();break}catch(a){xs(e,a)}if(to(),Rl=n,Pl.current=r,null!==Dl)throw Error(i(261));return Ol=null,Il=0,Bl}function Ls(){for(;null!==Dl;)Ps(Dl)}function As(){for(;null!==Dl&&!Ta();)Ps(Dl)}function Ps(e){var t=Wl(e.alternate,e,Ml);e.memoizedProps=e.pendingProps,null===t?Ns(e):Dl=t,Nl.current=null}function Ns(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ll(n,t,Ml)))return void(Dl=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&Ml)||0==(4&n.mode)){for(var r=0,a=n.child;null!==a;)r|=a.lanes|a.childLanes,a=a.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=sl(t)))return n.flags&=2047,void(Dl=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Dl=t);Dl=t=e}while(null!==t);0===Bl&&(Bl=5)}function Rs(e){var t=Ga();return Ha(99,Os.bind(null,e,t)),null}function Os(e,t){do{Is()}while(null!==es);if(0!=(48&Rl))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var r=n.lanes|n.childLanes,a=r,o=e.pendingLanes&~a;e.pendingLanes=a,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=a,e.mutableReadLanes&=a,e.entangledLanes&=a,a=e.entanglements;for(var l=e.eventTimes,s=e.expirationTimes;0<o;){var c=31-Gt(o),u=1<<c;a[c]=0,l[c]=-1,s[c]=-1,o&=~u}if(null!==as&&0==(24&r)&&as.has(e)&&as.delete(e),e===Ol&&(Dl=Ol=null,Il=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,r=n.firstEffect):r=n:r=n.firstEffect,null!==r){if(a=Rl,Rl|=32,Nl.current=null,zr=Wt,hr(l=gr())){if("selectionStart"in l)s={start:l.selectionStart,end:l.selectionEnd};else e:if(s=(s=l.ownerDocument)&&s.defaultView||window,(u=s.getSelection&&s.getSelection())&&0!==u.rangeCount){s=u.anchorNode,o=u.anchorOffset,c=u.focusNode,u=u.focusOffset;try{s.nodeType,c.nodeType}catch(C){s=null;break e}var d=0,p=-1,f=-1,m=0,g=0,h=l,b=null;t:for(;;){for(var v;h!==s||0!==o&&3!==h.nodeType||(p=d+o),h!==c||0!==u&&3!==h.nodeType||(f=d+u),3===h.nodeType&&(d+=h.nodeValue.length),null!==(v=h.firstChild);)b=h,h=v;for(;;){if(h===l)break t;if(b===s&&++m===o&&(p=d),b===c&&++g===u&&(f=d),null!==(v=h.nextSibling))break;b=(h=b).parentNode}h=v}s=-1===p||-1===f?null:{start:p,end:f}}else s=null;s=s||{start:0,end:0}}else s=null;Ur={focusedElem:l,selectionRange:s},Wt=!1,us=null,ds=!1,Yl=r;do{try{Ds()}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);us=null,Yl=r;do{try{for(l=e;null!==Yl;){var y=Yl.flags;if(16&y&&be(Yl.stateNode,""),128&y){var w=Yl.alternate;if(null!==w){var k=w.ref;null!==k&&("function"==typeof k?k(null):k.current=null)}}switch(1038&y){case 2:Sl(Yl),Yl.flags&=-3;break;case 6:Sl(Yl),Yl.flags&=-3,Cl(Yl.alternate,Yl);break;case 1024:Yl.flags&=-1025;break;case 1028:Yl.flags&=-1025,Cl(Yl.alternate,Yl);break;case 4:Cl(Yl.alternate,Yl);break;case 8:xl(l,s=Yl);var S=s.alternate;wl(s),null!==S&&wl(S)}Yl=Yl.nextEffect}}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);if(k=Ur,w=gr(),y=k.focusedElem,l=k.selectionRange,w!==y&&y&&y.ownerDocument&&mr(y.ownerDocument.documentElement,y)){null!==l&&hr(y)&&(w=l.start,void 0===(k=l.end)&&(k=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(k,y.value.length)):(k=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(k=k.getSelection(),s=y.textContent.length,S=Math.min(l.start,s),l=void 0===l.end?S:Math.min(l.end,s),!k.extend&&S>l&&(s=l,l=S,S=s),s=fr(y,S),o=fr(y,l),s&&o&&(1!==k.rangeCount||k.anchorNode!==s.node||k.anchorOffset!==s.offset||k.focusNode!==o.node||k.focusOffset!==o.offset)&&((w=w.createRange()).setStart(s.node,s.offset),k.removeAllRanges(),S>l?(k.addRange(w),k.extend(o.node,o.offset)):(w.setEnd(o.node,o.offset),k.addRange(w))))),w=[];for(k=y;k=k.parentNode;)1===k.nodeType&&w.push({element:k,left:k.scrollLeft,top:k.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(k=w[y]).element.scrollLeft=k.left,k.element.scrollTop=k.top}Wt=!!zr,Ur=zr=null,e.current=n,Yl=r;do{try{for(y=e;null!==Yl;){var E=Yl.flags;if(36&E&&bl(y,Yl.alternate,Yl),128&E){w=void 0;var _=Yl.ref;if(null!==_){var x=Yl.stateNode;Yl.tag,w=x,"function"==typeof _?_(w):_.current=w}}Yl=Yl.nextEffect}}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);Yl=null,ja(),Rl=a}else e.current=n;if(Jl)Jl=!1,es=e,ts=t;else for(Yl=r;null!==Yl;)t=Yl.nextEffect,Yl.nextEffect=null,8&Yl.flags&&((E=Yl).sibling=null,E.stateNode=null),Yl=t;if(0===(r=e.pendingLanes)&&(Xl=null),1===r?e===is?os++:(os=0,is=e):os=0,n=n.stateNode,Ea&&"function"==typeof Ea.onCommitFiberRoot)try{Ea.onCommitFiberRoot(Sa,n,void 0,64==(64&n.current.flags))}catch(C){}if(hs(e,$a()),Kl)throw Kl=!1,e=Ql,Ql=null,e;return 0!=(8&Rl)||Va(),null}function Ds(){for(;null!==Yl;){var e=Yl.alternate;ds||null===us||(0!=(8&Yl.flags)?Je(Yl,us)&&(ds=!0):13===Yl.tag&&Ll(e,Yl)&&Je(Yl,us)&&(ds=!0));var t=Yl.flags;0!=(256&t)&&hl(e,Yl),0==(512&t)||Jl||(Jl=!0,Za(97,(function(){return Is(),null}))),Yl=Yl.nextEffect}}function Is(){if(90!==ts){var e=97<ts?97:ts;return ts=90,Ha(e,Bs)}return!1}function Ms(e,t){ns.push(t,e),Jl||(Jl=!0,Za(97,(function(){return Is(),null})))}function js(e,t){rs.push(t,e),Jl||(Jl=!0,Za(97,(function(){return Is(),null})))}function Bs(){if(null===es)return!1;var e=es;if(es=null,0!=(48&Rl))throw Error(i(331));var t=Rl;Rl|=32;var n=rs;rs=[];for(var r=0;r<n.length;r+=2){var a=n[r],o=n[r+1],l=a.destroy;if(a.destroy=void 0,"function"==typeof l)try{l()}catch(c){if(null===o)throw Error(i(330));zs(o,c)}}for(n=ns,ns=[],r=0;r<n.length;r+=2){a=n[r],o=n[r+1];try{var s=a.create;a.destroy=s()}catch(c){if(null===o)throw Error(i(330));zs(o,c)}}for(s=e.current.firstEffect;null!==s;)e=s.nextEffect,s.nextEffect=null,8&s.flags&&(s.sibling=null,s.stateNode=null),s=e;return Rl=t,Va(),!0}function Fs(e,t,n){uo(e,t=pl(0,t=cl(n,t),1)),t=ps(),null!==(e=gs(e,1))&&($t(e,1,t),hs(e,t))}function zs(e,t){if(3===e.tag)Fs(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Fs(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Xl||!Xl.has(r))){var a=fl(n,e=cl(t,e),1);if(uo(n,a),a=ps(),null!==(n=gs(n,1)))$t(n,1,a),hs(n,a);else if("function"==typeof r.componentDidCatch&&(null===Xl||!Xl.has(r)))try{r.componentDidCatch(t,e)}catch(o){}break}}n=n.return}}function Us(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=ps(),e.pingedLanes|=e.suspendedLanes&n,Ol===e&&(Il&n)===n&&(4===Bl||3===Bl&&(62914560&Il)===Il&&500>$a()-Hl?_s(e,0):Gl|=n),hs(e,t)}function $s(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===Ga()?1:2:(0===ss&&(ss=zl),0===(t=zt(62914560&~ss))&&(t=4194304))),n=ps(),null!==(e=gs(e,t))&&($t(e,t,n),hs(e,n))}function Gs(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function qs(e,t,n,r){return new Gs(e,t,n,r)}function Hs(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Zs(e,t){var n=e.alternate;return null===n?((n=qs(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Vs(e,t,n,r,a,o){var l=2;if(r=e,"function"==typeof e)Hs(e)&&(l=1);else if("string"==typeof e)l=5;else e:switch(e){case _:return Ws(n.children,a,o,t);case M:l=8,a|=16;break;case x:l=8,a|=1;break;case C:return(e=qs(12,n,t,8|a)).elementType=C,e.type=C,e.lanes=o,e;case P:return(e=qs(13,n,t,a)).type=P,e.elementType=P,e.lanes=o,e;case N:return(e=qs(19,n,t,a)).elementType=N,e.lanes=o,e;case j:return Ys(n,a,o,t);case B:return(e=qs(24,n,t,a)).elementType=B,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:l=10;break e;case L:l=9;break e;case A:l=11;break e;case R:l=14;break e;case O:l=16,r=null;break e;case D:l=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=qs(l,n,t,a)).elementType=e,t.type=r,t.lanes=o,t}function Ws(e,t,n,r){return(e=qs(7,e,r,t)).lanes=n,e}function Ys(e,t,n,r){return(e=qs(23,e,r,t)).elementType=j,e.lanes=n,e}function Ks(e,t,n){return(e=qs(6,e,null,t)).lanes=n,e}function Qs(e,t,n){return(t=qs(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Xs(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Ut(0),this.expirationTimes=Ut(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ut(0),this.mutableSourceEagerHydrationData=null}function Js(e,t,n,r){var a=t.current,o=ps(),l=fs(a);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var s=n;do{switch(s.tag){case 3:s=s.stateNode.context;break t;case 1:if(ha(s.type)){s=s.stateNode.__reactInternalMemoizedMergedChildContext;break t}}s=s.return}while(null!==s);throw Error(i(171))}if(1===n.tag){var c=n.type;if(ha(c)){n=ya(n,c,s);break e}}n=s}else n=da;return null===t.context?t.context=n:t.pendingContext=n,(t=co(o,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),uo(a,t),ms(a,l,o),l}function ec(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function tc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function nc(e,t){tc(e,t),(e=e.alternate)&&tc(e,t)}function rc(e,t,n){var r=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Xs(e,t,null!=n&&!0===n.hydrate),t=qs(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,lo(t),e[Jr]=n.current,Nr(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var a=(t=r[e])._getVersion;a=a(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,a]:n.mutableSourceEagerHydrationData.push(t,a)}this._internalRoot=n}function ac(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function oc(e,t,n,r,a){var o=n._reactRootContainer;if(o){var i=o._internalRoot;if("function"==typeof a){var l=a;a=function(){var e=ec(i);l.call(e)}}Js(t,i,e,a)}else{if(o=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new rc(e,0,t?{hydrate:!0}:void 0)}(n,r),i=o._internalRoot,"function"==typeof a){var s=a;a=function(){var e=ec(i);s.call(e)}}ks((function(){Js(t,i,e,a)}))}return ec(i)}function ic(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!ac(t))throw Error(i(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:E,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)}Wl=function(e,t,n){var r=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||fa.current)Mi=!0;else{if(0==(n&r)){switch(Mi=!1,t.tag){case 3:Zi(t),Vo();break;case 5:Io(t);break;case 1:ha(t.type)&&wa(t);break;case 4:Oo(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value;var a=t.type._context;ua(Qa,a._currentValue),a._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Xi(e,t,n):(ua(jo,1&jo.current),null!==(t=ol(e,t,n))?t.sibling:null);ua(jo,1&jo.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(64&e.flags)){if(r)return al(e,t,n);t.flags|=64}if(null!==(a=t.memoizedState)&&(a.rendering=null,a.tail=null,a.lastEffect=null),ua(jo,jo.current),r)break;return null;case 23:case 24:return t.lanes=0,Ui(e,t,n)}return ol(e,t,n)}Mi=0!=(16384&e.flags)}else Mi=!1;switch(t.lanes=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=ga(t,pa.current),ao(t,n),a=ii(null,t,r,e,a,n),t.flags|=1,"object"==typeof a&&null!==a&&"function"==typeof a.render&&void 0===a.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,ha(r)){var o=!0;wa(t)}else o=!1;t.memoizedState=null!==a.state&&void 0!==a.state?a.state:null,lo(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&ho(t,r,l,e),a.updater=bo,t.stateNode=a,a._reactInternals=t,ko(t,r,e,n),t=Hi(null,t,r,!0,o,n)}else t.tag=0,ji(null,t,a,n),t=t.child;return t;case 16:a=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=(o=a._init)(a._payload),t.type=a,o=t.tag=function(e){if("function"==typeof e)return Hs(e)?1:0;if(null!=e){if((e=e.$$typeof)===A)return 11;if(e===R)return 14}return 2}(a),e=Ka(a,e),o){case 0:t=Gi(null,t,a,e,n);break e;case 1:t=qi(null,t,a,e,n);break e;case 11:t=Bi(null,t,a,e,n);break e;case 14:t=Fi(null,t,a,Ka(a.type,e),r,n);break e}throw Error(i(306,a,""))}return t;case 0:return r=t.type,a=t.pendingProps,Gi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 1:return r=t.type,a=t.pendingProps,qi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 3:if(Zi(t),r=t.updateQueue,null===e||null===r)throw Error(i(282));if(r=t.pendingProps,a=null!==(a=t.memoizedState)?a.element:null,so(e,t),fo(t,r,null,n),(r=t.memoizedState.element)===a)Vo(),t=ol(e,t,n);else{if((o=(a=t.stateNode).hydrate)&&(zo=Vr(t.stateNode.containerInfo.firstChild),Fo=t,o=Uo=!0),o){if(null!=(e=a.mutableSourceEagerHydrationData))for(a=0;a<e.length;a+=2)(o=e[a])._workInProgressVersionPrimary=e[a+1],Wo.push(o);for(n=To(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else ji(e,t,r,n),Vo();t=t.child}return t;case 5:return Io(t),null===e&&qo(t),r=t.type,a=t.pendingProps,o=null!==e?e.memoizedProps:null,l=a.children,Gr(r,a)?l=null:null!==o&&Gr(r,o)&&(t.flags|=16),$i(e,t),ji(e,t,l,n),t.child;case 6:return null===e&&qo(t),null;case 13:return Xi(e,t,n);case 4:return Oo(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Co(t,null,r,n):ji(e,t,r,n),t.child;case 11:return r=t.type,a=t.pendingProps,Bi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 7:return ji(e,t,t.pendingProps,n),t.child;case 8:case 12:return ji(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,a=t.pendingProps,l=t.memoizedProps,o=a.value;var s=t.type._context;if(ua(Qa,s._currentValue),s._currentValue=o,null!==l)if(s=l.value,0===(o=cr(s,o)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(s,o):1073741823))){if(l.children===a.children&&!fa.current){t=ol(e,t,n);break e}}else for(null!==(s=t.child)&&(s.return=t);null!==s;){var c=s.dependencies;if(null!==c){l=s.child;for(var u=c.firstContext;null!==u;){if(u.context===r&&0!=(u.observedBits&o)){1===s.tag&&((u=co(-1,n&-n)).tag=2,uo(s,u)),s.lanes|=n,null!==(u=s.alternate)&&(u.lanes|=n),ro(s.return,n),c.lanes|=n;break}u=u.next}}else l=10===s.tag&&s.type===t.type?null:s.child;if(null!==l)l.return=s;else for(l=s;null!==l;){if(l===t){l=null;break}if(null!==(s=l.sibling)){s.return=l.return,l=s;break}l=l.return}s=l}ji(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,r=(o=t.pendingProps).children,ao(t,n),r=r(a=oo(a,o.unstable_observedBits)),t.flags|=1,ji(e,t,r,n),t.child;case 14:return o=Ka(a=t.type,t.pendingProps),Fi(e,t,a,o=Ka(a.type,o),r,n);case 15:return zi(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,a=t.pendingProps,a=t.elementType===r?a:Ka(r,a),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,ha(r)?(e=!0,wa(t)):e=!1,ao(t,n),yo(t,r,a),ko(t,r,a,n),Hi(null,t,r,!0,e,n);case 19:return al(e,t,n);case 23:case 24:return Ui(e,t,n)}throw Error(i(156,t.tag))},rc.prototype.render=function(e){Js(e,this._internalRoot,null,null)},rc.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;Js(null,e,null,(function(){t[Jr]=null}))},et=function(e){13===e.tag&&(ms(e,4,ps()),nc(e,4))},tt=function(e){13===e.tag&&(ms(e,67108864,ps()),nc(e,67108864))},nt=function(e){if(13===e.tag){var t=ps(),n=fs(e);ms(e,n,t),nc(e,n)}},rt=function(e,t){return t()},Ce=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=aa(r);if(!a)throw Error(i(90));Q(r),ne(r,a)}}}break;case"textarea":ce(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Re=ws,Oe=function(e,t,n,r,a){var o=Rl;Rl|=4;try{return Ha(98,e.bind(null,t,n,r,a))}finally{0===(Rl=o)&&(Vl(),Va())}},De=function(){0==(49&Rl)&&(function(){if(null!==as){var e=as;as=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,hs(e,$a())}))}Va()}(),Is())},Ie=function(e,t){var n=Rl;Rl|=2;try{return e(t)}finally{0===(Rl=n)&&(Vl(),Va())}};var lc={Events:[na,ra,aa,Pe,Ne,Is,{current:!1}]},sc={findFiberByHostInstance:ta,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},cc={bundleType:sc.bundleType,version:sc.version,rendererPackageName:sc.rendererPackageName,rendererConfig:sc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Xe(e))?null:e.stateNode},findFiberByHostInstance:sc.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var uc=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!uc.isDisabled&&uc.supportsFiber)try{Sa=uc.inject(cc),Ea=uc}catch(ge){}}t.hydrate=function(e,t,n){if(!ac(t))throw Error(i(200));return oc(null,e,t,!0,n)}},3935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(4448)},9590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,c,u;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(!o(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;for(u=e.entries();!(s=u.next()).done;)if(!o(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((l=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!=s--;)if(!Object.prototype.hasOwnProperty.call(i,c[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!=s--;)if(("_owner"!==c[s]&&"__v"!==c[s]&&"__o"!==c[s]||!e.$$typeof)&&!o(e[c[s]],i[c[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>H,ql:()=>J});var r=n(7294),a=n(5697),o=n.n(a),i=n(9590),l=n.n(i),s=n(1143),c=n.n(s),u=n(6774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function g(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(h).map((function(e){return h[e]})),k={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},S=Object.keys(k).reduce((function(e,t){return e[k[t]]=t,e}),{}),E=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=E(e,h.TITLE),n=E(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=E(e,"defaultTitle");return t||r||void 0},x=function(e){return E(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a<r.length;a+=1){var o=r[a].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},L=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var a={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var l=o[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),a[n]||(a[n]={}),!r[n][c]&&(a[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(a),i=0;i<o.length;i+=1){var l=o[i],s=p({},r[l],a[l]);r[l]=s}return e}),[]).reverse()},A=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},N=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},R=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},O=[h.NOSCRIPT,h.SCRIPT,h.STYLE],D=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},I=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},M=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[k[n]||n]=e[n],t}),t)},j=function(e,t){return t.map((function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach((function(e){var n=k[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),r.createElement(e,o)}))},B=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=M(n,a),[r.createElement(h.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=I(n),o=P(t);return a?"<"+e+' data-rh="true" '+a+">"+D(o,r)+"</"+e+">":"<"+e+' data-rh="true">'+D(o,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return M(t)},toString:function(){return I(t)}};default:return{toComponent:function(){return j(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+D(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===O.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},F=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=N(e.metaTags,y),o=N(t,b),i=N(n,v);return{priorityMethods:{toComponent:function(){return[].concat(j(h.META,a.priority),j(h.LINK,o.priority),j(h.SCRIPT,i.priority))},toString:function(){return B(h.META,a.priority,r)+" "+B(h.LINK,o.priority,r)+" "+B(h.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);f=m.priorityMethods,u=m.linkTags,d=m.metaTags,p=m.scriptTags}return{priority:f,base:B(h.BASE,t,r),bodyAttributes:B("bodyAttributes",n,r),htmlAttributes:B("htmlAttributes",a,r),link:B(h.LINK,u,r),meta:B(h.META,d,r),noscript:B(h.NOSCRIPT,o,r),script:B(h.SCRIPT,p,r),style:B(h.STYLE,i,r),title:B(h.TITLE,{title:s,titleAttributes:c},r)}},z=[],U=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=F({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},$=r.createContext({}),G=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),q="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new U(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement($.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=q,H.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var Z=function(e,t){var n,r=document.head||document.querySelector(h.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,r.isEqualNode(e)}))?o.splice(n,1):i.push(r)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:o,newTags:i}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],c=t[s]||"";n.getAttribute(s)!==c&&n.setAttribute(s,c),-1===a.indexOf(s)&&a.push(s);var u=o.indexOf(s);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},W=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;V(h.BODY,e.bodyAttributes),V(h.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),V(h.TITLE,t)}(u,d);var p={baseTag:Z(h.BASE,n),linkTags:Z(h.LINK,a),metaTags:Z(h.META,o),noscriptTags:Z(h.NOSCRIPT,i),scriptTags:Z(h.SCRIPT,s),styleTags:Z(h.STYLE,c)},f={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),l(e,f,m)},Y=null,K=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,a=null,o=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:E(e,"defer"),encode:E(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:L(h.LINK,["rel","href"],e),metaTags:L(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:L(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:x(e),scriptTags:L(h.SCRIPT,["src","innerHTML"],e),styleTags:L(h.STYLE,["cssText"],e),title:_(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:A(e,"prioritizeSeoTags")});H.canUseDOM?(t=o,Y&&cancelAnimationFrame(Y),t.defer?Y=requestAnimationFrame((function(){W(t,(function(){Y=null}))})):(W(t),Y=null)):F&&(a=F(o)),r(a)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);K.propTypes={context:G.isRequired},K.displayName="HelmetDispatcher";var Q=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(R(this.props,"helmetData"),R(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case h.TITLE:return p({},a,((t={})[r.type]=i,t.titleAttributes=p({},o),t));case h.BODY:return p({},a,{bodyAttributes:p({},o)});case h.HTML:return p({},a,{htmlAttributes:p({},o)});default:return p({},a,((n={})[r.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,o=r.children,i=g(r,Q),l=Object.keys(i).reduce((function(e,t){return e[S[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,o),s){case h.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:l,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=g(e,X),a=p({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof U||(o=new U(o.context,o.instances)),o?r.createElement(K,p({},a,{context:o.value,helmetData:void 0})):r.createElement($.Consumer,null,(function(e){return r.createElement(K,p({},a,{context:e}))}))},t}(r.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},9921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,g=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case o:case l:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case h:case g:case s:return e;default:return t}}case a:return t}}}function S(e){return k(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=p,t.Fragment=o,t.Lazy=h,t.Memo=g,t.Portal=a,t.Profiler=l,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return S(e)||k(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===c},t.isContextProvider=function(e){return k(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===p},t.isFragment=function(e){return k(e)===o},t.isLazy=function(e){return k(e)===h},t.isMemo=function(e){return k(e)===g},t.isPortal=function(e){return k(e)===a},t.isProfiler=function(e){return k(e)===l},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===l||e===i||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===g||e.$$typeof===s||e.$$typeof===c||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=k},9864:(e,t,n)=>{"use strict";e.exports=n(9921)},8356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(7294),s=n(5697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var a=d(e[r]);a.loading?t.loading=!0:(t.loaded[r]=a.loaded,t.error=a.error),n.push(a.promise),a.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),g=null;function h(){return g||(g=e(m.loader)),g.promise}return c.push(h),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=d=function(t){function n(n){var r;return o(a(a(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),g=e(m.loader),r._loadModule()})),h(),r.state={error:g.error,pastDelay:!1,timedOut:!1,loading:g.loading,loaded:g.loaded},r}r(n,t),n.preload=function(){return h()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.loadable.report(t)})),g.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:g.error,loaded:g.loaded,loading:g.loading}),e._clearTimeouts()};g.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(l.Component),o(d,"contextTypes",{loadable:s.shape({report:s.func.isRequired})}),p}function g(e){return m(d,e)}g.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return l.Children.only(this.props.children)},t}(l.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}o(h,"propTypes",{report:s.func.isRequired}),o(h,"childContextTypes",{loadable:s.shape({report:s.func.isRequired}).isRequired}),g.Capture=h,g.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},g.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=g},8790:(e,t,n)=>{"use strict";n.d(t,{H:()=>l,f:()=>i});var r=n(6550),a=n(7462),o=n(7294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var a=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return a&&(n.push({route:e,match:a}),e.routes&&i(e.routes,t,n)),a})),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(r.rs,n,e.map((function(e,n){return o.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,a.Z)({},n,{},t,{route:e})):o.createElement(e.component,(0,a.Z)({},n,t,{route:e}))}})}))):null}},3727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>u,rU:()=>h});var r=n(6550),a=n(5068),o=n(7294),i=n(9318),l=n(7462),s=n(3366),c=n(2177),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.lX)(t.props),t}return(0,a.Z)(t,e),t.prototype.render=function(){return o.createElement(r.F0,{history:this.history,children:this.props.children})},t}(o.Component);o.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},f=function(e){return e},m=o.forwardRef;void 0===m&&(m=f);var g=m((function(e,t){var n=e.innerRef,r=e.navigate,a=e.onClick,i=(0,s.Z)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,l.Z)({},i,{onClick:function(e){try{a&&a(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=f!==m&&t||n,o.createElement("a",u)}));var h=m((function(e,t){var n=e.component,a=void 0===n?g:n,u=e.replace,h=e.to,b=e.innerRef,v=(0,s.Z)(e,["component","replace","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,r=p(d(h,e.location),e.location),s=r?n.createHref(r):"",g=(0,l.Z)({},v,{href:s,navigate:function(){var t=d(h,e.location),r=(0,i.Ep)(e.location)===(0,i.Ep)(p(t));(u||r?n.replace:n.push)(t)}});return f!==m?g.ref=t||b:g.innerRef=b,o.createElement(a,g)}))})),b=function(e){return e},v=o.forwardRef;void 0===v&&(v=b);var y=v((function(e,t){var n=e["aria-current"],a=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,f=e.activeStyle,m=e.className,g=e.exact,y=e.isActive,w=e.location,k=e.sensitive,S=e.strict,E=e.style,_=e.to,x=e.innerRef,C=(0,s.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=w||e.location,i=p(d(_,n),n),s=i.pathname,T=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),L=T?(0,r.LX)(n.pathname,{path:T,exact:g,sensitive:k,strict:S}):null,A=!!(y?y(L,n):L),P="function"==typeof m?m(A):m,N="function"==typeof E?E(A):E;A&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,u),N=(0,l.Z)({},N,f));var R=(0,l.Z)({"aria-current":A&&a||null,className:P,style:N,to:i},C);return b!==v?R.ref=t||x:R.innerRef=x,o.createElement(h,R)}))}))},6550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>_,F0:()=>y,LX:()=>E,TH:()=>O,k6:()=>R,rs:()=>P,s6:()=>v});var r=n(5068),a=n(7294),o=n(5697),i=n.n(o),l=n(9318),s=n(2177),c=n(7462),u=n(4779),d=n.n(u),p=(n(9864),n(3366)),f=(n(8679),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var g=a.createContext||function(e,t){var n,o,l="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n,r,a=arguments.length,o=new Array(a),i=0;i<a;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.Z)(n,e);var a=n.prototype;return a.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},a.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(i=a)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(r,a):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},a.render=function(){return this.props.children},n}(a.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var a=n.prototype;return a.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},a.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},a.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},a.getValue=function(){return this.context[l]?this.context[l].get():e},a.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(a.Component);return c.contextTypes=((o={})[l]=i().object,o),{Provider:s,Consumer:c}},h=function(e){var t=g();return t.displayName=e,t},b=h("Router-History"),v=h("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return a.createElement(v.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},a.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(a.Component);a.Component;a.Component;var w={},k=1e4,S=0;function E(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,i=n.strict,l=void 0!==i&&i,s=n.sensitive,c=void 0!==s&&s;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var a=[],o={regexp:d()(e,a,t),keys:a};return S<k&&(r[e]=o,S++),o}(n,{end:o,strict:l,sensitive:c}),a=r.regexp,i=r.keys,s=a.exec(e);if(!s)return null;var u=s[0],p=s.slice(1),f=e===u;return o&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var _=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,s.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?E(n.pathname,e.props):t.match,o=(0,c.Z)({},t,{location:n,match:r}),i=e.props,l=i.children,u=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===a.Children.count(e)}(l)&&(l=null),a.createElement(v.Provider,{value:o},o.match?l?"function"==typeof l?l(o):l:u?a.createElement(u,o):d?d(o):null:"function"==typeof l?l(o):null)}))},t}(a.Component);function x(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=x(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,l.Ep)(e)}function L(e){return function(){(0,s.Z)(!1)}}function A(){}a.Component;var P=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,s.Z)(!1);var n,r,o=e.props.location||t.location;return a.Children.forEach(e.props.children,(function(e){if(null==r&&a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?E(o.pathname,(0,c.Z)({},e.props,{path:i})):t.match}})),r?a.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(a.Component);var N=a.useContext;function R(){return N(b)}function O(){return N(v).location}},2408:(e,t,n)=>{"use strict";var r=n(7418),a=60103,o=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,l=60110,s=60112;t.Suspense=60113;var c=60115,u=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;a=d("react.element"),o=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),l=d("react.context"),s=d("react.forward_ref"),t.Suspense=d("react.suspense"),c=d("react.memo"),u=d("react.lazy")}var p="function"==typeof Symbol&&Symbol.iterator;function f(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g={};function h(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}function b(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}h.prototype.isReactComponent={},h.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(f(85));this.updater.enqueueSetState(this,e,t,"setState")},h.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=h.prototype;var y=v.prototype=new b;y.constructor=v,r(y,h.prototype),y.isPureReactComponent=!0;var w={current:null},k=Object.prototype.hasOwnProperty,S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,n){var r,o={},i=null,l=null;if(null!=t)for(r in void 0!==t.ref&&(l=t.ref),void 0!==t.key&&(i=""+t.key),t)k.call(t,r)&&!S.hasOwnProperty(r)&&(o[r]=t[r]);var s=arguments.length-2;if(1===s)o.children=n;else if(1<s){for(var c=Array(s),u=0;u<s;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(r in s=e.defaultProps)void 0===o[r]&&(o[r]=s[r]);return{$$typeof:a,type:e,key:i,ref:l,props:o,_owner:w.current}}function _(e){return"object"==typeof e&&null!==e&&e.$$typeof===a}var x=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,n,r,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s=!1;if(null===e)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case a:case o:s=!0}}if(s)return i=i(s=e),e=""===r?"."+C(s,0):r,Array.isArray(i)?(n="",null!=e&&(n=e.replace(x,"$&/")+"/"),T(i,t,n,"",(function(e){return e}))):null!=i&&(_(i)&&(i=function(e,t){return{$$typeof:a,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||s&&s.key===i.key?"":(""+i.key).replace(x,"$&/")+"/")+e)),t.push(i)),1;if(s=0,r=""===r?".":r+":",Array.isArray(e))for(var c=0;c<e.length;c++){var u=r+C(l=e[c],c);s+=T(l,t,n,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=p&&e[p]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(l=e.next()).done;)s+=T(l=l.value,t,n,u=r+C(l,c++),i);else if("object"===l)throw t=""+e,Error(f(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return s}function L(e,t,n){if(null==e)return e;var r=[],a=0;return T(e,r,"","",(function(e){return t.call(n,e,a++)})),r}function A(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function N(){var e=P.current;if(null===e)throw Error(f(321));return e}var R={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:L,forEach:function(e,t,n){L(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return L(e,(function(){t++})),t},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!_(e))throw Error(f(143));return e}},t.Component=h,t.PureComponent=v,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=R,t.cloneElement=function(e,t,n){if(null==e)throw Error(f(267,e));var o=r({},e.props),i=e.key,l=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(l=t.ref,s=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(u in t)k.call(t,u)&&!S.hasOwnProperty(u)&&(o[u]=void 0===t[u]&&void 0!==c?c[u]:t[u])}var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){c=Array(u);for(var d=0;d<u;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:a,type:e.type,key:i,ref:l,props:o,_owner:s}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:l,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:s,render:e}},t.isValidElement=_,t.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:A}},t.memo=function(e,t){return{$$typeof:c,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return N().useCallback(e,t)},t.useContext=function(e,t){return N().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return N().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return N().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return N().useLayoutEffect(e,t)},t.useMemo=function(e,t){return N().useMemo(e,t)},t.useReducer=function(e,t,n){return N().useReducer(e,t,n)},t.useRef=function(e){return N().useRef(e)},t.useState=function(e){return N().useState(e)},t.version="17.0.2"},7294:(e,t,n)=>{"use strict";e.exports=n(2408)},53:(e,t)=>{"use strict";var n,r,a,o;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var c=null,u=null,d=function(){if(null!==c)try{var e=t.unstable_now();c(!0,e),c=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==c?setTimeout(n,0,e):(c=e,setTimeout(d,0))},r=function(e,t){u=setTimeout(e,t)},a=function(){clearTimeout(u)},t.unstable_shouldYield=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var p=window.setTimeout,f=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var g=!1,h=null,b=-1,v=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):v=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,k=w.port2;w.port1.onmessage=function(){if(null!==h){var e=t.unstable_now();y=e+v;try{h(!0,e)?k.postMessage(null):(g=!1,h=null)}catch(n){throw k.postMessage(null),n}}else g=!1},n=function(e){h=e,g||(g=!0,k.postMessage(null))},r=function(e,n){b=p((function(){e(t.unstable_now())}),n)},a=function(){f(b),b=-1}}function S(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<x(a,t)))break e;e[r]=t,e[n]=a,n=r}}function E(e){return void 0===(e=e[0])?null:e}function _(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var o=2*(r+1)-1,i=e[o],l=o+1,s=e[l];if(void 0!==i&&0>x(i,n))void 0!==s&&0>x(s,i)?(e[r]=s,e[l]=n,r=l):(e[r]=i,e[o]=n,r=o);else{if(!(void 0!==s&&0>x(s,n)))break e;e[r]=s,e[l]=n,r=l}}}return t}return null}function x(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],T=[],L=1,A=null,P=3,N=!1,R=!1,O=!1;function D(e){for(var t=E(T);null!==t;){if(null===t.callback)_(T);else{if(!(t.startTime<=e))break;_(T),t.sortIndex=t.expirationTime,S(C,t)}t=E(T)}}function I(e){if(O=!1,D(e),!R)if(null!==E(C))R=!0,n(M);else{var t=E(T);null!==t&&r(I,t.startTime-e)}}function M(e,n){R=!1,O&&(O=!1,a()),N=!0;var o=P;try{for(D(n),A=E(C);null!==A&&(!(A.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=A.callback;if("function"==typeof i){A.callback=null,P=A.priorityLevel;var l=i(A.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?A.callback=l:A===E(C)&&_(C),D(n)}else _(C);A=E(C)}if(null!==A)var s=!0;else{var c=E(T);null!==c&&r(I,c.startTime-n),s=!1}return s}finally{A=null,P=o,N=!1}}var j=o;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){R||N||(R=!0,n(M))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return E(C)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=j,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,o,i){var l=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?l+i:l:i=l,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:L++,callback:o,priorityLevel:e,startTime:i,expirationTime:s=i+s,sortIndex:-1},i>l?(e.sortIndex=i,S(T,e),null===E(C)&&e===E(T)&&(O?a():O=!0,r(I,i-l))):(e.sortIndex=s,S(C,e),R||N||(R=!0,n(M))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},3840:(e,t,n)=>{"use strict";e.exports=n(53)},6774:e=>{e.exports=function(e,t,n,r){var a=n?n.call(r,e,t):void 0;if(void 0!==a)return!!a;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<o.length;s++){var c=o[s];if(!l(c))return!1;var u=e[c],d=t[c];if(!1===(a=n?n.call(r,u,d,c):void 0)||void 0===a&&u!==d)return!1}return!0}},2177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t;throw new Error(n?a+": "+n:a)}}},3250:(e,t,n)=>{"use strict";var r=n(7294);var a="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=r.useState,i=r.useEffect,l=r.useLayoutEffect,s=r.useDebugValue;function c(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!a(e,n)}catch(r){return!0}}var u="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=o({inst:{value:n,getSnapshot:t}}),a=r[0].inst,u=r[1];return l((function(){a.value=n,a.getSnapshot=t,c(a)&&u({inst:a})}),[e,n,t]),i((function(){return c(a)&&u({inst:a}),e((function(){c(a)&&u({inst:a})}))}),[e]),s(n),n};void 0!==r.useSyncExternalStore&&r.useSyncExternalStore},1688:(e,t,n)=>{"use strict";n(3250)},6809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"The Cwtch Handbook",tagline:"Your Guide to setting up, and using, Surveillance Resistant Infrastructure",url:"https://docs.cwtch.im",baseUrl:"/de/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/favicon.png",organizationName:"Open Privacy Research Society",projectName:"cwtch.im",i18n:{defaultLocale:"en",locales:["en","es","de","it"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/",remarkPlugins:[null],rehypePlugins:[null]},blog:{feedOptions:{type:"all",copyright:"Copyright \xa9 ${new Date().getFullYear()} Open Privacy Research Society",title:"Cwtch Development Log",description:"The latest insight into Cwtch Development and what the Cwtch team are working on"},blogSidebarCount:20},theme:{customCss:"/home/sarah/PARA/projects/docs.cwtch.im/src/css/custom.css"}}]],themeConfig:{image:"img/cwtch_handbook_header.jpg",colorMode:{defaultMode:"dark",disableSwitch:!1,respectPrefersColorScheme:!1},navbar:{title:"Cwtch Handbuch",logo:{alt:"Cwtch-Logo",src:"img/knott.png"},items:[{type:"doc",docId:"intro",position:"left",label:"Cwtch-Einf\xfchrung"},{to:"/security/intro",position:"left",label:"Sicherheitshandbuch"},{to:"/developing/intro",position:"left",label:"Entwicklerhandbuch"},{to:"blog",position:"left",label:"Entwicklungsprotokoll"},{href:"https://openprivacy.ca/donate",label:"Spenden",position:"right"},{href:"https://patreon.com/openprivacy",label:"Patreon",position:"right"},{href:"https://cwtch.im/download",label:"Herunterladen",position:"right"},{type:"localeDropdown",position:"right",dropdownItemsBefore:[],dropdownItemsAfter:[]}],hideOnScroll:!1},footer:{links:[{title:"Dokumentation",items:[{label:"Einf\xfchrung",to:"/docs/intro"},{to:"/security/intro",label:"Sicherheitshandbuch"},{to:"/developing/intro",label:"Entwicklerhandbuch"}]},{title:"Gemeinschaft",items:[{label:"Mastodon",href:"https://fosstodon.org/@cwtch"},{label:"Twitter",href:"https://twitter.com/cwtch_im"}]},{title:"Mitwirken",items:[{label:"Spenden",href:"https://openprivacy.ca/donate"},{label:"Patreon",href:"https://patreon.com/openprivacy"},{label:"Quellcode",href:"https://git.openprivacy.ca/cwtch.im"},{label:"Herunterladen",href:"https://cwtch.im/download"}]}],copyright:"Copyright \xa9 Open Privacy Research Society",style:"light"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},plugins:[["@docusaurus/plugin-content-docs",{id:"docs-security",path:"security",routeBasePath:"security",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}],["@docusaurus/plugin-content-docs",{id:"docs-developer",path:"developing",routeBasePath:"developing",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}]],stylesheets:[{href:"/katex/katex.min.css",type:"text/css"}],baseUrlIssueBanner:!0,onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},themes:[],scripts:[],headTags:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{mermaid:!1}}},7462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},5068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>a})},3366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}n.d(t,{Z:()=>r})},7529:e=>{"use strict";e.exports=JSON.parse('{"theme.AnnouncementBar.closeButtonAriaLabel":"Schliessen","theme.BackToTopButton.buttonAriaLabel":"Zur\xfcck nach oben springen","theme.CodeBlock.copied":"Kopiert","theme.CodeBlock.copy":"Kopieren","theme.CodeBlock.copyButtonAriaLabel":"Code in die Zwischenablage kopieren","theme.CodeBlock.wordWrapToggle":"Zeilenumbruch ein-/ausschalten","theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel":"Einklappbare Seitenleistenkategorie \\"{label}\\" umschalten","theme.ErrorPageContent.title":"Diese Seite ist abgest\xfcrzt.","theme.ErrorPageContent.tryAgain":"Erneut versuchen","theme.NavBar.navAriaLabel":"Hauptseite","theme.NotFound.p1":"Wir konnten leider nicht finden, wonach du gesucht hast.","theme.NotFound.p2":"Bitte kontaktiere den/die Besitzer*in der Seite, die dich mit der urspr\xfcnglichen URL verlinkt hat, und teile mit, dass der Link nicht mehr funktioniert.","theme.NotFound.title":"Seite nicht gefunden","theme.TOCCollapsible.toggleButtonLabel":"Auf dieser Seite","theme.admonition.caution":"caution Vorsicht","theme.admonition.danger":"danger Gefahr","theme.admonition.info":"info Info","theme.admonition.note":"note Hinweis","theme.admonition.tip":"tip Hinweis","theme.blog.archive.description":"Archiv","theme.blog.archive.title":"Archiv","theme.blog.paginator.navAriaLabel":"Navigation der Blogs","theme.blog.paginator.newerEntries":"Neuere Eintr\xe4ge","theme.blog.paginator.olderEntries":"\xc4ltere Eintr\xe4ge","theme.blog.post.paginator.navAriaLabel":"Blog Post Seiten Navigation","theme.blog.post.paginator.newerPost":"Neuerer Beitrag","theme.blog.post.paginator.olderPost":"\xc4lterer Beitrag","theme.blog.post.plurals":"Ein Beitrag|{count} Beitr\xe4ge","theme.blog.post.readMore":"Mehr lesen","theme.blog.post.readMoreLabel":"Mehr \xfcber {title} lesen","theme.blog.post.readingTime.plurals":"Eine Minute Lesezeit|{readingTime} Minuten Lesezeit","theme.blog.sidebar.navAriaLabel":"Navigation der letzten Blogbeitr\xe4ge","theme.blog.tagTitle":"{nPosts} markiert mit \\"{tagName}\\"","theme.colorToggle.ariaLabel":"Zwischen Dunkel- und Hellmodus wechseln (derzeit {mode})","theme.colorToggle.ariaLabel.mode.dark":"dunkler Modus","theme.colorToggle.ariaLabel.mode.light":"heller Modus","theme.common.editThisPage":"Diese Seite bearbeiten","theme.common.headingLinkTitle":"Direkter Link zur \xdcberschrift","theme.common.skipToMainContent":"Zum Hauptinhalt springen","theme.docs.DocCard.categoryDescription":"{count} Elemente","theme.docs.breadcrumbs.home":"Startseite","theme.docs.breadcrumbs.navAriaLabel":"Breadcrumbs","theme.docs.paginator.navAriaLabel":"Navigation der Dokumentationsseiten","theme.docs.paginator.next":"N\xe4chste","theme.docs.paginator.previous":"Vorherige","theme.docs.sidebar.closeSidebarButtonAriaLabel":"Navigationsleiste schlie\xdfen","theme.docs.sidebar.collapseButtonAriaLabel":"Seitenleiste ausblenden","theme.docs.sidebar.collapseButtonTitle":"Seitenleiste ausblenden","theme.docs.sidebar.expandButtonAriaLabel":"Seitenleiste einblenden","theme.docs.sidebar.expandButtonTitle":"Seitenleiste einblenden","theme.docs.sidebar.navAriaLabel":"Dokumentenseitenleiste","theme.docs.sidebar.toggleSidebarButtonAriaLabel":"Navigationsleiste umschalten","theme.docs.tagDocListPageTitle":"{nDocsTagged} markiert mit \\"{tagName}\\"","theme.docs.tagDocListPageTitle.nDocsTagged":"Ein Dokument markiert|{count} Dokumente markiert","theme.docs.versionBadge.label":"Version: {versionLabel}","theme.docs.versions.latestVersionLinkLabel":"aktuelle Version","theme.docs.versions.latestVersionSuggestionLabel":"F\xfcr die aktuellste Dokumentation bitte auf {latestVersionLink} ({versionLabel}) gehen.","theme.docs.versions.unmaintainedVersionLabel":"Dies ist eine Dokumentation f\xfcr {siteTitle} {versionLabel}, die nicht mehr aktiv gepflegt wird.","theme.docs.versions.unreleasedVersionLabel":"Dies ist eine unver\xf6ffentlichte Dokumentation f\xfcr die Version {siteTitle} {versionLabel}.","theme.lastUpdated.atDate":" am {date}","theme.lastUpdated.byUser":" von {user}","theme.lastUpdated.lastUpdatedAtBy":"Zuletzt aktualisiert {atDate} {byUser}","theme.navbar.mobileLanguageDropdown.label":"Sprachen","theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel":"\u2190 Zur\xfcck zum Hauptmen\xfc","theme.navbar.mobileVersionsDropdown.label":"Versionen","theme.tags.tagsListLabel":"Schlagw\xf6rter:","theme.tags.tagsPageLink":"Alle Schlagw\xf6rter anzeigen","theme.tags.tagsPageTitle":"Schlagw\xf6rter","Get Started With Cwtch":"Beginnen Sie mit Cwtch","The Cwtch Handbook":"The Cwtch Handbook","Your Guide to setting up, and using, Surveillance Resistant Infrastructure":"Your Guide to setting up, and using, Surveillance Resistant Infrastructure"}')},6887:e=>{"use strict";e.exports=JSON.parse('{"/de/blog-2e8":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"metadata":"41944db3"},"/de/blog/archive-1a3":{"__comp":"9e4087bc","__context":{"plugin":"c94c4dfb"},"archive":"291c70d7"},"/de/blog/autobindings-c2b":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9dd8190d"},"/de/blog/autobindings-ii-1ad":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"8fe7a387"},"/de/blog/availability-status-profile-attributes-6a7":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6a78f460"},"/de/blog/cwtch-android-reproducibility-4ca":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9b12a270"},"/de/blog/cwtch-bindings-reproducible-ad0":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"0d64c1d9"},"/de/blog/cwtch-developer-documentation-578":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a65a3c47"},"/de/blog/cwtch-documentation-6ef":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6275ceb4"},"/de/blog/cwtch-nightly-1-11-785":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"c96c5262"},"/de/blog/cwtch-nightly-1-12-691":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a02b4022"},"/de/blog/cwtch-nightly-v.11-74-cfa":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5beee875"},"/de/blog/cwtch-platform-support-9cb":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5e5faacc"},"/de/blog/cwtch-stable-api-design-2d7":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9e2a7473"},"/de/blog/cwtch-stable-roadmap-update-b9c":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"af23c5f9"},"/de/blog/cwtch-stable-roadmap-update-june-f96":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"61794344"},"/de/blog/cwtch-testing-i-6cf":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"43b107c1"},"/de/blog/cwtch-testing-ii-7bf":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9f1c7621"},"/de/blog/page/2-21e":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"metadata":"1a97c86e"},"/de/blog/path-to-cwtch-stable-13e":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"b0404c31"},"/de/blog/tags-e73":{"__comp":"01a85c17","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","tags":"5a84578f"},"/de/blog/tags/api-6e1":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"a79c88c2"}],"tag":"979b71b8","listMetadata":"c97dce39"},"/de/blog/tags/autobindings-e5f":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"b95aefa5","listMetadata":"523378a0"},"/de/blog/tags/bindings-b9e":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"},{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"03e998ac","listMetadata":"980b70df"},"/de/blog/tags/cwtch-934":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"6937af2a","listMetadata":"940964f5"},"/de/blog/tags/cwtch-stable-b4f":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"e2df4ad2","listMetadata":"4fad3920"},"/de/blog/tags/cwtch-stable/page/2-779":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"15c93cf0","listMetadata":"549d43e9"},"/de/blog/tags/cwtch/page/2-fda":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"0c915b16","listMetadata":"a92fc3a1"},"/de/blog/tags/developer-documentation-6b3":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"fe1dd7ae"},{"content":"5cb298ca"}],"tag":"0bd16fd2","listMetadata":"f4799792"},"/de/blog/tags/documentation-eba":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"afe8c04b","listMetadata":"89504eb8"},"/de/blog/tags/libcwtch-56b":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"326317af","listMetadata":"b96d814b"},"/de/blog/tags/nightly-416":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"141cdfa9"}],"tag":"0eb0d69b","listMetadata":"37c407d1"},"/de/blog/tags/planning-2e8":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"f041e880"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"9bec89a3","listMetadata":"decd0f12"},"/de/blog/tags/release-414":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"4aa555c3"},{"content":"89f86a37"}],"tag":"773ceef9","listMetadata":"113ce370"},"/de/blog/tags/repliqate-54a":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"a85d9f35","listMetadata":"0f04f840"},"/de/blog/tags/reproducible-builds-b3d":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"7a34d4a9","listMetadata":"f3be3c38"},"/de/blog/tags/security-handbook-00f":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"85f98c10","listMetadata":"5bdf583d"},"/de/blog/tags/support-234":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"},{"content":"ef78badf"}],"tag":"ed1907a0","listMetadata":"0861b93e"},"/de/blog/tags/testing-f12":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"}],"tag":"1908c298","listMetadata":"43bdde93"},"/de/developing-7da":{"__comp":"1be78505","__context":{"plugin":"d5f314f9"},"versionMetadata":"f928e8d9"},"/de/developing/building-a-cwtch-app/building-an-echobot-ea6":{"__comp":"17896441","content":"fd27e325"},"/de/developing/building-a-cwtch-app/core-concepts-19b":{"__comp":"17896441","content":"c14f15fd"},"/de/developing/building-a-cwtch-app/intro-157":{"__comp":"17896441","content":"824a28c6"},"/de/developing/category/building-a-cwtch-app-c92":{"__comp":"14eb3368","categoryGeneratedIndex":"e7b1bf29"},"/de/developing/intro-60e":{"__comp":"17896441","content":"fb3c1916"},"/de/developing/release-853":{"__comp":"17896441","content":"5dc151e9"},"/de/docs-41a":{"__comp":"1be78505","__context":{"plugin":"3db42865"},"versionMetadata":"935f2afb"},"/de/docs/category/appearance-d88":{"__comp":"14eb3368","categoryGeneratedIndex":"e6b5bfb1"},"/de/docs/category/behaviour-f3c":{"__comp":"14eb3368","categoryGeneratedIndex":"6e61466c"},"/de/docs/category/contribute-60f":{"__comp":"14eb3368","categoryGeneratedIndex":"e3d8cb96"},"/de/docs/category/conversations-fc8":{"__comp":"14eb3368","categoryGeneratedIndex":"5549e0e2"},"/de/docs/category/experiments-f3e":{"__comp":"14eb3368","categoryGeneratedIndex":"b0f5629f"},"/de/docs/category/getting-started-ddf":{"__comp":"14eb3368","categoryGeneratedIndex":"746f1580"},"/de/docs/category/groups-321":{"__comp":"14eb3368","categoryGeneratedIndex":"5fdc7b06"},"/de/docs/category/platforms-cdb":{"__comp":"14eb3368","categoryGeneratedIndex":"57fc9be0"},"/de/docs/category/profiles-c71":{"__comp":"14eb3368","categoryGeneratedIndex":"8e4780ba"},"/de/docs/category/servers-554":{"__comp":"14eb3368","categoryGeneratedIndex":"75bff082"},"/de/docs/category/settings-113":{"__comp":"14eb3368","categoryGeneratedIndex":"021fdb12"},"/de/docs/chat/accept-deny-new-conversation-486":{"__comp":"17896441","content":"803df0d9"},"/de/docs/chat/add-contact-718":{"__comp":"17896441","content":"e445c1ea"},"/de/docs/chat/block-contact-494":{"__comp":"17896441","content":"5f9a9669"},"/de/docs/chat/conversation-settings-30f":{"__comp":"17896441","content":"72a13759"},"/de/docs/chat/delete-contact-2ab":{"__comp":"17896441","content":"56c80d06"},"/de/docs/chat/introduction-02c":{"__comp":"17896441","content":"98609693"},"/de/docs/chat/message-formatting-c43":{"__comp":"17896441","content":"78e4de8f"},"/de/docs/chat/reply-to-message-638":{"__comp":"17896441","content":"b802a7ab"},"/de/docs/chat/save-conversation-history-aaf":{"__comp":"17896441","content":"a8d50805"},"/de/docs/chat/share-address-with-friends-a0a":{"__comp":"17896441","content":"9bd730d3"},"/de/docs/chat/share-file-7a5":{"__comp":"17896441","content":"0487f903"},"/de/docs/chat/unblock-contact-4ae":{"__comp":"17896441","content":"7747f3f6"},"/de/docs/contribute/developing-9df":{"__comp":"17896441","content":"7bea1ff1"},"/de/docs/contribute/documentation-519":{"__comp":"17896441","content":"e49fb087"},"/de/docs/contribute/stickers-a8d":{"__comp":"17896441","content":"d2095d9b"},"/de/docs/contribute/testing-5bb":{"__comp":"17896441","content":"b17c3fe9"},"/de/docs/contribute/translate-08b":{"__comp":"17896441","content":"c1102df1"},"/de/docs/getting-started/supported_platforms-902":{"__comp":"17896441","content":"6e606510"},"/de/docs/groups/accept-group-invite-09e":{"__comp":"17896441","content":"69baf694"},"/de/docs/groups/create-group-183":{"__comp":"17896441","content":"d72b1382"},"/de/docs/groups/edit-group-name-f7a":{"__comp":"17896441","content":"fe6d997b"},"/de/docs/groups/introduction-db2":{"__comp":"17896441","content":"58b7fc4c"},"/de/docs/groups/leave-group-99e":{"__comp":"17896441","content":"aa1db8cb"},"/de/docs/groups/manage-known-servers-7f8":{"__comp":"17896441","content":"5d8d36f7"},"/de/docs/groups/send-invite-0fb":{"__comp":"17896441","content":"2250486b"},"/de/docs/intro-22a":{"__comp":"17896441","content":"5bfc32c8"},"/de/docs/platforms/tails-478":{"__comp":"17896441","content":"39333829"},"/de/docs/profiles/availability-status-c91":{"__comp":"17896441","content":"5ab392cd"},"/de/docs/profiles/change-name-105":{"__comp":"17896441","content":"c5f4eaa1"},"/de/docs/profiles/change-password-710":{"__comp":"17896441","content":"001a236d"},"/de/docs/profiles/change-profile-image-9db":{"__comp":"17896441","content":"53f3dc0a"},"/de/docs/profiles/create-a-profile-ffb":{"__comp":"17896441","content":"787066a3"},"/de/docs/profiles/delete-profile-4e1":{"__comp":"17896441","content":"3e3471db"},"/de/docs/profiles/exporting-profile-782":{"__comp":"17896441","content":"c089f5db"},"/de/docs/profiles/importing-a-profile-00b":{"__comp":"17896441","content":"da082baa"},"/de/docs/profiles/introduction-4aa":{"__comp":"17896441","content":"8638bedc"},"/de/docs/profiles/profile-info-864":{"__comp":"17896441","content":"9428180e"},"/de/docs/profiles/unlock-profile-fca":{"__comp":"17896441","content":"3c1e1d04"},"/de/docs/servers/create-server-36f":{"__comp":"17896441","content":"373c7d5f"},"/de/docs/servers/delete-server-721":{"__comp":"17896441","content":"bfe3d434"},"/de/docs/servers/edit-server-c82":{"__comp":"17896441","content":"92123ee2"},"/de/docs/servers/introduction-88b":{"__comp":"17896441","content":"4350c8c2"},"/de/docs/servers/share-key-e79":{"__comp":"17896441","content":"0831902b"},"/de/docs/servers/unlock-server-e87":{"__comp":"17896441","content":"e949296e"},"/de/docs/settings/appearance/change-language-92a":{"__comp":"17896441","content":"16771999"},"/de/docs/settings/appearance/light-dark-mode-9b8":{"__comp":"17896441","content":"8b57ba24"},"/de/docs/settings/appearance/streamer-mode-66f":{"__comp":"17896441","content":"78625d6f"},"/de/docs/settings/appearance/ui-columns-72c":{"__comp":"17896441","content":"55bf5a51"},"/de/docs/settings/behaviour/block-unknown-connections-6b6":{"__comp":"17896441","content":"995c4a51"},"/de/docs/settings/behaviour/notification-content-a3b":{"__comp":"17896441","content":"f83bd450"},"/de/docs/settings/behaviour/notification-policy-ff8":{"__comp":"17896441","content":"924c44fc"},"/de/docs/settings/experiments/clickable-links-2ee":{"__comp":"17896441","content":"6036bdcc"},"/de/docs/settings/experiments/file-sharing-e78":{"__comp":"17896441","content":"18aaeea6"},"/de/docs/settings/experiments/group-experiment-ca3":{"__comp":"17896441","content":"5a2a7ed5"},"/de/docs/settings/experiments/image-previews-and-profile-pictures-ab5":{"__comp":"17896441","content":"948dc444"},"/de/docs/settings/experiments/message-formatting-9ec":{"__comp":"17896441","content":"c862d987"},"/de/docs/settings/experiments/qrcodes-0a3":{"__comp":"17896441","content":"2bb9f32f"},"/de/docs/settings/experiments/server-hosting-17e":{"__comp":"17896441","content":"ab726e24"},"/de/docs/settings/introduction-b7a":{"__comp":"17896441","content":"f7e5475a"},"/de/docs/tor-8fb":{"__comp":"17896441","content":"2114bf44"},"/de/security-63f":{"__comp":"1be78505","__context":{"plugin":"4f68bcc6"},"versionMetadata":"a8c7fdc6"},"/de/security/category/connectivity--tor-ae4":{"__comp":"14eb3368","categoryGeneratedIndex":"708a1ab9"},"/de/security/category/cwtch-087":{"__comp":"14eb3368","categoryGeneratedIndex":"12959a59"},"/de/security/category/cwtch-components-028":{"__comp":"14eb3368","categoryGeneratedIndex":"efb6a870"},"/de/security/category/cwtch-ui-a39":{"__comp":"14eb3368","categoryGeneratedIndex":"c2f21224"},"/de/security/category/tapir-db3":{"__comp":"14eb3368","categoryGeneratedIndex":"bba9d075"},"/de/security/components/connectivity/intro-69e":{"__comp":"17896441","content":"4dde1d77"},"/de/security/components/cwtch/groups-4ac":{"__comp":"17896441","content":"de5e68d7"},"/de/security/components/cwtch/key_bundles-1c3":{"__comp":"17896441","content":"dc2bcacd"},"/de/security/components/cwtch/message_formats-2a0":{"__comp":"17896441","content":"e0940a37"},"/de/security/components/cwtch/server-e86":{"__comp":"17896441","content":"b44f0b89"},"/de/security/components/ecosystem-overview-f56":{"__comp":"17896441","content":"b877509f"},"/de/security/components/intro-b7e":{"__comp":"17896441","content":"07a1a58f"},"/de/security/components/tapir/authentication_protocol-1d9":{"__comp":"17896441","content":"63475243"},"/de/security/components/tapir/packet_format-81e":{"__comp":"17896441","content":"9ad9d6dc"},"/de/security/components/ui/android-c38":{"__comp":"17896441","content":"dda846b3"},"/de/security/components/ui/image_previews-38e":{"__comp":"17896441","content":"7c7a84a1"},"/de/security/components/ui/input-670":{"__comp":"17896441","content":"f9d690e3"},"/de/security/components/ui/overlays-e2b":{"__comp":"17896441","content":"6f232d8e"},"/de/security/deployment-ba7":{"__comp":"17896441","content":"9323a439"},"/de/security/development-a32":{"__comp":"17896441","content":"a1dbc401"},"/de/security/intro-049":{"__comp":"17896441","content":"0692a985"},"/de/security/references-d86":{"__comp":"17896441","content":"cc484fa2"},"/de/security/risk-311":{"__comp":"17896441","content":"9c488c02"},"/de/-5da":{"__comp":"c4f5d8e4","__context":{"plugin":"e88d32a9"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[532],(()=>{return t=9383,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/build-staging/de/assets/js/main.2f831fc6.js.LICENSE.txt b/build-staging/de/assets/js/main.2f831fc6.js.LICENSE.txt new file mode 100644 index 00000000..eb75d691 --- /dev/null +++ b/build-staging/de/assets/js/main.2f831fc6.js.LICENSE.txt @@ -0,0 +1,63 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/** + * @license React + * use-sync-external-store-shim.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + */ + +/** @license React v0.20.2 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/build-staging/de/assets/js/runtime~main.aac63c61.js b/build-staging/de/assets/js/runtime~main.aac63c61.js new file mode 100644 index 00000000..312466cb --- /dev/null +++ b/build-staging/de/assets/js/runtime~main.aac63c61.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,a,f,c,d,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=b,r.c=t,e=[],r.O=(a,f,c,d)=>{if(!f){var b=1/0;for(i=0;i<e.length;i++){f=e[i][0],c=e[i][1],d=e[i][2];for(var t=!0,o=0;o<f.length;o++)(!1&d||b>=d)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,d<b&&(b=d));if(t){e.splice(i--,1);var n=c();void 0!==n&&(a=n)}}return a}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[f,c,d]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,c){if(1&c&&(e=this(e)),8&c)return e;if("object"==typeof e&&e){if(4&c&&e.__esModule)return e;if(16&c&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var b={};a=a||[null,f({}),f([]),f(f)];for(var t=2&c&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(d,b),d},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({53:"935f2afb",97:"9c488c02",171:"d72b1382",214:"e49fb087",263:"a1dbc401",276:"fb3c1916",337:"773ceef9",362:"7bea1ff1",380:"b877509f",420:"85f98c10",439:"6a78f460",497:"55bf5a51",563:"3c1e1d04",590:"dc2bcacd",716:"b802a7ab",725:"291c70d7",764:"6e606510",769:"bba9d075",788:"4d27f429",828:"9ad9d6dc",923:"5dc151e9",1020:"708a1ab9",1032:"56c80d06",1091:"57fc9be0",1118:"0f04f840",1132:"75bff082",1194:"e3d8cb96",1197:"43bdde93",1199:"fd27e325",1258:"9e2a7473",1280:"5bfc32c8",1312:"9f1c7621",1370:"ab726e24",1602:"a8c7fdc6",1725:"0eb0d69b",1740:"5d8d36f7",1745:"6036bdcc",1756:"6e61466c",1778:"efb6a870",1814:"f7e5475a",1865:"da082baa",1979:"fe1dd7ae",2044:"8e4780ba",2051:"9bd730d3",2096:"b17c3fe9",2112:"803df0d9",2184:"f76a3b8e",2233:"cc484fa2",2287:"0861b93e",2528:"f9d690e3",2535:"814f3328",2543:"979b71b8",2591:"e6b5bfb1",2612:"37c407d1",2619:"5fdc7b06",2628:"aa1db8cb",2688:"9dd8190d",2708:"39333829",2738:"6f232d8e",2833:"0c915b16",2849:"a85d9f35",2909:"5cb298ca",2911:"fe6d997b",2979:"7c7a84a1",3089:"a6aa9e1f",3218:"af23c5f9",3233:"de5e68d7",3249:"12959a59",3250:"b0f5629f",3271:"16771999",3278:"5f9a9669",3407:"8b57ba24",3413:"924c44fc",3492:"a02b4022",3508:"d2095d9b",3516:"4f68bcc6",3577:"decd0f12",3608:"9e4087bc",3629:"0487f903",3642:"72a13759",3717:"e7b1bf29",3727:"1a97c86e",3761:"c96c5262",3767:"ed1907a0",3887:"e0940a37",3906:"c862d987",3951:"001a236d",3952:"78625d6f",4013:"01a85c17",4195:"c4f5d8e4",4228:"0692a985",4240:"c089f5db",4481:"78e4de8f",4582:"995c4a51",4788:"1ebd8798",4814:"6937af2a",4817:"f3be3c38",4908:"53f3dc0a",5045:"5a84578f",5107:"c2f21224",5117:"7747f3f6",5226:"f041e880",5233:"8fe7a387",5246:"f83bd450",5273:"bf059cf9",5508:"7a34d4a9",5532:"ef78badf",5578:"1908c298",5674:"b95aefa5",5732:"1a25c548",5733:"326317af",5745:"89504eb8",5843:"c97dce39",5869:"d5f314f9",5883:"b96d814b",5905:"824a28c6",6011:"afe8c04b",6103:"ccc49370",6105:"e445c1ea",6153:"4dde1d77",6204:"69baf694",6232:"61794344",6275:"63475243",6295:"bfe3d434",6354:"18aaeea6",6395:"9323a439",6419:"0bd16fd2",6431:"5ab392cd",6452:"5549e0e2",6536:"a8d50805",6555:"6275ceb4",6585:"e88d32a9",6769:"58b7fc4c",6773:"92123ee2",6862:"4fad3920",6900:"980b70df",7015:"2250486b",7044:"b44f0b89",7139:"3db42865",7216:"113ce370",7252:"2114bf44",7293:"141cdfa9",7432:"5a2a7ed5",7460:"07a1a58f",7495:"41944db3",7591:"a65a3c47",7594:"53cc4802",7649:"c14f15fd",7782:"3a109bd3",7797:"4aa555c3",7860:"b0404c31",7918:"17896441",7970:"15c93cf0",7992:"f4799792",8192:"5e5faacc",8225:"c1102df1",8268:"e2df4ad2",8344:"9bec89a3",8351:"021fdb12",8357:"787066a3",8493:"8638bedc",8510:"3e3471db",8581:"03e998ac",8610:"6875c492",8710:"0d64c1d9",8786:"f928e8d9",8799:"b125d866",8835:"c747432f",8851:"948dc444",8932:"0831902b",8943:"c5f4eaa1",8959:"549d43e9",8980:"a92fc3a1",9085:"373c7d5f",9146:"c94c4dfb",9149:"e949296e",9162:"2bb9f32f",9178:"940964f5",9200:"43b107c1",9249:"9b12a270",9338:"dda846b3",9369:"4350c8c2",9444:"5beee875",9475:"523378a0",9508:"746f1580",9514:"1be78505",9550:"9428180e",9759:"89f86a37",9794:"98609693",9817:"14eb3368",9976:"a79c88c2",9978:"5bdf583d"}[e]||e)+"."+{53:"a1a09f05",97:"6046e2f8",171:"95676827",214:"590b19a4",263:"3390b4c3",276:"22eef329",337:"a5e9fd7a",362:"0cd85505",380:"c2fadaf5",420:"5193f85b",439:"b626ebee",497:"fe193480",563:"a4fd9050",590:"d9d70268",716:"531ba26b",725:"e1cc0c5e",764:"764571cd",769:"462177c6",788:"127d02e8",828:"db6df9ae",923:"84a9b26a",1020:"3254a360",1032:"c3a1d1c2",1091:"a0292f31",1118:"97f5d109",1132:"f91bcae3",1194:"9c9869df",1197:"aca904f8",1199:"0befa4a1",1258:"b8282671",1280:"786598ab",1312:"9a518122",1370:"9db808a3",1602:"6b08bc27",1725:"26f61e30",1740:"6b89d887",1745:"00b31633",1756:"7c750783",1778:"5c973c8c",1814:"ad1f9dbe",1865:"9e99cb9e",1979:"bb7908e8",2044:"c33e9ba5",2051:"9aafd7fc",2096:"ade4c602",2112:"1e172b64",2184:"21fab117",2233:"2ca9fa40",2287:"20851427",2528:"0acf5a91",2535:"46222a47",2543:"a0be1006",2591:"22e467e7",2612:"d2079a43",2619:"83b3ba22",2628:"63926186",2688:"76d06a78",2708:"65f7ccd9",2738:"57c8d8fd",2833:"73cbc157",2849:"4f11e7a8",2909:"2fcf1742",2911:"bf7f26e0",2979:"647782ac",3089:"8ac198c5",3218:"6408958f",3233:"f9e5a10c",3249:"7fe15889",3250:"8b4a2916",3271:"1ff393da",3278:"b039c6fb",3407:"61fcf910",3413:"e836e1ce",3492:"50e2e98d",3508:"ce009bc9",3516:"d9b156bf",3577:"35f6ebc7",3608:"582408aa",3629:"207c6625",3642:"4d747520",3717:"72210083",3727:"536b8e99",3761:"e2f3c8a0",3767:"765640b3",3887:"88839e56",3906:"cd734824",3951:"36952d55",3952:"bf004fbb",4013:"fbcc85f1",4195:"ea3b76f3",4228:"ebb8ca74",4240:"d346cd81",4481:"24d34fb4",4582:"55d04cd2",4788:"30d73187",4814:"a156a2a0",4817:"b0575211",4908:"98083968",4972:"486cf118",5045:"a3429355",5107:"75b22dc5",5117:"0738ad71",5226:"de1fab10",5233:"4209f6b8",5246:"363d02f2",5273:"2c6d0b26",5508:"084018de",5532:"10c4eea9",5578:"fa350f38",5674:"eb30a5e8",5732:"952c300d",5733:"7d99625d",5745:"bbcb116a",5843:"f8e42b29",5869:"1dc05f26",5883:"8e446437",5905:"a3dd5280",6011:"80a41c12",6048:"e7c7c18a",6103:"a9ca1f91",6105:"b181e62a",6153:"13b5e2ec",6204:"b646c8ee",6232:"e3775f5b",6275:"07180f7a",6295:"1ebf7514",6354:"de5edb8b",6395:"d4fdc476",6419:"cc975847",6431:"e73fd644",6452:"d72ced7a",6536:"c8607d5f",6555:"81dd6f1a",6585:"ff20b8ba",6769:"f2d94692",6773:"0766ae56",6862:"f7c18516",6900:"5d920609",7015:"30003be1",7044:"11a8e0bb",7139:"27ab3fca",7216:"ee3364d0",7252:"9b098c3d",7293:"087acaed",7432:"66520fa0",7460:"312624e8",7495:"558ad49b",7591:"a5f7f3c6",7594:"0826d515",7649:"0a8c6726",7782:"5c0e28ac",7797:"1751a2c9",7860:"c233cba7",7918:"27340309",7970:"d9154bf1",7992:"570b3460",8192:"463a908d",8225:"a3659bd9",8268:"abfeee4d",8344:"bd2b9eed",8351:"feb7c5a3",8357:"5dbcebe2",8493:"9fde2922",8510:"9ff1a319",8581:"0baefc34",8610:"a3d95c11",8710:"74653bc5",8786:"a40cdb9a",8799:"186024b1",8835:"92e780a0",8851:"62bf25d1",8932:"07b29433",8943:"abb16b7e",8959:"18ffa95a",8980:"799159ae",9085:"5c158d00",9146:"5e3bcaf2",9149:"b3b118aa",9162:"067a6a9d",9178:"c09d4cfe",9200:"11623f77",9249:"8c3428a2",9338:"81a1bc96",9369:"23a8a705",9444:"c7b0929b",9475:"36eab610",9508:"72b2827d",9514:"c2da882e",9550:"e7e66090",9759:"977505fc",9785:"e0c467d7",9794:"d9ca1bf2",9817:"5ac78d9e",9976:"011183de",9978:"f74a444e"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),c={},d="user-handbook:",r.l=(e,a,f,b)=>{if(c[e])c[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==d+f){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",d+f),t.src=e),c[e]=[a];var l=(a,f)=>{t.onerror=t.onload=null,clearTimeout(s);var d=c[e];if(delete c[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(f))),a)return a(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/de/",r.gca=function(e){return e={16771999:"3271",17896441:"7918",39333829:"2708",61794344:"6232",63475243:"6275",98609693:"9794","935f2afb":"53","9c488c02":"97",d72b1382:"171",e49fb087:"214",a1dbc401:"263",fb3c1916:"276","773ceef9":"337","7bea1ff1":"362",b877509f:"380","85f98c10":"420","6a78f460":"439","55bf5a51":"497","3c1e1d04":"563",dc2bcacd:"590",b802a7ab:"716","291c70d7":"725","6e606510":"764",bba9d075:"769","4d27f429":"788","9ad9d6dc":"828","5dc151e9":"923","708a1ab9":"1020","56c80d06":"1032","57fc9be0":"1091","0f04f840":"1118","75bff082":"1132",e3d8cb96:"1194","43bdde93":"1197",fd27e325:"1199","9e2a7473":"1258","5bfc32c8":"1280","9f1c7621":"1312",ab726e24:"1370",a8c7fdc6:"1602","0eb0d69b":"1725","5d8d36f7":"1740","6036bdcc":"1745","6e61466c":"1756",efb6a870:"1778",f7e5475a:"1814",da082baa:"1865",fe1dd7ae:"1979","8e4780ba":"2044","9bd730d3":"2051",b17c3fe9:"2096","803df0d9":"2112",f76a3b8e:"2184",cc484fa2:"2233","0861b93e":"2287",f9d690e3:"2528","814f3328":"2535","979b71b8":"2543",e6b5bfb1:"2591","37c407d1":"2612","5fdc7b06":"2619",aa1db8cb:"2628","9dd8190d":"2688","6f232d8e":"2738","0c915b16":"2833",a85d9f35:"2849","5cb298ca":"2909",fe6d997b:"2911","7c7a84a1":"2979",a6aa9e1f:"3089",af23c5f9:"3218",de5e68d7:"3233","12959a59":"3249",b0f5629f:"3250","5f9a9669":"3278","8b57ba24":"3407","924c44fc":"3413",a02b4022:"3492",d2095d9b:"3508","4f68bcc6":"3516",decd0f12:"3577","9e4087bc":"3608","0487f903":"3629","72a13759":"3642",e7b1bf29:"3717","1a97c86e":"3727",c96c5262:"3761",ed1907a0:"3767",e0940a37:"3887",c862d987:"3906","001a236d":"3951","78625d6f":"3952","01a85c17":"4013",c4f5d8e4:"4195","0692a985":"4228",c089f5db:"4240","78e4de8f":"4481","995c4a51":"4582","1ebd8798":"4788","6937af2a":"4814",f3be3c38:"4817","53f3dc0a":"4908","5a84578f":"5045",c2f21224:"5107","7747f3f6":"5117",f041e880:"5226","8fe7a387":"5233",f83bd450:"5246",bf059cf9:"5273","7a34d4a9":"5508",ef78badf:"5532","1908c298":"5578",b95aefa5:"5674","1a25c548":"5732","326317af":"5733","89504eb8":"5745",c97dce39:"5843",d5f314f9:"5869",b96d814b:"5883","824a28c6":"5905",afe8c04b:"6011",ccc49370:"6103",e445c1ea:"6105","4dde1d77":"6153","69baf694":"6204",bfe3d434:"6295","18aaeea6":"6354","9323a439":"6395","0bd16fd2":"6419","5ab392cd":"6431","5549e0e2":"6452",a8d50805:"6536","6275ceb4":"6555",e88d32a9:"6585","58b7fc4c":"6769","92123ee2":"6773","4fad3920":"6862","980b70df":"6900","2250486b":"7015",b44f0b89:"7044","3db42865":"7139","113ce370":"7216","2114bf44":"7252","141cdfa9":"7293","5a2a7ed5":"7432","07a1a58f":"7460","41944db3":"7495",a65a3c47:"7591","53cc4802":"7594",c14f15fd:"7649","3a109bd3":"7782","4aa555c3":"7797",b0404c31:"7860","15c93cf0":"7970",f4799792:"7992","5e5faacc":"8192",c1102df1:"8225",e2df4ad2:"8268","9bec89a3":"8344","021fdb12":"8351","787066a3":"8357","8638bedc":"8493","3e3471db":"8510","03e998ac":"8581","6875c492":"8610","0d64c1d9":"8710",f928e8d9:"8786",b125d866:"8799",c747432f:"8835","948dc444":"8851","0831902b":"8932",c5f4eaa1:"8943","549d43e9":"8959",a92fc3a1:"8980","373c7d5f":"9085",c94c4dfb:"9146",e949296e:"9149","2bb9f32f":"9162","940964f5":"9178","43b107c1":"9200","9b12a270":"9249",dda846b3:"9338","4350c8c2":"9369","5beee875":"9444","523378a0":"9475","746f1580":"9508","1be78505":"9514","9428180e":"9550","89f86a37":"9759","14eb3368":"9817",a79c88c2:"9976","5bdf583d":"9978"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(a,f)=>{var c=r.o(e,a)?e[a]:void 0;if(0!==c)if(c)f.push(c[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var d=new Promise(((f,d)=>c=e[a]=[f,d]));f.push(c[2]=d);var b=r.p+r.u(a),t=new Error;r.l(b,(f=>{if(r.o(e,a)&&(0!==(c=e[a])&&(e[a]=void 0),c)){var d=f&&("load"===f.type?"missing":f.type),b=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",t.name="ChunkLoadError",t.type=d,t.request=b,c[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var c,d,b=f[0],t=f[1],o=f[2],n=0;if(b.some((a=>0!==e[a]))){for(c in t)r.o(t,c)&&(r.m[c]=t[c]);if(o)var i=o(r)}for(a&&a(f);n<b.length;n++)d=b[n],r.o(e,d)&&e[d]&&e[d][0](),e[d]=0;return r.O(i)},f=self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[];f.forEach(a.bind(null,0)),f.push=a.bind(null,f.push.bind(f))})()})(); \ No newline at end of file diff --git a/build-staging/de/blog/archive/index.html b/build-staging/de/blog/archive/index.html new file mode 100644 index 00000000..eff6b990 --- /dev/null +++ b/build-staging/de/blog/archive/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html lang="de" dir="ltr" class="plugin-blog plugin-id-default"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v2.4.1"> +<title data-rh="true">Archiv | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/blog/atom.xml b/build-staging/de/blog/atom.xml new file mode 100644 index 00000000..30b558fc --- /dev/null +++ b/build-staging/de/blog/atom.xml @@ -0,0 +1,276 @@ + + + https://docs.cwtch.im/de/blog + Cwtch Development Log + 2023-06-30T00:00:00.000Z + https://github.com/jpmonette/feed + + The latest insight into Cwtch Development and what the Cwtch team are working on + https://docs.cwtch.im/de/img/favicon.png + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update-june + + 2023-06-30T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/de/blog/cwtch-nightly-1-12 + + 2023-06-16T00:00:00.000Z + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/de/blog/cwtch-nightly-v.11-74 + + 2023-06-07T00:00:00.000Z + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/de/blog/cwtch-developer-documentation + + 2023-04-28T00:00:00.000Z + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/de/blog/availability-status-profile-attributes + + 2023-04-06T00:00:00.000Z + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update + + 2023-03-31T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/de/blog/cwtch-nightly-1-11 + + 2023-03-29T00:00:00.000Z + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/de/blog/cwtch-documentation + + 2023-03-10T00:00:00.000Z + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/de/blog/autobindings-ii + + 2023-03-03T00:00:00.000Z + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/de/blog/autobindings + + 2023-02-24T00:00:00.000Z + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/de/blog/cwtch-testing-ii + + 2023-02-17T00:00:00.000Z + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/de/blog/cwtch-android-reproducibility + + 2023-02-10T00:00:00.000Z + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/de/blog/cwtch-testing-i + + 2023-02-03T00:00:00.000Z + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/de/blog/cwtch-platform-support + + 2023-01-27T00:00:00.000Z + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/de/blog/cwtch-bindings-reproducible + + 2023-01-20T00:00:00.000Z + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/de/blog/cwtch-stable-api-design + + 2023-01-13T00:00:00.000Z + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/de/blog/path-to-cwtch-stable + + 2023-01-06T00:00:00.000Z + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+
\ No newline at end of file diff --git a/build-staging/de/blog/autobindings-ii/index.html b/build-staging/de/blog/autobindings-ii/index.html new file mode 100644 index 00000000..366ec819 --- /dev/null +++ b/build-staging/de/blog/autobindings-ii/index.html @@ -0,0 +1,33 @@ + + + + + +Compile-time Optional Application Experiments (Autobindings) | The Cwtch Handbook + + + + + + + + + + + + +
+

Compile-time Optional Application Experiments (Autobindings)

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/autobindings/index.html b/build-staging/de/blog/autobindings/index.html new file mode 100644 index 00000000..5b6a716c --- /dev/null +++ b/build-staging/de/blog/autobindings/index.html @@ -0,0 +1,26 @@ + + + + + +Autogenerating Cwtch Bindings | The Cwtch Handbook + + + + + + + + + + + + +
+

Autogenerating Cwtch Bindings

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/availability-status-profile-attributes/index.html b/build-staging/de/blog/availability-status-profile-attributes/index.html new file mode 100644 index 00000000..3b143b5a --- /dev/null +++ b/build-staging/de/blog/availability-status-profile-attributes/index.html @@ -0,0 +1,25 @@ + + + + + +Availability Status and Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Availability Status and Profile Attributes

· 2 Minuten Lesezeit
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-android-reproducibility/index.html b/build-staging/de/blog/cwtch-android-reproducibility/index.html new file mode 100644 index 00000000..85458ed6 --- /dev/null +++ b/build-staging/de/blog/cwtch-android-reproducibility/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Android Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Android Bindings Reproducible

· 3 Minuten Lesezeit
Sarah Jamie Lewis

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-bindings-reproducible/index.html b/build-staging/de/blog/cwtch-bindings-reproducible/index.html new file mode 100644 index 00000000..4449467b --- /dev/null +++ b/build-staging/de/blog/cwtch-bindings-reproducible/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Bindings Reproducible

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-developer-documentation/index.html b/build-staging/de/blog/cwtch-developer-documentation/index.html new file mode 100644 index 00000000..b2e22e5c --- /dev/null +++ b/build-staging/de/blog/cwtch-developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly. | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-documentation/index.html b/build-staging/de/blog/cwtch-documentation/index.html new file mode 100644 index 00000000..b4843117 --- /dev/null +++ b/build-staging/de/blog/cwtch-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Updates to Cwtch Documentation | The Cwtch Handbook + + + + + + + + + + + + +
+

Updates to Cwtch Documentation

· 3 Minuten Lesezeit
Sarah Jamie Lewis

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-nightly-1-11/index.html b/build-staging/de/blog/cwtch-nightly-1-11/index.html new file mode 100644 index 00000000..69a30b6d --- /dev/null +++ b/build-staging/de/blog/cwtch-nightly-1-11/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.11 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.11

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-nightly-1-12/index.html b/build-staging/de/blog/cwtch-nightly-1-12/index.html new file mode 100644 index 00000000..5197e7fe --- /dev/null +++ b/build-staging/de/blog/cwtch-nightly-1-12/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.12 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.12

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-nightly-v.11-74/index.html b/build-staging/de/blog/cwtch-nightly-v.11-74/index.html new file mode 100644 index 00000000..e91cf646 --- /dev/null +++ b/build-staging/de/blog/cwtch-nightly-v.11-74/index.html @@ -0,0 +1,24 @@ + + + + + +New Cwtch Nightly (v1.11.0-74-g0406) | The Cwtch Handbook + + + + + + + + + + + + +
+

New Cwtch Nightly (v1.11.0-74-g0406)

· 2 Minuten Lesezeit
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-platform-support/index.html b/build-staging/de/blog/cwtch-platform-support/index.html new file mode 100644 index 00000000..7ed37340 --- /dev/null +++ b/build-staging/de/blog/cwtch-platform-support/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI Platform Support | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch UI Platform Support

· 11 Minuten Lesezeit
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-stable-api-design/index.html b/build-staging/de/blog/cwtch-stable-api-design/index.html new file mode 100644 index 00000000..7854e301 --- /dev/null +++ b/build-staging/de/blog/cwtch-stable-api-design/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable API Design | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable API Design

· 18 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-stable-roadmap-update-june/index.html b/build-staging/de/blog/cwtch-stable-roadmap-update-june/index.html new file mode 100644 index 00000000..13f71dbf --- /dev/null +++ b/build-staging/de/blog/cwtch-stable-roadmap-update-june/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-stable-roadmap-update/index.html b/build-staging/de/blog/cwtch-stable-roadmap-update/index.html new file mode 100644 index 00000000..23ddf41d --- /dev/null +++ b/build-staging/de/blog/cwtch-stable-roadmap-update/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-testing-i/index.html b/build-staging/de/blog/cwtch-testing-i/index.html new file mode 100644 index 00000000..5af1a122 --- /dev/null +++ b/build-staging/de/blog/cwtch-testing-i/index.html @@ -0,0 +1,25 @@ + + + + + +Notes on Cwtch UI Testing | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing

· 5 Minuten Lesezeit
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/cwtch-testing-ii/index.html b/build-staging/de/blog/cwtch-testing-ii/index.html new file mode 100644 index 00000000..e85eef07 --- /dev/null +++ b/build-staging/de/blog/cwtch-testing-ii/index.html @@ -0,0 +1,26 @@ + + + + + +Notes on Cwtch UI Testing (II) | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing (II)

· 2 Minuten Lesezeit
Sarah Jamie Lewis

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/feed.json b/build-staging/de/blog/feed.json new file mode 100644 index 00000000..62a16f98 --- /dev/null +++ b/build-staging/de/blog/feed.json @@ -0,0 +1,292 @@ +{ + "version": "https://jsonfeed.org/version/1", + "title": "Cwtch Development Log", + "home_page_url": "https://docs.cwtch.im/de/blog", + "description": "The latest insight into Cwtch Development and what the Cwtch team are working on", + "items": [ + { + "id": "https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update-june", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update-june", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals", + "date_modified": "2023-06-30T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-nightly-1-12", + "content_html": "

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-nightly-1-12", + "title": "Cwtch Beta 1.12", + "summary": "Cwtch Beta 1.12 is now available for download", + "date_modified": "2023-06-16T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-nightly-v.11-74", + "content_html": "

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-nightly-v.11-74", + "title": "New Cwtch Nightly (v1.11.0-74-g0406)", + "summary": "In this development log we take a look at the new Cwtch Nightly", + "date_modified": "2023-06-07T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-developer-documentation", + "content_html": "

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-developer-documentation", + "title": "Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.", + "summary": "In this development log we take a look at the new Cwtch developer docs!", + "date_modified": "2023-04-28T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/availability-status-profile-attributes", + "content_html": "

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like\nours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are \"Away\" or \"Busy\".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/availability-status-profile-attributes", + "title": "Availability Status and Profile Attributes", + "summary": "Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.", + "date_modified": "2023-04-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "nightly" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more", + "date_modified": "2023-03-31T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-nightly-1-11", + "content_html": "

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-nightly-1-11", + "title": "Cwtch Beta 1.11", + "summary": "Cwtch Beta 1.11 is now available for download", + "date_modified": "2023-03-29T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-documentation", + "content_html": "

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-documentation", + "title": "Updates to Cwtch Documentation", + "summary": " In this development log we will highlight some of the major documentation updates over the last few weeks.", + "date_modified": "2023-03-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "documentation", + "security-handbook" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/autobindings-ii", + "content_html": "

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an\ninitialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can\npass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option exp which will call the function on the configured experiment, and global to allow the setting up\nof a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import \"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on\ngeneration of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the\nfeature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/autobindings-ii", + "title": "Compile-time Optional Application Experiments (Autobindings)", + "summary": "In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.", + "date_modified": "2023-03-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/autobindings", + "content_html": "

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/autobindings", + "title": "Autogenerating Cwtch Bindings", + "summary": "In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.", + "date_modified": "2023-02-24T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-testing-ii", + "content_html": "

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-testing-ii", + "title": "Notes on Cwtch UI Testing (II)", + "summary": "In this development log we provide more updates on automated UI integration testing!", + "date_modified": "2023-02-17T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-android-reproducibility", + "content_html": "

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-android-reproducibility", + "title": "Making Cwtch Android Bindings Reproducible", + "summary": "In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible", + "date_modified": "2023-02-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-testing-i", + "content_html": "

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like \"take a screenshot\" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-testing-i", + "title": "Notes on Cwtch UI Testing", + "summary": "In this development log we provide an update on automated UI integration testing!", + "date_modified": "2023-02-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-platform-support", + "content_html": "

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\"

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

\"🟡\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-platform-support", + "title": "Cwtch UI Platform Support", + "summary": "This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.", + "date_modified": "2023-01-27T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-bindings-reproducible", + "content_html": "

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/cwtch-bindings-reproducible", + "title": "Making Cwtch Bindings Reproducible", + "summary": "How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.", + "date_modified": "2023-01-20T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/cwtch-stable-api-design", + "content_html": "

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • \"Unencrypted\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \"unencrypted\".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
", + "url": "https://docs.cwtch.im/de/blog/cwtch-stable-api-design", + "title": "Cwtch Stable API Design", + "summary": "The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ", + "date_modified": "2023-01-13T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning", + "api" + ] + }, + { + "id": "https://docs.cwtch.im/de/blog/path-to-cwtch-stable", + "content_html": "

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/de/blog/path-to-cwtch-stable", + "title": "Path to Cwtch Stable", + "summary": "The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.", + "date_modified": "2023-01-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + } + ] +} \ No newline at end of file diff --git a/build-staging/de/blog/index.html b/build-staging/de/blog/index.html new file mode 100644 index 00000000..a605006d --- /dev/null +++ b/build-staging/de/blog/index.html @@ -0,0 +1,26 @@ + + + + + +Entwicklungsprotokoll | The Cwtch Handbook + + + + + + + + + + + + +
+

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 2 Minuten Lesezeit
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 Minuten Lesezeit
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/page/2/index.html b/build-staging/de/blog/page/2/index.html new file mode 100644 index 00000000..c559b65c --- /dev/null +++ b/build-staging/de/blog/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +Entwicklungsprotokoll | The Cwtch Handbook + + + + + + + + + + + + +
+

· 5 Minuten Lesezeit
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 Minuten Lesezeit
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 Minuten Lesezeit
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/path-to-cwtch-stable/index.html b/build-staging/de/blog/path-to-cwtch-stable/index.html new file mode 100644 index 00000000..bfda2d61 --- /dev/null +++ b/build-staging/de/blog/path-to-cwtch-stable/index.html @@ -0,0 +1,24 @@ + + + + + +Path to Cwtch Stable | The Cwtch Handbook + + + + + + + + + + + + +
+

Path to Cwtch Stable

· 10 Minuten Lesezeit
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/rss.xml b/build-staging/de/blog/rss.xml new file mode 100644 index 00000000..eba64f40 --- /dev/null +++ b/build-staging/de/blog/rss.xml @@ -0,0 +1,227 @@ + + + + Cwtch Development Log + https://docs.cwtch.im/de/blog + The latest insight into Cwtch Development and what the Cwtch team are working on + Fri, 30 Jun 2023 00:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + de + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update-june + https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update-june + Fri, 30 Jun 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/de/blog/cwtch-nightly-1-12 + https://docs.cwtch.im/de/blog/cwtch-nightly-1-12 + Fri, 16 Jun 2023 00:00:00 GMT + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/de/blog/cwtch-nightly-v.11-74 + https://docs.cwtch.im/de/blog/cwtch-nightly-v.11-74 + Wed, 07 Jun 2023 00:00:00 GMT + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/de/blog/cwtch-developer-documentation + https://docs.cwtch.im/de/blog/cwtch-developer-documentation + Fri, 28 Apr 2023 00:00:00 GMT + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/de/blog/availability-status-profile-attributes + https://docs.cwtch.im/de/blog/availability-status-profile-attributes + Thu, 06 Apr 2023 00:00:00 GMT + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + nightly +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update + https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update + Fri, 31 Mar 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/de/blog/cwtch-nightly-1-11 + https://docs.cwtch.im/de/blog/cwtch-nightly-1-11 + Wed, 29 Mar 2023 00:00:00 GMT + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/de/blog/cwtch-documentation + https://docs.cwtch.im/de/blog/cwtch-documentation + Fri, 10 Mar 2023 00:00:00 GMT + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + documentation + security-handbook +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/de/blog/autobindings-ii + https://docs.cwtch.im/de/blog/autobindings-ii + Fri, 03 Mar 2023 00:00:00 GMT + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/de/blog/autobindings + https://docs.cwtch.im/de/blog/autobindings + Fri, 24 Feb 2023 00:00:00 GMT + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/de/blog/cwtch-testing-ii + https://docs.cwtch.im/de/blog/cwtch-testing-ii + Fri, 17 Feb 2023 00:00:00 GMT + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/de/blog/cwtch-android-reproducibility + https://docs.cwtch.im/de/blog/cwtch-android-reproducibility + Fri, 10 Feb 2023 00:00:00 GMT + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/de/blog/cwtch-testing-i + https://docs.cwtch.im/de/blog/cwtch-testing-i + Fri, 03 Feb 2023 00:00:00 GMT + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/de/blog/cwtch-platform-support + https://docs.cwtch.im/de/blog/cwtch-platform-support + Fri, 27 Jan 2023 00:00:00 GMT + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/de/blog/cwtch-bindings-reproducible + https://docs.cwtch.im/de/blog/cwtch-bindings-reproducible + Fri, 20 Jan 2023 00:00:00 GMT + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/de/blog/cwtch-stable-api-design + https://docs.cwtch.im/de/blog/cwtch-stable-api-design + Fri, 13 Jan 2023 00:00:00 GMT + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ cwtch + cwtch-stable + planning + api +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/de/blog/path-to-cwtch-stable + https://docs.cwtch.im/de/blog/path-to-cwtch-stable + Fri, 06 Jan 2023 00:00:00 GMT + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+
+
\ No newline at end of file diff --git a/build-staging/de/blog/tags/api/index.html b/build-staging/de/blog/tags/api/index.html new file mode 100644 index 00000000..acb28209 --- /dev/null +++ b/build-staging/de/blog/tags/api/index.html @@ -0,0 +1,24 @@ + + + + + +Ein Beitrag markiert mit "api" | The Cwtch Handbook + + + + + + + + + + + + +
+

Ein Beitrag markiert mit "api"

Alle Schlagwörter anzeigen

· 18 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/autobindings/index.html b/build-staging/de/blog/tags/autobindings/index.html new file mode 100644 index 00000000..7b8ee43e --- /dev/null +++ b/build-staging/de/blog/tags/autobindings/index.html @@ -0,0 +1,25 @@ + + + + + +2 Beiträge markiert mit "autobindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "autobindings"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/bindings/index.html b/build-staging/de/blog/tags/bindings/index.html new file mode 100644 index 00000000..1ca413d8 --- /dev/null +++ b/build-staging/de/blog/tags/bindings/index.html @@ -0,0 +1,25 @@ + + + + + +4 Beiträge markiert mit "bindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 Beiträge markiert mit "bindings"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/cwtch-stable/index.html b/build-staging/de/blog/tags/cwtch-stable/index.html new file mode 100644 index 00000000..534bcd92 --- /dev/null +++ b/build-staging/de/blog/tags/cwtch-stable/index.html @@ -0,0 +1,26 @@ + + + + + +17 Beiträge markiert mit "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 Beiträge markiert mit "cwtch-stable"

Alle Schlagwörter anzeigen

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 2 Minuten Lesezeit
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 Minuten Lesezeit
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/cwtch-stable/page/2/index.html b/build-staging/de/blog/tags/cwtch-stable/page/2/index.html new file mode 100644 index 00000000..101902cd --- /dev/null +++ b/build-staging/de/blog/tags/cwtch-stable/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 Beiträge markiert mit "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 Beiträge markiert mit "cwtch-stable"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 Minuten Lesezeit
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 Minuten Lesezeit
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/cwtch/index.html b/build-staging/de/blog/tags/cwtch/index.html new file mode 100644 index 00000000..a50c18fc --- /dev/null +++ b/build-staging/de/blog/tags/cwtch/index.html @@ -0,0 +1,26 @@ + + + + + +17 Beiträge markiert mit "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 Beiträge markiert mit "cwtch"

Alle Schlagwörter anzeigen

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 2 Minuten Lesezeit
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 Minuten Lesezeit
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/cwtch/page/2/index.html b/build-staging/de/blog/tags/cwtch/page/2/index.html new file mode 100644 index 00000000..5ef3c36b --- /dev/null +++ b/build-staging/de/blog/tags/cwtch/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 Beiträge markiert mit "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 Beiträge markiert mit "cwtch"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 Minuten Lesezeit
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 Minuten Lesezeit
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/developer-documentation/index.html b/build-staging/de/blog/tags/developer-documentation/index.html new file mode 100644 index 00000000..28256364 --- /dev/null +++ b/build-staging/de/blog/tags/developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +2 Beiträge markiert mit "developer-documentation" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "developer-documentation"

Alle Schlagwörter anzeigen

· 2 Minuten Lesezeit
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/documentation/index.html b/build-staging/de/blog/tags/documentation/index.html new file mode 100644 index 00000000..e98adcd5 --- /dev/null +++ b/build-staging/de/blog/tags/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Ein Beitrag markiert mit "documentation" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/index.html b/build-staging/de/blog/tags/index.html new file mode 100644 index 00000000..76e2f97d --- /dev/null +++ b/build-staging/de/blog/tags/index.html @@ -0,0 +1,24 @@ + + + + + +Schlagwörter | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/libcwtch/index.html b/build-staging/de/blog/tags/libcwtch/index.html new file mode 100644 index 00000000..c050aeb3 --- /dev/null +++ b/build-staging/de/blog/tags/libcwtch/index.html @@ -0,0 +1,25 @@ + + + + + +2 Beiträge markiert mit "libcwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "libcwtch"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 Minuten Lesezeit
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/nightly/index.html b/build-staging/de/blog/tags/nightly/index.html new file mode 100644 index 00000000..9b60d1d8 --- /dev/null +++ b/build-staging/de/blog/tags/nightly/index.html @@ -0,0 +1,25 @@ + + + + + +Ein Beitrag markiert mit "nightly" | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/planning/index.html b/build-staging/de/blog/tags/planning/index.html new file mode 100644 index 00000000..7ec80456 --- /dev/null +++ b/build-staging/de/blog/tags/planning/index.html @@ -0,0 +1,24 @@ + + + + + +4 Beiträge markiert mit "planning" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 Beiträge markiert mit "planning"

Alle Schlagwörter anzeigen

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 6 Minuten Lesezeit
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 18 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 Minuten Lesezeit
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/release/index.html b/build-staging/de/blog/tags/release/index.html new file mode 100644 index 00000000..6ae0d47a --- /dev/null +++ b/build-staging/de/blog/tags/release/index.html @@ -0,0 +1,24 @@ + + + + + +2 Beiträge markiert mit "release" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "release"

Alle Schlagwörter anzeigen

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 3 Minuten Lesezeit
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/repliqate/index.html b/build-staging/de/blog/tags/repliqate/index.html new file mode 100644 index 00000000..3e34db32 --- /dev/null +++ b/build-staging/de/blog/tags/repliqate/index.html @@ -0,0 +1,24 @@ + + + + + +2 Beiträge markiert mit "repliqate" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "repliqate"

Alle Schlagwörter anzeigen

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/reproducible-builds/index.html b/build-staging/de/blog/tags/reproducible-builds/index.html new file mode 100644 index 00000000..ff24aee8 --- /dev/null +++ b/build-staging/de/blog/tags/reproducible-builds/index.html @@ -0,0 +1,24 @@ + + + + + +2 Beiträge markiert mit "reproducible-builds" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "reproducible-builds"

Alle Schlagwörter anzeigen

· 8 Minuten Lesezeit
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/security-handbook/index.html b/build-staging/de/blog/tags/security-handbook/index.html new file mode 100644 index 00000000..bcb0f99c --- /dev/null +++ b/build-staging/de/blog/tags/security-handbook/index.html @@ -0,0 +1,24 @@ + + + + + +Ein Beitrag markiert mit "security-handbook" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/support/index.html b/build-staging/de/blog/tags/support/index.html new file mode 100644 index 00000000..869f27e9 --- /dev/null +++ b/build-staging/de/blog/tags/support/index.html @@ -0,0 +1,24 @@ + + + + + +3 Beiträge markiert mit "support" | The Cwtch Handbook + + + + + + + + + + + + +
+

3 Beiträge markiert mit "support"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 Minuten Lesezeit
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

+ + + + \ No newline at end of file diff --git a/build-staging/de/blog/tags/testing/index.html b/build-staging/de/blog/tags/testing/index.html new file mode 100644 index 00000000..97963b8c --- /dev/null +++ b/build-staging/de/blog/tags/testing/index.html @@ -0,0 +1,24 @@ + + + + + +2 Beiträge markiert mit "testing" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 Beiträge markiert mit "testing"

Alle Schlagwörter anzeigen

· 5 Minuten Lesezeit
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

+ + + + \ No newline at end of file diff --git a/build-staging/de/developing/building-a-cwtch-app/building-an-echobot/index.html b/build-staging/de/developing/building-a-cwtch-app/building-an-echobot/index.html new file mode 100644 index 00000000..d1d33808 --- /dev/null +++ b/build-staging/de/developing/building-a-cwtch-app/building-an-echobot/index.html @@ -0,0 +1,25 @@ + + + + + +Building a Cwtch Echobot | The Cwtch Handbook + + + + + + + + + + + + +
+

Building a Cwtch Echobot

In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.

For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or +framework.

Using CwtchBot (Go)

CwtchBot Framework

This tutorial uses the CwtchBot framework.

Start by creating a new Go project, and a file main.go. In the main function:

package main

import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
"fmt"
"git.openprivacy.ca/sarah/cwtchbot"
_ "github.com/mutecomm/go-sqlcipher/v4"
"os/user"
"path"
)

func main() {
user, _ := user.Current()
cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")
cwtchbot.Launch()

// Set Some Profile Information
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")

fmt.Printf("echobot address: %v\n", cwtchbot.Peer.GetOnion())

for {
message := cwtchbot.Queue.Next()
cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])
switch message.EventType {
case event.NewMessageFromPeer:
msg := cwtchbot.UnpackMessage(message.Data[event.Data])
fmt.Printf("Message: %v\n", msg)
reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))
cwtchbot.Peer.SendMessage(cid.ID, reply)
case event.ContactCreated:
fmt.Printf("Auto approving stranger %v %v\n", cid, message.Data[event.RemotePeer])
// accept the stranger as a new contact
cwtchbot.Peer.AcceptConversation(cid.ID)
// Send Hello...
reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))
cwtchbot.Peer.SendMessage(cid.ID, reply)
}
}
}

Using Imp (Rust)

Imp (Rust) Bot Framework

This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.

use std::borrow::BorrowMut;
use std::thread;
use chrono::{DateTime, FixedOffset};
use libcwtch;
use libcwtch::CwtchLib;
use libcwtch::structs::*;
use libcwtch::event::*;
use cwtch_imp::imp;
use cwtch_imp::behaviour::*;
use cwtch_imp::imp::Imp;

const BOT_HOME: &str = "~/.cwtch/bots/echobot";
const BOT_NAME: &str = "echobot";

struct Echobot {}

fn main() {
let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();
let event_loop_handle = thread::spawn(move || {
let mut echobot = Echobot {};
let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());
bot.event_loop::<Echobot>(echobot.borrow_mut());
});
event_loop_handle.join().expect("Error running event loop");
}

impl imp::EventHandler for Echobot {
fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {
let response = Message {
o: MessageType::TextMessage,
d: message.d,
};
cwtch.send_message(&profile.profile_id, conversation_id, &response);
}

fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {
match event {
Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {
println!(
"\n***** {} at {} *****\n",
name, profile_id.as_str()
);
}
_ => (),
};
}
}
+ + + + \ No newline at end of file diff --git a/build-staging/de/developing/building-a-cwtch-app/core-concepts/index.html b/build-staging/de/developing/building-a-cwtch-app/core-concepts/index.html new file mode 100644 index 00000000..32bebf67 --- /dev/null +++ b/build-staging/de/developing/building-a-cwtch-app/core-concepts/index.html @@ -0,0 +1,24 @@ + + + + + +Core Concepts | The Cwtch Handbook + + + + + + + + + + + + +
+

Core Concepts

This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.

Cwtch Home Directory

Often referred to as $CWTCH_HOME, the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application.

Profiles

Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations.

The Event Bus

Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. NewMessageFromPeer and setup an event handler to run code in response to such a message.

For an example see the Echo Bot tutorial.

Settings

Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration.

Experiments

Certain Cwtch features are gated behind experiments. These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all.

+ + + + \ No newline at end of file diff --git a/build-staging/de/developing/building-a-cwtch-app/intro/index.html b/build-staging/de/developing/building-a-cwtch-app/intro/index.html new file mode 100644 index 00000000..921eb248 --- /dev/null +++ b/build-staging/de/developing/building-a-cwtch-app/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Getting Started | The Cwtch Handbook + + + + + + + + + + + + +
+

Getting Started

Choosing A Cwtch Library

Cwtch Go Lib

The official Cwtch library is written in Go and can be found at https://git.openprivacy.ca/cwtch.im/cwtch. This library allows access to all Cwtch functionality.

CwtchBot

We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the building an echobot tutorial.

Autobindings (C-bindings)

The official c-bindings for Cwtch are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI.

libCwtch-rs (Rust)

An experimental rust-fied version of Cwtch Autobindings is available in libCwtch-rs. While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem.

+ + + + \ No newline at end of file diff --git a/build-staging/de/developing/category/building-a-cwtch-app/index.html b/build-staging/de/developing/category/building-a-cwtch-app/index.html new file mode 100644 index 00000000..4edf89e8 --- /dev/null +++ b/build-staging/de/developing/category/building-a-cwtch-app/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Cwtch App erstellen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/developing/intro/index.html b/build-staging/de/developing/intro/index.html new file mode 100644 index 00000000..5f1c1a69 --- /dev/null +++ b/build-staging/de/developing/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Introduction to Cwtch Development | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/developing/release/index.html b/build-staging/de/developing/release/index.html new file mode 100644 index 00000000..2091fcea --- /dev/null +++ b/build-staging/de/developing/release/index.html @@ -0,0 +1,24 @@ + + + + + +Release and Packaging Process | The Cwtch Handbook + + + + + + + + + + + + +
+

Release and Packaging Process

Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.

Automated Testing

Drone carries out a suite of automated tests at various stages of the release pipeline.

Test SuiteRepositoryNotes
Integration Testcwtch.im/cwtchA full exercise of peer-to-peer and group messaging
File Sharing Testcwtch.im/cwtchTests that file sharing and image downloading work as expected
Automated Download Testcwtch.im/cwtchTests that automated image downloading (e.g. profile pictures) work as expected
UI Integration Testcwtch.im/cwtch-uiA suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings

Cwtch Autobindings

Drone produces the following build artifacts for all Cwtch autobindings builds.

Build ArtifactPlatformNotes
android/cwtch-sources.jarAndroidgomobile derived source code for the Android Cwtch library
android/cwtch.aarAndroidAndroid Cwtch library. Supports arm, arm64, and amd64.
linux/libCwtch.hLinuxC header file
linux/libCwtch.soLinuxx64 shared library
windows/libCwtch.hWindowsC header file
windows/libCwtch.dllWindowsx64 bit shared library
macos/libCwtch.arm64.dylibMacOSArm64 shared library
macos/libCwtch.x64.dylibMacOSx64 shared library

UI Nightly Builds

We make unreleased versions of Cwtch available for testing as Cwtch Nightlies.

Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:

Build ArtifactPlatformNotes
cwtch-VERSION.apkAndroidSupports arm, arm64, and amd64. Can be sideloaded.
cwtch-VERSION.aabAndroidAndroid App Bundle for publishing to appstores
Cwtch-VERSION.dmgMacOS
cwtch-VERSION.tar.gzLinuxContains the code, libs, and assets in addition to install scripts for various devices
cwtch-VERSION.zipWindows
cwtch-installer-VERSION.exeWindowsNSIS powered installation wizard

Nightly builds are regularly purged from the system

Official Releases

The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps.

When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. v.1.12.0. The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder.

Reproducible Builds

We use repliqate to provide reproducible build scripts for Cwtch.

We update the repliqate-scripts repository with scripts for all official releases. Currently only Cwtch bindings are reproducible

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/appearance/index.html b/build-staging/de/docs/category/appearance/index.html new file mode 100644 index 00000000..6accacaa --- /dev/null +++ b/build-staging/de/docs/category/appearance/index.html @@ -0,0 +1,24 @@ + + + + + +Darstellung | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/behaviour/index.html b/build-staging/de/docs/category/behaviour/index.html new file mode 100644 index 00000000..ba7edfb9 --- /dev/null +++ b/build-staging/de/docs/category/behaviour/index.html @@ -0,0 +1,24 @@ + + + + + +Verhalten | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/contribute/index.html b/build-staging/de/docs/category/contribute/index.html new file mode 100644 index 00000000..937c023b --- /dev/null +++ b/build-staging/de/docs/category/contribute/index.html @@ -0,0 +1,24 @@ + + + + + +Mitwirken | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/conversations/index.html b/build-staging/de/docs/category/conversations/index.html new file mode 100644 index 00000000..f0b76470 --- /dev/null +++ b/build-staging/de/docs/category/conversations/index.html @@ -0,0 +1,24 @@ + + + + + +Konversationen | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/experiments/index.html b/build-staging/de/docs/category/experiments/index.html new file mode 100644 index 00000000..7108c39a --- /dev/null +++ b/build-staging/de/docs/category/experiments/index.html @@ -0,0 +1,24 @@ + + + + + +Experimentelle Funktionen | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/getting-started/index.html b/build-staging/de/docs/category/getting-started/index.html new file mode 100644 index 00000000..d28aabeb --- /dev/null +++ b/build-staging/de/docs/category/getting-started/index.html @@ -0,0 +1,24 @@ + + + + + +Erste Schritte | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/groups/index.html b/build-staging/de/docs/category/groups/index.html new file mode 100644 index 00000000..7cadb6ec --- /dev/null +++ b/build-staging/de/docs/category/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Gruppen | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/platforms/index.html b/build-staging/de/docs/category/platforms/index.html new file mode 100644 index 00000000..134492f4 --- /dev/null +++ b/build-staging/de/docs/category/platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Plattformen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/profiles/index.html b/build-staging/de/docs/category/profiles/index.html new file mode 100644 index 00000000..97873c52 --- /dev/null +++ b/build-staging/de/docs/category/profiles/index.html @@ -0,0 +1,24 @@ + + + + + +Profile | The Cwtch Handbook + + + + + + + + + + + + +
+

Profile

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/servers/index.html b/build-staging/de/docs/category/servers/index.html new file mode 100644 index 00000000..43485eaa --- /dev/null +++ b/build-staging/de/docs/category/servers/index.html @@ -0,0 +1,24 @@ + + + + + +Server | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/category/settings/index.html b/build-staging/de/docs/category/settings/index.html new file mode 100644 index 00000000..1d0796bb --- /dev/null +++ b/build-staging/de/docs/category/settings/index.html @@ -0,0 +1,24 @@ + + + + + +Einstellungen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/accept-deny-new-conversation/index.html b/build-staging/de/docs/chat/accept-deny-new-conversation/index.html new file mode 100644 index 00000000..52015a7d --- /dev/null +++ b/build-staging/de/docs/chat/accept-deny-new-conversation/index.html @@ -0,0 +1,24 @@ + + + + + +Neue Konversationen akzeptieren/ablehnen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/add-contact/index.html b/build-staging/de/docs/chat/add-contact/index.html new file mode 100644 index 00000000..fef1db44 --- /dev/null +++ b/build-staging/de/docs/chat/add-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Neues Gespräch beginnen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/block-contact/index.html b/build-staging/de/docs/chat/block-contact/index.html new file mode 100644 index 00000000..3f9c55a4 --- /dev/null +++ b/build-staging/de/docs/chat/block-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Einen Kontakt blockieren | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/conversation-settings/index.html b/build-staging/de/docs/chat/conversation-settings/index.html new file mode 100644 index 00000000..ddfde512 --- /dev/null +++ b/build-staging/de/docs/chat/conversation-settings/index.html @@ -0,0 +1,24 @@ + + + + + +Konversationseinstellungen aufrufen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/delete-contact/index.html b/build-staging/de/docs/chat/delete-contact/index.html new file mode 100644 index 00000000..77e5f947 --- /dev/null +++ b/build-staging/de/docs/chat/delete-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Entfernen einer Konversation | The Cwtch Handbook + + + + + + + + + + + + +
+

Entfernen einer Konversation

Warnung

Diese Funktion wird unwiderruflich löschen. Dieses kann nicht rückgängig gemacht werden.

  • In einem Chat mit Kontakt, gehe in die Konversationseinstellungen oben rechts
  • Scrolle zum Verlasse diese Konversation und drücken darauf.
  • Sie wirst aufgefordert zu bestätigen, wenn du die Unterhaltung verlassen möchtest. Diese Aktion kann nicht rückgängig gemacht werden.
info Info

Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem du es mit vergrößerst.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/introduction/index.html b/build-staging/de/docs/chat/introduction/index.html new file mode 100644 index 00000000..8c1bf1b4 --- /dev/null +++ b/build-staging/de/docs/chat/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Einführung in die Cwtch P2P Chat | The Cwtch Handbook + + + + + + + + + + + + +
+

Eine Einführung in die Cwtch P2P Chat

Cwtch benutzt Tor v3 Onion Dienste, um anonyme, Peer-to-Peer-Verbindungen zwischen Profilen herzustellen.

Wie P2P-Chat unter der Haube funktioniert

Um mit deinen Freunden in einem Peer-to-Peer-Gespräch zu chatten, müssen beide online sein.

Nach einer erfolgreichen Verbindung beteiligen sich beide Seiten an einem -Authentifizierungsprotokoll von:

  • Behauptet, dass jede Seite Zugang zu dem privaten Schlüssel hat, der mit ihrer öffentlichen Identität verbunden ist.
  • Erzeugt einen ephemeren Session-Schlüssel, der zur Verschlüsselung aller weiteren Kommunikation während der Sitzung verwendet wird.

Dieser Austausch (detailliert im -Authentifizierungsprotokolldokumentiert) ist offline verweigerbar d. h. es ist möglich für jede Seite Transkripte dieses Protokoll-Auszutausches zu fälschen und daher ist es unmöglich definitiv zu beweisen, dass der Austausch überhaupt stattgefunden hat.

Sobald der Authentifizierungsprozess erfolgreich ist, kannst Du und dein Freund sicher sein, dass niemand anderes etwas über den Inhalt oder die Metadaten eurer Konversation erfahren kann.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/message-formatting/index.html b/build-staging/de/docs/chat/message-formatting/index.html new file mode 100644 index 00000000..4a08f6c0 --- /dev/null +++ b/build-staging/de/docs/chat/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Nachrichtenformatierung | The Cwtch Handbook + + + + + + + + + + + + +
+

Nachrichtenformatierung

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Nachrichten Formatierung Experiment eingeschaltet ist.

Optional kannst du Klickbare Links aktivieren, um URLs in Nachrichten in Cwtch anklickbar zu machen.

Cwtch unterstützt zur Zeit folgende Formatierungsmarkierungen für Nachrichten:

  • **bold** welches fett rendern wird
  • *italic* welches kursiv rendern wird
  • code welches code rendern wird
  • ^superscript^ das superscript rendern wird
  • _subscript_ welches subscript rendern wird
  • ~~strikthrough~~ welches strikethrough rendern wird
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/reply-to-message/index.html b/build-staging/de/docs/chat/reply-to-message/index.html new file mode 100644 index 00000000..59f00b1c --- /dev/null +++ b/build-staging/de/docs/chat/reply-to-message/index.html @@ -0,0 +1,24 @@ + + + + + +Auf eine Nachricht antworten | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/save-conversation-history/index.html b/build-staging/de/docs/chat/save-conversation-history/index.html new file mode 100644 index 00000000..814f1a3a --- /dev/null +++ b/build-staging/de/docs/chat/save-conversation-history/index.html @@ -0,0 +1,24 @@ + + + + + +Gesprächsverlauf speichern | The Cwtch Handbook + + + + + + + + + + + + +
+

Gesprächsverlauf speichern

Standardmäßig speichert Cwtch aus Gründen der Privatsphäre keine Unterhaltungshistorie zwischen den Sitzungen.

Um den Verlauf für eine bestimmte Konversation zu aktivieren:

  1. Gehe in einem Konversationsfenster zu Einstellungen
  2. Gehe zu Verlauf speichern
  3. Klicke das Dropdown-Menü
  4. Verlauf speichern auswählen
  5. Jetzt wird dein Verlauf gespeichert

Die Konversationshistorie kann an jedem beliebigen Punkt abgeschaltet werden, indem du im Dropdown-Menü "Verlauf löschen" auswählst.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/share-address-with-friends/index.html b/build-staging/de/docs/chat/share-address-with-friends/index.html new file mode 100644 index 00000000..a187dac8 --- /dev/null +++ b/build-staging/de/docs/chat/share-address-with-friends/index.html @@ -0,0 +1,24 @@ + + + + + +Teilen von Cwtch Adressen | The Cwtch Handbook + + + + + + + + + + + + +
+

Teilen von Cwtch Adressen

Es gibt viele Möglichkeiten, eine Cwtch Adresse zu teilen.

Teilen deiner Cwtch Adresse

  1. Zu deinem Profil gehen
  2. Klicke auf das Kopiere-Adresse-Symbol

Du kannst diese Adresse nun teilen. Personen mit dieser Adresse können dich als Cwtch Kontakt hinzufügen.

Für Informationen zum Blockieren von Verbindungen von Personen, die du nicht kennst, lies bitte Einstellungen: Unbekannte Verbindungen blockieren

Teilen der Cwtch Adresse von Freunden

Innerhalb von Cwtch gibt es einen weiteren Mechanismus zum Austausch von Cwtch-Adressen.

info Info

Diese Dokumentationsseite ist ein Muster. Du kannst helfen, indem du es mit vergrößerst.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/share-file/index.html b/build-staging/de/docs/chat/share-file/index.html new file mode 100644 index 00000000..aa340189 --- /dev/null +++ b/build-staging/de/docs/chat/share-file/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Datei teilen | The Cwtch Handbook + + + + + + + + + + + + +
+

Eine Datei teilen

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Datei Teilen Experiment eingeschaltet ist.

Optional kannst du Bilder und Profilbilder Vorschau aktivieren, um geteilte Bilder als Vorschau im Konversationsfenster zu sehen.

In einer Konversation

  1. Klicke auf das Anhang-Symbol
  2. Finde die Datei, die du senden möchtest
  3. Bestätige, dass du es senden möchtest

Wie funktioniert das Teilen von Dateien mit Gruppen? Sind meine Dateien irgendwo auf einem Server gespeichert?

Dateien werden über onion-to-onion Cwtch Verbindungen direkt von der Person verschickt, die die Datei dem Empfänger anbietet. Das ursprüngliche Angebot zum Senden einer Datei wird als Standard Cwtch Konversation/Overlay-Nachricht veröffentlicht. Für Gruppen bedeutet dies, dass das ursprüngliche Angebot (welches den Dateinamen, die Größe, Hash und eine Nonce beinhaltet) auf den Gruppenserver gestellt wird aber dann verbindet sich jeder Empfänger zu dir, um den eigentlichen Dateiinhalt zu erhalten.

Muss ich somit online sein, um eine Datei zu senden?

Ja. Wenn die Person, die die Datei anbietet, offline geht, musst du warten, bis sie online kommt, um die Übertragung fortzusetzen. Das zugrunde liegende Protokoll teilt die Dateien in einzelne, überprüfbare Chunks, so dass Sie in einer zukünftigen Version eine Datei "rehosten" können, die in einer Gruppe veröffentlicht wird und sogar Download von mehreren Hosts auf einmal (eine Art von Bittorrent) möglich sein wird.

Warum tauchen neue Kontakte in meiner Liste auf?

Dies ist darauf zurückzuführen, wie Cwtch derzeit Verbindungen von unbekannten Adressen behandelt. Da eine Datei in eine Gruppe geschrieben wird, führt dies dazu, dass Gruppenmitglieder sich direkt mit dir verbinden, einige dieser Mitglieder befinden sich möglicherweise noch nicht in deiner Kontaktliste, so dass deren Downloadverbindung zu dir als Kontaktanfrage in deiner Liste erscheint.

Was heißt "SHA512"?

SHA512 ist ein kryptographischer Hash der verwendet werden kann, um zu überprüfen, dass die heruntergeladene Datei eine korrekte Kopie der angebotenen Datei ist. Cwtch macht diese Verifizierung automatisch, aber du bist herzlich eingeladen, es selbst auszuprobieren! Beachte, dass wir auch ein zufälliges nonce in Datei-Angeboten einschließen, so dass die Leute dich nicht einfach nach einem zufälligen Hash fragen können, den du haben kannst, oder Dateien aus Unterhaltungen, von denen sie nicht selber dabei sind.

Gibt es eine Begrenzung der Dateigröße?

Das aktuelle Limit beträgt 10 Gigabytes pro Datei.

Was sind diese .manifest Dateien?

Die .manifest-Dateien werden beim Herunterladen der Datei verwendet, um zu überprüfen, ob einzelne Chunks korrekt empfangen werden, und um die Fortsetzung der unterbrochenen Übertragung zu unterstützen. Sie enthalten auch die Informationen aus dem ursprünglichen Datei-Angebot. Du kannst diese sicher löschen, sobald der Download abgeschlossen ist. Auf Android werden die Manifeste im Cache der App gespeichert und können über die Systemeinstellungen gelöscht werden.

Was ist mit den Datei-Metadaten?

Wir schicken den Namen der Datei als Vorschlag und um zu helfen, die Datei von anderen Dateiangeboten zu unterscheiden. Vor dem Absenden des Angebots wird der gesamte Pfad abgeschnitten. Du solltest dich vor versteckten Metadaten hüten, die in der Datei selbst gespeichert sein könnten, was je nach Dateiformat variiert. Zum Beispiel können Bilder Geo-Lokationen und Informationen über die Kamera enthalten, die sie aufgenommen haben und PDF-Dateien sind dafür berüchtigt, versteckte Informationen wie den Namen des Autors oder die Maschine, auf der sie erstellt wurden, zu enthalten. Im Allgemeinen solltest du nur Dateien mit Leuten senden und empfangen, denen du vertraust.

Kann ich Dateien automatisch herunterladen?

Wenn das Bild-Vorschau und Profilbilder Experiment aktiviert ist, wird Cwtch automatisch Bilder von akzeptierten Unterhaltungen herunterladen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/chat/unblock-contact/index.html b/build-staging/de/docs/chat/unblock-contact/index.html new file mode 100644 index 00000000..62357ec1 --- /dev/null +++ b/build-staging/de/docs/chat/unblock-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Einen Kontakt entsperren | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/contribute/developing/index.html b/build-staging/de/docs/contribute/developing/index.html new file mode 100644 index 00000000..63b7dc9e --- /dev/null +++ b/build-staging/de/docs/contribute/developing/index.html @@ -0,0 +1,24 @@ + + + + + +Entwicklung von Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Entwicklung von Cwtch

Dieser Abschnitt dokumentiert einige Möglichkeiten, um mit der Cwtch-Entwicklung zu beginnen.

Cwtch-Fehlerverfolgungsprozess

Alle Cwtch-Probleme werden aus dem cwtch-ui git Repositoryverfolgt, auch wenn der Fehler / das Feature in einer Upstream-Bibliothek entsteht. Dies erlaubt uns, alles an einem Ort zu halten.

Probleme sind in 4 verschiedene Kategorien unterteilt:

  • Unbearbeitete - Dies sind neue Probleme, die vom Cwtch Team nicht diskutiert wurden.
  • Geplant - Diese Probleme wurden für eine kommende Veröffentlichung eingeplant. Normalerweise werden sie mit der Release Version getaggt, in der sie voraussichtlich in cwtch-1.11 behoben werden. Ein Kern-Cwtch-Team-Mitglied arbeitet wahrscheinlich an diesem Problem oder wird in den nächsten Wochen an diesem Thema arbeiten.
  • Gewünscht - Dies sind Probleme, die wir gerne beheben würden, aber aus irgendeinem Grund können wir diese nicht planen. Dies könnte daran liegen, dass die Funktion groß ist und viel Aufwand erfordert, oder weil es einen Blocker gibt (z.B. Eine fehlende Funktion in Flutter oder einer anderen Bibliothek), die die Arbeit an der Funktion verhindert.
  • Hilfe gesucht - Dies sind in der Regel kleine Probleme, die wir gerne beheben würden, die aber als geringe Priorität eingestuft wurden. Dies sind ideale erste Probleme für Freiwillige.

Wenn du an einem offenen Fehler/Feature arbeiten möchtest, bitte kommentiere das Problem und ein Mitglied des Cwtch Teams wird dir Ratschläge geben, wohin du von dort gehen solltest. Dies hilft uns, den Überblick zu behalten, wer an welchen Problemen arbeitet, und reduziert den Umfang der doppelten Arbeit. Wir sind bestrebt, die meisten Anfragen innerhalb von 24 Stunden zu beantworten, fühle dich frei, an ein Problem zu "erinnern", wenn es länger als diese Zeit dauert.

Hinweis

Aufgrund eines Problems mit unserem E-Mail-Provider sind wir derzeit nicht in der Lage, E-Mails von unserer gitea-Instanz zu versenden. Bitte überprüfe regelmäßig offene Probleme / Pull-Requests auf Updates (oder abonniere die RSS-Feeds des Projektarchivs)

Cwtch Pull-Request Prozess

Alle Pull-Requests müssen von einem Kernmitglied des Cwtch Teams überprüft und genehmigt werden, bevor das Zusammenführen erfolgt. Sarah prüft alle neuen und aktiven Pull-Anfragen mehrmals in der Woche.

Bot bauen

Alle Cwtch Projekte werden mit automatisierten Builds und Tests eingerichtet. Es wird erwartet, dass jeder Pull-Request diese Pipelines durchlaufen kann, bevor er zusammengeführt wird. Wenn buildbot einen Fehler meldet, dann wird Sarah mit dir zusammenarbeiten, um das Problem und alle notwendigen Korrekturen zu ermitteln.

Der Buildbot kann aus Gründen, die außerhalb deiner Kontrolle liegen, fehlschlagen, z.B. viele unserer Integrationstests sind auf das Einrichten von Tor-Verbindungen angewiesen, diese können gelegentlich spröde sein und zu Timeouts und Fehlern führen. Bestätige immer die Hauptursache für einen Testfehler, bevor du entscheidest, was als nächstes zu tun ist.

Nützliche Ressourcen

Hinweis

Alle Beiträge sind berechtigt für Aufkleber

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/contribute/documentation/index.html b/build-staging/de/docs/contribute/documentation/index.html new file mode 100644 index 00000000..2db3b864 --- /dev/null +++ b/build-staging/de/docs/contribute/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Stilregeln der Dokumentation | The Cwtch Handbook + + + + + + + + + + + + +
+

Stilregeln der Dokumentation

Dieser Abschnitt dokumentiert die erwartete Struktur und Qualität der Cwtch-Dokumentation.

Screenshots und Übertragung von Zeichen

Die meisten Cwtch-Dokumentationen sollte mindestens einen Screenshot oder ein animiertes Bild enthalten. Screenshots der Cwtch-Anwendung sollten sich auf die in der Dokumentation beschriebene Funktion konzentrieren.

Um die Konsistenz zwischen Screenshots zu gewährleisten, schlagen wir vor, dass das betreffende Profil besonderen, konstanten und Rollen dienen sollte.

  • Alice - wird verwendet, um das primäre Profil zu repräsentieren.
  • Bob - der primäre Kontakt, nützlich bei der Darstellung von Peer-to-Peer-Funktionen
  • Carol - ein sekundärer Kontakt, nützlich bei der Darstellung von Gruppenfunktionen
  • Mallory - stellt einen böswilligen Partner dar (welcher verwendet wird, um die Blockierfunktionalität zu demonstrieren)

Dialog und Inhalt

Wo Screenshots und Demonstrationen Dialog, Gespräche und/oder Bilder zeigen, halte bitte die Gespräche kurz zu einem lässigen Thema. Beispiele dafür sind:

  • Organisieren eines Picknicks
  • Teilen von Fotos aus einem Urlaub
  • Senden des Dokuments zur Prüfung

Experimente

Alle Funktionen, die auf die Aktivierung eines Experiments angewiesen sind, sollten dies alles oben auf der Seite hervorheben z. B.:

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Beispiel Experiment eingeschaltet ist.

Risiko

Wenn eine Funktion zur Zerstörung des Schlüsselmaterials oder zur dauerhaften Löschung des Status führen könnte dann sollten diese auch oben in der Dokumentation aufgerufen werden, z. B.:

Warnung

Diese Funktion wird das Schlüsselmaterial unwiderruflich löschen. Dieses kann nicht rückgängig gemacht werden.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/contribute/stickers/index.html b/build-staging/de/docs/contribute/stickers/index.html new file mode 100644 index 00000000..144c35b4 --- /dev/null +++ b/build-staging/de/docs/contribute/stickers/index.html @@ -0,0 +1,24 @@ + + + + + +Aufkleber | The Cwtch Handbook + + + + + + + + + + + + +
+

Aufkleber

Alle Beiträge sind für Aufkleber berechtigt. Wenn du zu Bugs, Features, Testen oder Sprache beiträgst oder in der Vergangenheit einen wesentlichen Beitrag geleistet hast, schreibe bitte eine E-Mail an erinn@openprivacy. mit Details und einer Adresse für uns, damit wir die Aufkleber dir schicken können.

Ein Foto von Cwtch-Aufklebern

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/contribute/testing/index.html b/build-staging/de/docs/contribute/testing/index.html new file mode 100644 index 00000000..b712b103 --- /dev/null +++ b/build-staging/de/docs/contribute/testing/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch testen | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch testen

Dieser Abschnitt dokumentiert einige Möglichkeiten, um mit Cwtch-Tests zu beginnen.

Laufender Fuzzbot

FuzzBot ist unser Entwicklungs-Testbot. Du kannst FuzzBot als Kontakt hinzufügen: cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad.

FuzzBot Hilfe

Wenn Du FuzzBot eine Hilfe- Nachricht sendest, werden alle derzeit verfügbaren Testbefehle angezeigt.

Weitere Informationen über FuzzBot findest Du in unserem Discreet Log Development Blog.

Trete der Cwtch Release Candidate Tester Gruppe bei

Wenn Du Fuzzbot den Befehl testgroup-invite sendest, lädt FuzzBot Dich zur Cwtch Testers Group ein! Dort kannst du Fragen stellen, Fehlerberichte schreiben und Feedback geben.

Cwtch Nightlies

Cwtch Nightly Builds sind Entwicklungs-Builds, die neue Features enthalten, die zum Testen bereit sind.

Die aktuellsten Entwicklungsversionen von Cwtch sind auf unserem Build-Server verfügbar.

Wir empfehlen nicht, dass Tester immer auf die neueste Nightly aktualisieren, sondern wir werden eine Nachricht an die Cwtch Release Candidate Testers Gruppe schicken, wenn eine bedeutsame Nightly verfügbar wird. Eine Nightly wird als bedeutsam angesehen, wenn sie eine neue Funktion oder eine größere Fehlerbehebung enthält.

Hinweis

Alle Beiträge sind berechtigt für Aufkleber

Feedback abgeben

Es gibt drei wichtige Möglichkeiten, Test-Feedback an das Team zu übermitteln:

  • Über Cwtch: Entweder über die Release Candidate Tester Gruppe oder direkt über ein Cwtch Team-Mitglied.
  • Via Gitea: Bitte öffne ein Problem unter https://git.openprivacy.ca/cwtch. m/cwtch-ui/issues - Bitte mache dir keine Gedanken über doppelte Probleme, wir werden doppelte Probleme als Teil unseres Triage Prozesses entfernen.
  • Per E-Mail: E-Mail team@cwtch.im mit dem Fehlerbericht und eines unserer Teams wird ihn prüfen.
Hinweis

Aufgrund eines Problems mit unserem E-Mail-Provider sind wir derzeit nicht in der Lage, E-Mails von unserer gitea-Instanz zu versenden. Bitte überprüfe regelmäßig offene Probleme / Pull-Requests auf Updates (oder abonniere die RSS-Feeds des Projektarchivs)

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/contribute/translate/index.html b/build-staging/de/docs/contribute/translate/index.html new file mode 100644 index 00000000..17db8011 --- /dev/null +++ b/build-staging/de/docs/contribute/translate/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch übersetzen | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch übersetzen

Wenn du Übersetzungen zu Cwtch beitragen möchtest, entweder zur App oder zu diesem Handbuch, kommt hier wie dies möglich ist.

Übersetzungen zur Cwtch-Anwendung beitragen

Es gibt zwei Möglichkeiten, zu Cwtch Anwendungen beizutragen.

Trete unserem Lokalise-Team bei

Wir verwenden Lokalise für die Verwaltung von Übersetzungen für die Cwtch-Anwendung.

  1. Registriere dich für ein Lokalise-Konto
  2. Sende eine E-Mail an team@cwtch.im mit der Sprache, die du übersetzen möchtest und einer E-Mail-Adresse, mit der wir dich in unser Lokalise-Team einladen können.

Direkt über Git

Für neue Übersetzungen, kannst du eine Kopie von https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb erstellen und übersetzen - Du kannst dann entweder Pull-Requests einreichen oder direkt Aktualisierungen an uns senden (team@cwtch.im) und wir werden sie zusammenführen.

Um zu existierenden Übersetzungen hinzuzufügen, kannst du Pull-Requests direkt auf jede Datei in https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/ einstellen und wir werden sie überprüfen und zusammenführen.

Cwtch-Benutzerhandbuch

Dieses Handbuch wird über Crowdin übersetzt.

Um unserem Crowdin-Projekt beizutreten:

  1. Registrieren dich für ein Konto bei Crowdin.
  2. Treten dem cwtch-users-handbook Projekt bei.

Wir bündeln Änderungen an der Dokumentation in Batches und synchronisieren sie regelmäßig mit dem Crowdin-Projekt.

Hinweis

Alle Beiträge sind berechtigt für Aufkleber

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/getting-started/supported_platforms/index.html b/build-staging/de/docs/getting-started/supported_platforms/index.html new file mode 100644 index 00000000..4d7aa750 --- /dev/null +++ b/build-staging/de/docs/getting-started/supported_platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Unterstützte Platformen | The Cwtch Handbook + + + + + + + + + + + + +
+

Unterstützte Platformen

Die folgende Tabelle stellt unser aktuelles Verständnis von Cwtch-Unterstützung auf verschiedenen Betriebssystemen und Architekturen dar (Stand Cwtch 1.10 und Januar 2023).

In vielen Fällen suchen wir nach Testern, die bestätigen, dass verschiedene Funktionen funktionieren. Wenn du daran interessiert bist, Cwtch auf einer bestimmten Plattform zu testen oder als freiwilliger Helfer bei der offiziellen Unterstützung einer hier nicht aufgelisteten Plattform helfen möchtest, dann schaue dir Beitragen zu Cwtch an.

Legende:

  • ✅: Offiziell unterstützt. Cwtch sollte auf diesen Plattformen ohne Probleme funktionieren. Regressionen werden als hohe Priorität behandelt.
  • 🟡: Beste Anstrengung zur Unterstützung. Cwtch sollte auf diesen Plattformen funktionieren, aber es kann dokumentierte oder unbekannte Probleme geben. Es kann notwendig sein, Tests durchzuführen. Einige Funktionen erfordern möglicherweise zusätzliche Arbeit. Freiwilligenarbeit wird gewürdigt.
  • ❌: Nicht unterstützt. Cwtch wird wahrscheinlich nicht auf diesen Systemen funktionieren. Wir werden vermutlich keine Fehlerberichte für diese Systeme akzeptieren.
PlattformOffizielle Cwtch BuildsQuellencode-UnterstützungAnmerkungen
Windows 11Nur 64-Bit amd64.
Windows 10Nur 64-Bit amd64. Nicht offiziell unterstützt, aber offizielle Builds könnten funktionieren.
Windows 8 und darunter🟡Nicht unterstützt. Dedizierte Builds aus dem Quellcode könnten funktionieren. Testen erforderlich.
OSX 10 und darunter🟡Nur 64-Bit. Offizielle Builds sollen auf Catalina funktionieren, aber nicht auf High Sierra
OSX 11Nur 64-Bit. Offizielle Builds unterstützen sowohl arm64 als auch x86 Architekturen.
OSX 12Nur 64-Bit. Offizielle Builds unterstützen sowohl arm64 als auch x86 Architekturen.
OSX 13Nur 64-Bit. Offizielle Builds unterstützen sowohl arm64 als auch x86 Architekturen.
Debian 11Nur 64-Bit amd64.
Debian 10🟡Nur 64-Bit amd64.
Debian 9 und darunter🟡Nur 64-Bit amd64. Builds aus dem Quellcode sollten funktionieren, aber offizielle Builds könnten mit installierten Abhängigkeiten inkompatibel sein.
Ubuntu 22.04Nur 64-Bit amd64.
Andere Ubuntu🟡Nur 64-Bit. Testen erforderlich. Builds aus dem Quellcode sollten funktionieren, aber offizielle Builds könnten mit installierten Abhängigkeiten inkompatibel sein.
CentOS🟡🟡Testen erforderlich.
Gentoo🟡🟡Testen erforderlich.
Arch🟡🟡Testen erforderlich.
Whonix🟡🟡Bekannte Probleme. Für die Unterstützung sind spezielle Änderungen an Cwtch erforderlich.
Raspian (arm64)🟡Builds aus dem Quellcode erstellt, funktionieren.
Andere Linux-Distributionen🟡🟡Testen erforderlich.
Android 9 und darunter🟡🟡Offizielle Builds könnten funktionieren.
Android 10Offizielle SDK unterstützen arm, arm64 und amd64 Architekturen.
Android 11Offizielle SDK unterstützen arm, arm64 und amd64 Architekturen.
Android 12Offizielle SDK unterstützen arm, arm64 und amd64 Architekturen.
Android 13Offizielle SDK unterstützen arm, arm64 und amd64 Architekturen.
LineageOSOffizielle SDK unterstützen arm, arm64 und amd64 Architekturen.
Andere Android Distributionen🟡🟡Testen erforderlich.
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/accept-group-invite/index.html b/build-staging/de/docs/groups/accept-group-invite/index.html new file mode 100644 index 00000000..fb615277 --- /dev/null +++ b/build-staging/de/docs/groups/accept-group-invite/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Gruppeneinladung annehmen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/create-group/index.html b/build-staging/de/docs/groups/create-group/index.html new file mode 100644 index 00000000..8b38b4e5 --- /dev/null +++ b/build-staging/de/docs/groups/create-group/index.html @@ -0,0 +1,24 @@ + + + + + +Eine neue Gruppe erstellen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/edit-group-name/index.html b/build-staging/de/docs/groups/edit-group-name/index.html new file mode 100644 index 00000000..35eccc89 --- /dev/null +++ b/build-staging/de/docs/groups/edit-group-name/index.html @@ -0,0 +1,24 @@ + + + + + +Einen Gruppennamen bearbeiten | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/introduction/index.html b/build-staging/de/docs/groups/introduction/index.html new file mode 100644 index 00000000..0b085ac6 --- /dev/null +++ b/build-staging/de/docs/groups/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Einführung in die Cwtch Gruppen | The Cwtch Handbook + + + + + + + + + + + + +
+

Eine Einführung in die Cwtch Gruppen

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.

Hinweis: Metadaten resistente Kommunikation ist noch ein aktives Entwicklungsfeld und was hier dokumentiert ist wird sehr wahrscheinlich in der Zukunft sich ändern.

Standardmäßig unterstützt Cwtch nur Peer-to-Peer online Chats. Um Mehrparteien-Gespräche zu unterstützen und Offline-Auslieferung zu ermöglichen, ist ein (nicht vertrauenswürdiger) Dritter erforderlich. Wir nennen diese Entitäten (Dritten) "Server"

Diese Server können von jedem eingerichtet werden und sind dafür gedacht, immer online zu sein. Am wichtigsten ist, dass die Kommunikation mit einem Server so gestaltet ist, dass der Server so wenig Informationen wie möglich über den Inhalt oder die Metadaten erfährt.

In vielerlei Hinsicht ist die Kommunikation mit einem Server identisch mit einer regulären Cwtch Peer, alle Schritte werden gleich unternommen, aber der Server fungiert immer als eingehender Peer, und der ausgehende Peer verwendet immer neu generierte ephemere (flüchtige) Schlüsselpaare - so dass jede Serversitzung getrennt wird.

Somit unterscheidet sich die Peer zu Server Konversation nur in der Art der Nachrichten, die zwischen zwei Seiten gesendet werden, mit dem Server, der alle Nachrichten, die er erhält, speichert und damit den Clients erlaubt den Server nach älteren Nachrichten abzufragen.

Das mit Servern verbundene Risikomodell ist komplizierter als Peer-to-Peer-Kommunikation, da wir derzeit Leute benötigen, die Server in Cwtch mit opt-in zum Gruppen-Chat-Experiment verwenden möchten um auf nicht vertrauenswürdigen Servern Gruppen hinzuzufügen, zu verwalten und zu erstellen.

Wie Gruppen unter der Haube funktionieren

Wenn eine Person eine Gruppendiskussion starten will, generiert sie einen zufälligen geheimen Gruppenschlüssel. Alle Gruppenkommunikation wird mit diesem Schlüssel verschlüsselt.

Zusammen mit dem Gruppenschlüssel entscheidet der Gruppenersteller sich auch für einen Cwtch Server als Host der Gruppe zu verwenden. Weitere Informationen darüber, wie Server sich selbst authentifizieren, findest du unter Schlüsselbündel.

Ein Gruppen Identifikator wird mit dem Gruppenschlüssel und dem Gruppenserver generiert und diese drei Elemente sind in einer Einladung verpackt, die an potenzielle Gruppenmitglieder gesendet werden kann (z.B. über existierende Peer-to-Peer-Verbindungen).

Um eine Nachricht an die Gruppe zu senden, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt (siehe unten), und verschlüsselt deine Nachricht mit dem Gruppenschlüssel `und erzeugt eine kryptographische Signatur über dieGruppen-Id, Gruppen Server` und die entschlüsselte Nachricht (siehe: Nachrichtenformate für weitere Informationen).

Um Nachrichten von der Gruppe zu erhalten, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt und lädt alle Nachrichten (seit ihrer vorherigen Verbindung) herunter. Die Profile versuchen dann jede Nachricht mit dem Gruppenschlüssel und wenn dies erfolgreich war, dann die Signatur zu verifizieren (siehe Cwtch Server Cwtch Groupen für einen Überblick über Attacken und Abschwächungen).

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/leave-group/index.html b/build-staging/de/docs/groups/leave-group/index.html new file mode 100644 index 00000000..49b7e0c0 --- /dev/null +++ b/build-staging/de/docs/groups/leave-group/index.html @@ -0,0 +1,24 @@ + + + + + +Wie man eine Gruppe verlässt? | The Cwtch Handbook + + + + + + + + + + + + +
+

Wie man eine Gruppe verlässt?

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.

Warnung

Diese Funktion wird das Schlüsselmaterial unwiderruflich löschen. Dieses kann nicht rückgängig gemacht werden.

  1. Gehen Sie im Chat-Fenster zu den Einstellungen
  2. Im Einstellungsfenster nach unten scrollen
  3. Drücke auf Konversation verlassen
  4. Bestätige, dass du verlassen möchtest
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/manage-known-servers/index.html b/build-staging/de/docs/groups/manage-known-servers/index.html new file mode 100644 index 00000000..2cd489be --- /dev/null +++ b/build-staging/de/docs/groups/manage-known-servers/index.html @@ -0,0 +1,24 @@ + + + + + +Server verwalten | The Cwtch Handbook + + + + + + + + + + + + +
+

Server verwalten

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Gruppen Experiment eingeschaltet ist.

Cwtch Gruppen werden von nicht vertrauenswürdigen Servern gehostet. Wenn du die Server sehen möchtest, über die du kennst, ihren Status und die auf ihnen gehosteten Gruppen:

  1. In deinem Kontakt-Bereich
  2. Zum Server verwalten Symbol gehen

Import lokal gehosteter Server

  1. Um einen lokal gehosteten Server zu importieren klicke auf lokalen Server auswählen
  2. Wähle den gewünschten Server aus
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/groups/send-invite/index.html b/build-staging/de/docs/groups/send-invite/index.html new file mode 100644 index 00000000..dd3f8c02 --- /dev/null +++ b/build-staging/de/docs/groups/send-invite/index.html @@ -0,0 +1,24 @@ + + + + + +Einladungen an eine Gruppe senden | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/intro/index.html b/build-staging/de/docs/intro/index.html new file mode 100644 index 00000000..4018d638 --- /dev/null +++ b/build-staging/de/docs/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Was ist Cwtch? | The Cwtch Handbook + + + + + + + + + + + + +
+

Was ist Cwtch?

Cwtch (/kʊtʃ/ - ein walisisches Wort, das grob übersetzt „eine Umarmung, die einen sicheren Ort schafft“ bedeutet) ist eine dezentralisierte, Privatspähre bewahrende, metadatenresistente Messenger-App.

  • Dezentralisiert und offen: Es gibt keinen „Cwtch-Dienst“ oder „Cwtch-Netzwerk“. Die Cwtch Teilnehmer können ihre eigenen sicheren Räume hosten oder ihre Infrastruktur anderen anbieten, die auf der Suche nach einem sicheren Raum sind. Das Cwtch-Protokoll ist offen und jeder kann Bots, Dienste und Benutzeroberflächen erstellen und in Cwtch integrieren und interagieren.
  • Datenschutz wahrend: Alle Kommunikation in Cwtch ist Ende-zu-Ende verschlüsselt und findet über Tor v3 onion Dienste statt.
  • Metadaten resistent: Cwtch wurde so konzipiert, dass ohne ihre ausdrückliche Zustimmung keine Informationen ausgetauscht oder zugänglich sind einschließlich On-the-wire Nachrichten und Protokoll-Metadaten.

Sicherheit und Verschlüsselung

Für einen detaillierteren Blick auf die in Cwtch verwendete Sicherheit, Privatsphäre und die zugrunde liegende Verschlüsselungstechnologie lesen Sie ies bitte unser Sicherheitshandbuch

Erste Schritte

Du kannst die neueste Version von Cwtch von herunterladen https://cwtch.im/download/

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/platforms/tails/index.html b/build-staging/de/docs/platforms/tails/index.html new file mode 100644 index 00000000..4f8040ba --- /dev/null +++ b/build-staging/de/docs/platforms/tails/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch in Tails laufen lassen | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch in Tails laufen lassen

Warnung Feature des nächtlichen Releases

Diese Funktionalität ist derzeit nur verfügbar in den Nächtlichen Release Builds von Cwtch.

Diese Funktionalität kann unvollständig und/oder gefährlich sein, wenn sie falsch benutzt wird. Bitte hilf uns bei der Überprüfung und dem Test.

Die folgenden Schritte erfordern, dass Tails mit einem Administrationspasswort gestartet wurde.

Tails verwendet Onion Grater um den Zugriff auf den Kontrollport zu schützen. Wir haben eine Onion Gratar Konfiguration cwtch-tails.yml paketiert und ein Skript (install-tails.sh) mit dem Cwtch unter Linux eingerichtet.

Der Tails-spezifische Teil des Skripts wird unten reproduziert:

    # Tails needs to be have been setup up with an Administration account
#
# Make Auth Cookie Readable
sudo chmod o+r /var/run/tor/control.authcookie
# Copy Onion Grater Config
sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml
# Restart Onion Grater so the Config Takes effect
sudo systemctl restart onion-grater.service

Beim Start sollte Cwtch auf Tails die CWTCH_TAILS=true Umgebungsvariable übergeben werden, um Cwtch automatisch für die Ausführung in einer Tails-ähnlichen Umgebung zu konfigurieren:

exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch

Installationsort

Der obige Befehl und die unten stehende Onion Gratar Konfiguration gehen davon aus, dass Cwtch in ~/.local/lib/cwtch/cwtch installiert wurde - wenn Cwtch irgendwo anders installiert wurde (oder wenn Du es direkt aus dem Download-Ordner laufen lässt) musst du die Befehle anpassen.

Onion Grater Konfiguration

Die Onion Gratar Konfiguration cwtch-tails.yml wird unten reproduziert. Wie erwähnt, kann diese Konfiguration wahrscheinlich noch viel weiter eingeschränkt werden.

    ---
# TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern

- apparmor-profiles:
- '/home/amnesia/.local/lib/cwtch/cwtch'
users:

- 'amnesia'
commands:
AUTHCHALLENGE:

- 'SAFECOOKIE .*'
SETEVENTS:

- 'CIRC WARN ERR'
- 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'
GETINFO:

- '.*'
GETCONF:

- 'DisableNetwork'
SETCONF:

- 'DisableNetwork.*'
ADD_ONION:

- '.*'
DEL_ONION:

- '.+'
HSFETCH:

- '.+'
events:
CIRC:
suppress: true
ORCONN:
suppress: true
INFO:
suppress: true
NOTICE:
suppress: true
WARN:
suppress: true
ERR:
suppress: true
HS_DESC:
response:

- pattern: '650 HS_DESC CREATED (\S+) (\S+) (\S+) \S+ (.+)'
replacement: '650 HS_DESC CREATED {} {} {} redacted {}'

- pattern: '650 HS_DESC UPLOAD (\S+) (\S+) .*'
replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'

- pattern: '650 HS_DESC UPLOADED (\S+) (\S+) .+'
replacement: '650 HS_DESC UPLOADED {} {} redacted'

- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH'

- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'

- pattern: '650 HS_DESC RECEIVED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'

- pattern: '.*'
replacement: ''
HS_DESC_CONTENT:
suppress: true

Dauerhaft

Standardmäßig erstellt Cwtch $HOME/.cwtch und speichert dort alle verschlüsselten Profile und Einstellungsdateien. Um Profil/Konversationen in Cwtch auf Tails zu speichern, musst du diesen Ordner in einem nicht flüchtigen Zuhause sichern.

Siehe Tails Dokumentation zum Einrichten von Dauerhaftem Speicher

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/availability-status/index.html b/build-staging/de/docs/profiles/availability-status/index.html new file mode 100644 index 00000000..90c663e7 --- /dev/null +++ b/build-staging/de/docs/profiles/availability-status/index.html @@ -0,0 +1,24 @@ + + + + + +Verfügbarkeitsstatus einstellen | The Cwtch Handbook + + + + + + + + + + + + +
+

Verfügbarkeitsstatus einstellen

Warnung Feature des nächtlichen Releases

Diese Funktionalität ist derzeit nur verfügbar in den Nächtlichen Release Builds von Cwtch.

Diese Funktionalität kann unvollständig und/oder gefährlich sein, wenn sie falsch benutzt wird. Bitte hilf uns bei der Überprüfung und dem Test.

Klicke im -Konversationsfenster auf das Status-Symbol neben deinem Profilbild.

Ein Dropdown-Menü wird angezeigt mit verschiedenen Optionen wie Verfügbar, Abwesend und Beschäftigt

Wenn du Abwesend oder Beschäftigt als Status auswählst, wird sich die Grenzlinie deines Profilbildes ändern, um den Status zu reflektieren

Kontakte sehen diese Änderung in ihrem Konversationsfenster.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/change-name/index.html b/build-staging/de/docs/profiles/change-name/index.html new file mode 100644 index 00000000..18fe174e --- /dev/null +++ b/build-staging/de/docs/profiles/change-name/index.html @@ -0,0 +1,24 @@ + + + + + +Ändern Deines Anzeigenamens | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/change-password/index.html b/build-staging/de/docs/profiles/change-password/index.html new file mode 100644 index 00000000..f956c4da --- /dev/null +++ b/build-staging/de/docs/profiles/change-password/index.html @@ -0,0 +1,24 @@ + + + + + +Passwort ändern | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/change-profile-image/index.html b/build-staging/de/docs/profiles/change-profile-image/index.html new file mode 100644 index 00000000..c8f31c91 --- /dev/null +++ b/build-staging/de/docs/profiles/change-profile-image/index.html @@ -0,0 +1,24 @@ + + + + + +Dein Profilbild ändern | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/create-a-profile/index.html b/build-staging/de/docs/profiles/create-a-profile/index.html new file mode 100644 index 00000000..90dc6061 --- /dev/null +++ b/build-staging/de/docs/profiles/create-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Ein neues Profil erstellen | The Cwtch Handbook + + + + + + + + + + + + +
+

Ein neues Profil erstellen

  1. Drücke die + Aktionstaste in der rechten unteren Ecke und wähle "Neues Profil"
  2. Wähle einen Anzeigenamen
  3. Wähle dies aus, wenn Du dieses Profil lokal mit starker Verschlüsselung schützen möchtest:
    • Passwort: Dein Konto ist vor anderen Personen geschützt, die dieses Gerät evtl. verwenden können
    • Kein Passwort: Jeder, der Zugriff auf dieses Gerät hat, kann auf dieses Profil zugreifen
  4. Gib dein Passwort ein und gib es erneut ein
  5. Neues Profil hinzufügen anklicken

Eine Anmerkung zu passwortgeschützten (verschlüsselten) Profilen

Die Profile werden lokal auf der Festplatte gespeichert und mittels eines Schlüssels verschlüsselt, der von einem Benutzer bekannten Passwort abgeleitet wird (via pbkdf2).

Beachte, dass einmal verschlüsselt und auf der Festplatte gespeichert die einzige Möglichkeit, ein Profil wiederherzustellen, ist das erneute Ableiten des Schlüssels aus dem Passwort - so ist es nicht möglich, eine vollständige Liste der Profile anzugeben, auf die ein Benutzer Zugriff haben könnte, bis er ein Passwort eingegeben hat.

Siehe auch: Cwtch Sicherheits-Handbuch: Profil Verschlüsselung & Speicher

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/delete-profile/index.html b/build-staging/de/docs/profiles/delete-profile/index.html new file mode 100644 index 00000000..8ff87b08 --- /dev/null +++ b/build-staging/de/docs/profiles/delete-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Ein Profil löschen | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/exporting-profile/index.html b/build-staging/de/docs/profiles/exporting-profile/index.html new file mode 100644 index 00000000..47c0fa19 --- /dev/null +++ b/build-staging/de/docs/profiles/exporting-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Sicherung oder Export eines Profils | The Cwtch Handbook + + + + + + + + + + + + +
+

Sicherung oder Export eines Profils

Auf der Profil-Verwaltungsseite:

  1. Klicke auf den Stift neben dem Profil, das du bearbeiten möchtest
  2. Scrolle nach unten zum Ende des Bildschirms
  3. Wähle "Export Profil"
  4. Wähle einen Ort und einen Dateinamen
  5. Bestätigen

Nach der Bestätigung wird Cwtch eine Kopie des Profils an der angegebenen Stelle ablegen. Diese Datei wird auf die gleiche Stufe verschlüsselt wie das Profil. Siehe Eine Notiz über passwortgeschützte (verschlüsselte) Profile für weitere Informationen zu verschlüsselten Profilen.

Diese Datei kann in eine andere Cwtch-Instanz auf jedem Gerät importiert werden.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/importing-a-profile/index.html b/build-staging/de/docs/profiles/importing-a-profile/index.html new file mode 100644 index 00000000..a7c5fa05 --- /dev/null +++ b/build-staging/de/docs/profiles/importing-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Profil importieren | The Cwtch Handbook + + + + + + + + + + + + +
+

Profil importieren

  1. Drücke die + Aktionstaste in der rechten unteren Ecke und wähle "Importiere Profil"
  2. Wähle eine exportierte Cwtch-Profildatei zum Importieren
  3. Gib das Passwort ein, das dem Profil zugeordnet ist und bestätige es.

Nach der Bestätigung wird Cwtch versuchen, die angegebene Datei mit einem aus dem angegebenen Passwort abgeleiteten Schlüssel zu entschlüsseln. Wenn es erfolgreich ist, erscheint das Profil auf dem Profilverwaltungs-Seite und kann verwendet werden.

Hinweis

Während ein Profil auf mehrere Geräte importiert werden kann zur Zeit nur eine Version des Profils aktiv sein. Ein gleichzeitiger Betrieb auf allen Geräten ist nicht möglich.

Versuche, das gleiche Profil auf mehreren Geräten gleichzeitig zu verwenden, können zu Verfügbarkeitsproblemen und Nachrichtenfehlern führen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/introduction/index.html b/build-staging/de/docs/profiles/introduction/index.html new file mode 100644 index 00000000..dc3f8e1e --- /dev/null +++ b/build-staging/de/docs/profiles/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Einführung in die Cwtch Profile | The Cwtch Handbook + + + + + + + + + + + + +
+

Eine Einführung in die Cwtch Profile

Mit Cwtch kannst Du eines von mehrere Profile erstellen. Jedes Profil erzeugt ein zufälliges ed25519 Schlüsselpaar, welches kompatibel mit dem Tor-Netzwerk ist.

Dies ist der Identifikator, den Du Personen geben kannst und den diese verwenden können, um dich über Cwtch zu kontaktieren.

Cwtch ermöglicht das Erstellen und Verwalten mehrerer separater Profile. Jedes Profil ist mit einem anderen Schlüsselpaar verknüpft, welches einen anderen Onion-Dienst startet.

Profile verwalten

Beim Start startet Cwtch den Bildschirm "Profile verwalten". Von diesem Bildschirm aus kannst Du:

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/profile-info/index.html b/build-staging/de/docs/profiles/profile-info/index.html new file mode 100644 index 00000000..12bc5a95 --- /dev/null +++ b/build-staging/de/docs/profiles/profile-info/index.html @@ -0,0 +1,24 @@ + + + + + +Profilattribute einstellen | The Cwtch Handbook + + + + + + + + + + + + +
+

Profilattribute einstellen

Warnung Feature des nächtlichen Releases

Diese Funktionalität ist derzeit nur verfügbar in den Nächtlichen Release Builds von Cwtch.

Diese Funktionalität kann unvollständig und/oder gefährlich sein, wenn sie falsch benutzt wird. Bitte hilf uns bei der Überprüfung und dem Test.

Im Profilverwaltungsfenster befinden sich drei freiformatige Textfelder unterhalb deines Profilbilds.

Du kannst diese Felder mit allen Informationen ausfüllen, die du potenzielle Kontakte wissen möchtest. Diese Informationen sind öffentlich - lege hier keine Informationen an, die du nicht mit allen teilen möchtest.

Kontakte können diese Informationen in den Konversationseinstellungen einsehen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/profiles/unlock-profile/index.html b/build-staging/de/docs/profiles/unlock-profile/index.html new file mode 100644 index 00000000..c51aa259 --- /dev/null +++ b/build-staging/de/docs/profiles/unlock-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Verschlüsselte Profile entsperren | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/servers/create-server/index.html b/build-staging/de/docs/servers/create-server/index.html new file mode 100644 index 00000000..bc11f276 --- /dev/null +++ b/build-staging/de/docs/servers/create-server/index.html @@ -0,0 +1,24 @@ + + + + + +Wie man einen Server erstellt | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/servers/delete-server/index.html b/build-staging/de/docs/servers/delete-server/index.html new file mode 100644 index 00000000..651a3f22 --- /dev/null +++ b/build-staging/de/docs/servers/delete-server/index.html @@ -0,0 +1,24 @@ + + + + + +Wie man einen Server löscht | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/servers/edit-server/index.html b/build-staging/de/docs/servers/edit-server/index.html new file mode 100644 index 00000000..3a4aa437 --- /dev/null +++ b/build-staging/de/docs/servers/edit-server/index.html @@ -0,0 +1,24 @@ + + + + + +Wie man einen Server bearbeitet | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/servers/introduction/index.html b/build-staging/de/docs/servers/introduction/index.html new file mode 100644 index 00000000..d0a1625c --- /dev/null +++ b/build-staging/de/docs/servers/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Server Einführung | The Cwtch Handbook + + + + + + + + + + + + +
+

Server Einführung

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.

Der Cwtch Kontakt zu Kontakt Chat ist vollständig peer to peer, d. h. wenn ein Teilnehmer offline ist, kannst du mit ihm nicht chatten, und es gibt keinen Mechanismus um mit mehreren Personen zu chatten.

Um Gruppenchat (und Offline-Zustellung) zu unterstützen, haben wir nicht vertrauenswürdige Cwtch-Server erstellt, die Nachrichten für eine Gruppe hosten können. Die Nachrichten werden mit dem Gruppenschlüssel verschlüsselt und über flüchtige Onions abgeholt, so dass der Server keine Möglichkeit hat zu wissen, welche Nachrichten für welche Gruppen er hat oder wer darauf zugreift.

Derzeit werden Server in der Cwtch-App nur auf der Desktop-Version unterstützt, da die Internet-Verbindung von mobilen Geräten zu instabil und nicht geeignet für den Betrieb eines Servers ist.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/servers/share-key/index.html b/build-staging/de/docs/servers/share-key/index.html new file mode 100644 index 00000000..e1c44395 --- /dev/null +++ b/build-staging/de/docs/servers/share-key/index.html @@ -0,0 +1,24 @@ + + + + + +Wie du dein Server-Schlüsselpaket teilst | The Cwtch Handbook + + + + + + + + + + + + +
+

Wie du dein Server-Schlüsselpaket teilst

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.

Dein Server-Schlüsselbündel ist das Datenpaket, das eine Cwtch-App benötigt, um einen Server nutzen zu können. Wenn du nur andere Cwtch-Benutzer auf deinen Server aufmerksam machen möchtest, kannst du dies mit ihnen teilen. Dann haben sie die Möglichkeit, eigene Gruppen auf dem Server zu erstellen.

  1. Zum Server-Symbol gehen
  2. Wähle den gewünschten Server aus
  3. Benutze das Kopier-Adressen-Symbol um die Server-Schlüssel zu kopieren
  4. Teile die Schlüssel nicht mit Leuten, denen du nicht vertraust
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/servers/unlock-server/index.html b/build-staging/de/docs/servers/unlock-server/index.html new file mode 100644 index 00000000..c6b7c526 --- /dev/null +++ b/build-staging/de/docs/servers/unlock-server/index.html @@ -0,0 +1,24 @@ + + + + + +Wie man einen Server entsperrt | The Cwtch Handbook + + + + + + + + + + + + +
+

Wie man einen Server entsperrt

Experimentelle Funktionen erforderlich

Diese Funktion erfordert, dass Experimente aktiviert und das Server Hosting Experiment eingeschaltet ist.

Wenn du deinen Server mit einem Passwort geschützt hast, muss er bei jedem Neustart der Anwendung entsperrt werden.

  1. Zum Server-Symbol gehen
  2. Klicken Sie auf das rosa Entsperr-Symbol
  3. Gib das Kennwort deines Servers ein
  4. Drücke Entsperren
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/appearance/change-language/index.html b/build-staging/de/docs/settings/appearance/change-language/index.html new file mode 100644 index 00000000..ebf1aa7c --- /dev/null +++ b/build-staging/de/docs/settings/appearance/change-language/index.html @@ -0,0 +1,24 @@ + + + + + +Sprache wechseln | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/appearance/light-dark-mode/index.html b/build-staging/de/docs/settings/appearance/light-dark-mode/index.html new file mode 100644 index 00000000..942dab51 --- /dev/null +++ b/build-staging/de/docs/settings/appearance/light-dark-mode/index.html @@ -0,0 +1,24 @@ + + + + + +Helles/Dunkles Design und Theme-Aufteilung | The Cwtch Handbook + + + + + + + + + + + + +
+

Helles/Dunkles Design und Theme-Aufteilung

  1. Drücke das Einstellungssymbol
  2. Du kannst ein helles oder dunkles Thema wählen, indem Du den Schalter „Verwende helles Theme“ einschaltest
  3. Wähle mit dem Dropdown-Menü „Farb-Theme“ ein Theme aus, das Dir gefällt
    1. Cwtch: lila Tönung
    2. Geist: Graue Tönung
    3. Meerjungfrau: Türkise und violette Tönung
    4. Mitternacht: Schwarze und graue Tönung
    5. Neon 1: lila und rosa Tönung
    6. Neon 2: lila und türkise Tönung
    7. Kürbis: lila und orange Tönung
    8. Hexe: Grüne und rosa Tönung
    9. Vampir: Violette und rote Tönung
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/appearance/streamer-mode/index.html b/build-staging/de/docs/settings/appearance/streamer-mode/index.html new file mode 100644 index 00000000..a9bcd795 --- /dev/null +++ b/build-staging/de/docs/settings/appearance/streamer-mode/index.html @@ -0,0 +1,24 @@ + + + + + +Streamer/Präsentationsmodus | The Cwtch Handbook + + + + + + + + + + + + +
+

Streamer/Präsentationsmodus

Streamer/Präsentationsmodus macht die App optisch privater. In diesem Modus wird Cwtch keine Hilfsinformationen wie Cwtch-Adressen und andere sensible Informationen auf den Hauptbildschirmen anzeigen.

Dies ist nützlich, wenn Du Screenshots machst oder Cwtch auf andere Art und Weise öffentlich anzeigst.

  1. Drücke das Einstellungssymbol
  2. "Streamer-Modus" auf "An"
  3. Überprüfe, ob es funktioniert, indem Du Dein Profil oder Deine Kontaktliste ansiehst
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/appearance/ui-columns/index.html b/build-staging/de/docs/settings/appearance/ui-columns/index.html new file mode 100644 index 00000000..ff422f51 --- /dev/null +++ b/build-staging/de/docs/settings/appearance/ui-columns/index.html @@ -0,0 +1,24 @@ + + + + + +UI Spalten | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/behaviour/block-unknown-connections/index.html b/build-staging/de/docs/settings/behaviour/block-unknown-connections/index.html new file mode 100644 index 00000000..cefb34a4 --- /dev/null +++ b/build-staging/de/docs/settings/behaviour/block-unknown-connections/index.html @@ -0,0 +1,24 @@ + + + + + +Unbekannte Verbindungen blockieren | The Cwtch Handbook + + + + + + + + + + + + +
+

Unbekannte Verbindungen blockieren

Standardmäßig interpretiert Cwtch Verbindungen von unbekannten Cwtch-Adressen als Kontaktanfragen. Du kannst dieses Verhalten durch die Blockierung unbekannter Verbindungen ändern.

Wenn aktiviert, schließt Cwtch automatisch alle Verbindungen von Cwtch-Adressen, die Du nicht zur Konversationsliste hinzugefügt hast. Dadurch wird verhindert, dass Personen, die Deine Cwtch-Adresse haben, sich mit Dir in Verbindung setzen, es sei denn, Du fügst diese hinzu.

Zum Aktivieren:

  1. Zu den Einstellungen
  2. Blockieren unbekannter Kontakte aktivieren
+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/behaviour/notification-content/index.html b/build-staging/de/docs/settings/behaviour/notification-content/index.html new file mode 100644 index 00000000..e6df97d9 --- /dev/null +++ b/build-staging/de/docs/settings/behaviour/notification-content/index.html @@ -0,0 +1,24 @@ + + + + + +Benachrichtigungsinhalt | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/behaviour/notification-policy/index.html b/build-staging/de/docs/settings/behaviour/notification-policy/index.html new file mode 100644 index 00000000..67bd354a --- /dev/null +++ b/build-staging/de/docs/settings/behaviour/notification-policy/index.html @@ -0,0 +1,24 @@ + + + + + +Benachrichtigungsrichtlinie | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/clickable-links/index.html b/build-staging/de/docs/settings/experiments/clickable-links/index.html new file mode 100644 index 00000000..58da657a --- /dev/null +++ b/build-staging/de/docs/settings/experiments/clickable-links/index.html @@ -0,0 +1,24 @@ + + + + + +Experiment klickbarer Links | The Cwtch Handbook + + + + + + + + + + + + +
+

Experiment klickbarer Links

Gefahr

Wenn aktiviert, stellt diese Funktion ein Entanonymisierung Risiko dar.

keine URLs von Personen öffnen, denen Du nicht vertraust. Links, die über Cwtch gesendet werden, werden über den Standard Browser auf dem System geöffnet. Die meisten Webbrowser können keine Anonymität anbieten.

Aktiviere das Experiment mit klickbaren Links

Anklickbare Links sind standardmäßig nicht aktiviert. Um Cwtch das Öffnen von Links in Nachrichten zu ermöglichen:

  1. Zu den Einstellungen
  2. Experimente aktivieren
  3. Aktiviere das Klickbare Links Experiment

Risiko

Klickbare Links in Nachrichten sind ein sehr nützliches Feature, aber es gibt Risiken, die Du beachten solltest, wenn Du diese Funktion aktivierst.

Um eine versehentliche Auslösung zu verhindern, öffnet Cwtch nach einem Klick auf einen Link in einer Nachricht zuerst eine zusätzliche Aufforderung mit zwei Optionen:

  1. Die URL in die Zwischenablage kopieren
  2. Öffne die URL im -Standard-Browser

Du kannst die Zurück-Taste auf DeinemGerät verwenden oder von dieser Eingabeaufforderung wegklicken, um die Auswahl einer der beiden Optionen zu vermeiden.

Cwtch kann Dich nicht schützen, wenn Du böswillige Links öffnest.

Die URL wird im -Standard-Browser geöffnet, was wahrscheinlich mindestens Deine IP-Adresse dem Server bekanntgeben wird, der die URL hostet. Webseiten können auch andere Browser-Verwundbarkeiten nutzen, um zusätzliche Informationen zu sammeln oder Deinen Computer weiter auszunutzen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/file-sharing/index.html b/build-staging/de/docs/settings/experiments/file-sharing/index.html new file mode 100644 index 00000000..45779550 --- /dev/null +++ b/build-staging/de/docs/settings/experiments/file-sharing/index.html @@ -0,0 +1,24 @@ + + + + + +Dateifreigabe | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/group-experiment/index.html b/build-staging/de/docs/settings/experiments/group-experiment/index.html new file mode 100644 index 00000000..502a88f1 --- /dev/null +++ b/build-staging/de/docs/settings/experiments/group-experiment/index.html @@ -0,0 +1,24 @@ + + + + + +experimentelle Gruppen Funktion | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/image-previews-and-profile-pictures/index.html b/build-staging/de/docs/settings/experiments/image-previews-and-profile-pictures/index.html new file mode 100644 index 00000000..a30ef707 --- /dev/null +++ b/build-staging/de/docs/settings/experiments/image-previews-and-profile-pictures/index.html @@ -0,0 +1,24 @@ + + + + + +Bildvorschau und Profilbilder | The Cwtch Handbook + + + + + + + + + + + + +
+

Bildvorschau und Profilbilder

Vorsicht

Dieses experimentelle Funktion erfordert das File Sharing aktiviert ist.

Wenn aktiviert, wird Cwtch die Bilddateien automatisch herunterladen, Bildvorschau im Konversationsfenster anzeigen und Profilbilder aktivieren;

Auf dem Desktop, durch das Aktivieren dieser experimentellen Funktion wird der Zugriff auf eine zusätzliche Einstellung "Downloadordner` erlaubt, die geändert werden kann, um Cwtch zu sagen, wo (automatisch) Bilder heruntergeladen werden sollen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/message-formatting/index.html b/build-staging/de/docs/settings/experiments/message-formatting/index.html new file mode 100644 index 00000000..963b2c7b --- /dev/null +++ b/build-staging/de/docs/settings/experiments/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Nachrichtenformatierung | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/qrcodes/index.html b/build-staging/de/docs/settings/experiments/qrcodes/index.html new file mode 100644 index 00000000..1b5e2ea7 --- /dev/null +++ b/build-staging/de/docs/settings/experiments/qrcodes/index.html @@ -0,0 +1,24 @@ + + + + + +QR Codes | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/experiments/server-hosting/index.html b/build-staging/de/docs/settings/experiments/server-hosting/index.html new file mode 100644 index 00000000..180a483d --- /dev/null +++ b/build-staging/de/docs/settings/experiments/server-hosting/index.html @@ -0,0 +1,24 @@ + + + + + +Server Hosting | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/docs/settings/introduction/index.html b/build-staging/de/docs/settings/introduction/index.html new file mode 100644 index 00000000..8c77a8cd --- /dev/null +++ b/build-staging/de/docs/settings/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Eine Einführung in die Cwtch App-Einstellungen | The Cwtch Handbook + + + + + + + + + + + + +
+

Eine Einführung in die Cwtch App-Einstellungen

Darstellung

Dies sind Einstellungen, die das Aussehen von Cwtch beeinflussen, einschließlich Themen und Lokalisierung.

Verhalten

Diese Einstellungen beeinflussen die Reaktion von Cwtch auf bestimmte Ereignisse wie z.B. Benachrichtigungen für neue Nachrichten oder Anfragen von unbekannten öffentlichen Adressen.

Experimente

Es gibt viele Funktionen in Cwtch, die man gerne ausprobieren möchte, deren Implementierung aber zusätzliche Metadaten erfordert oder Risiko, über das Minimum hinaus, das Cwtch für grundlegende Operationen benötigt, hinausgeht.

Unter Experimente findest du eine Anzahl von optionalen Einstellungen, die, wenn aktiviert, Dir zusätzliche Funktionen wie Gruppenchat, Dateiaustausch oder Nachrichtenformatierung bieten.

Du solltest sorgfältig über die neuen Risiken nachdenken, die damit verbunden sein könnten, wenn Du diese Funktionen aktivierst und wenn Du dich damit komfortabel fühlt, kannst du diese aktivieren. Für viele überwiegen die Vorteile des Dateiaustauschs, Bildvorschau und Gruppenchat die möglichen Schäden bei weitem - aber wir verlangen trotzdem von jedem, dass diese Funktionen selber aktiviert werden müssen.

Du kannst die Funktionen jederzeit wieder deaktivieren, alle Funktionen sind lokal innerhalb der Cwtch-App implementiert.

+ + + + \ No newline at end of file diff --git a/build-staging/de/docs/tor/index.html b/build-staging/de/docs/tor/index.html new file mode 100644 index 00000000..7fece4d5 --- /dev/null +++ b/build-staging/de/docs/tor/index.html @@ -0,0 +1,24 @@ + + + + + +Tor | The Cwtch Handbook + + + + + + + + + + + + +
+

Tor

Cwtch verwendet Tor um Routing und Verbindungen bereitzustellen. Die Verwendung von Tor-versteckten Diensten für das Hosten von Profilen und nebenbei generierte "ephemerale" Verbindungen, wenn eine Verbindung aufgebaut wird, bietet eine starke Anonymität für Benutzer von Cwtch.

Tor-Übersicht

Da wir Cwtch eine zusätzliche Netzwerk-Ebene hinzufügen, bieten wir eine Übersicht, um den Tor-Netzwerk-Status zu sehen und Änderungen vorzunehmen. Um darauf zuzugreifen

  1. Klicke auf das Tor-Symbol in der Profilliste tor icon
  2. Den Tor Netzwerkstatus anzeigen
Tor-Status: Online
Torversion: 0.4.6.9

Reset Tor

Das Tor-Netzwerk selbst kann gelegentlich veraltete Verbindungen haben, die nicht sofort von ihm oder Cwtch erkannt werden (wir versuchen dies immer weiter zu verbessern). Manchmal kann ein Benutzer Kontakte oder Gruppen finden, die offline erscheinen, auch wenn diese meinen, dass sie online sein sollten. Wenn du alle Netzwerkverbindungen in Cwtch neu starten möchtest, bieten wir einen Mechanismus zum Tor Neustart von innerhalb der App an. Der Reset Button startet Tor aus der Cwtch App heraus neu.

Cache-Tor-Konsens

Standardmäßig starten wir jedesmal einen neuen Tor-Prozess, wenn die App bootet, und es erfordert das Herunterladen eines Tor-Netzwerk-Zustandes, bevor dieser gestartet werden kann. Dieser Prozess ist nicht so schnell. Wenn du den Cwtch-Start beschleunigen möchtest, kannst du den Tor-Cache-Konsens aktivieren, um zukünftige Starts zu beschleunigen. Wenn du in ein Start Problem kommst, wo die Daten veraltet oder korrupt sind und Cwtch meldet, dass es nicht starten kann, dann deaktiviere diese Einstellung und reset Tor erneut, dann sollte es funktionieren.

Erweiterte Tor Einstellungen

Wir bieten dir auch die Möglichkeit an, in diesem Abschnitt eine erweiterte Tor-Konfiguration bereitzustellen, indem wir dir erlauben:

  • Gib einen benutzerdefinierten SOCKS-Port an, um eine Verbindung zu einem bestehenden Tor herzustellen
  • Gib einen benutzerdefinierten Kontroll-Port an, um eine Verbindung zu einem bestehenden Tor herzustellen
  • und gib weitere Optionen an, indem du benutzerdefinierte torrc Optionen eingibst
+ + + + \ No newline at end of file diff --git a/build-staging/de/img/1.10.midnight.png b/build-staging/de/img/1.10.midnight.png new file mode 100644 index 00000000..e706a501 Binary files /dev/null and b/build-staging/de/img/1.10.midnight.png differ diff --git a/build-staging/de/img/1.png b/build-staging/de/img/1.png new file mode 100644 index 00000000..65538ea1 Binary files /dev/null and b/build-staging/de/img/1.png differ diff --git a/build-staging/de/img/2.png b/build-staging/de/img/2.png new file mode 100644 index 00000000..4de6eb1c Binary files /dev/null and b/build-staging/de/img/2.png differ diff --git a/build-staging/de/img/3.png b/build-staging/de/img/3.png new file mode 100644 index 00000000..7aac7c0a Binary files /dev/null and b/build-staging/de/img/3.png differ diff --git a/build-staging/de/img/4.png b/build-staging/de/img/4.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/de/img/4.png differ diff --git a/build-staging/de/img/5_year_banner.png b/build-staging/de/img/5_year_banner.png new file mode 100644 index 00000000..ecc179a9 Binary files /dev/null and b/build-staging/de/img/5_year_banner.png differ diff --git a/build-staging/de/img/Anti-Spam_1.svg b/build-staging/de/img/Anti-Spam_1.svg new file mode 100644 index 00000000..3860cbfb --- /dev/null +++ b/build-staging/de/img/Anti-Spam_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Anti-Spam_2.svg b/build-staging/de/img/Anti-Spam_2.svg new file mode 100644 index 00000000..eb7a90b7 --- /dev/null +++ b/build-staging/de/img/Anti-Spam_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Anti-Spam_3.svg b/build-staging/de/img/Anti-Spam_3.svg new file mode 100644 index 00000000..df33b751 --- /dev/null +++ b/build-staging/de/img/Anti-Spam_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/BASE_0.png b/build-staging/de/img/BASE_0.png new file mode 100644 index 00000000..384cbefa Binary files /dev/null and b/build-staging/de/img/BASE_0.png differ diff --git a/build-staging/de/img/BASE_1.png b/build-staging/de/img/BASE_1.png new file mode 100644 index 00000000..0adb8240 Binary files /dev/null and b/build-staging/de/img/BASE_1.png differ diff --git a/build-staging/de/img/BASE_2.png b/build-staging/de/img/BASE_2.png new file mode 100644 index 00000000..d1cbb8e5 Binary files /dev/null and b/build-staging/de/img/BASE_2.png differ diff --git a/build-staging/de/img/BASE_3.png b/build-staging/de/img/BASE_3.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/de/img/BASE_3.png differ diff --git a/build-staging/de/img/BASE_5.png b/build-staging/de/img/BASE_5.png new file mode 100644 index 00000000..0330d03b Binary files /dev/null and b/build-staging/de/img/BASE_5.png differ diff --git a/build-staging/de/img/BASE_6.png b/build-staging/de/img/BASE_6.png new file mode 100644 index 00000000..3de5d899 Binary files /dev/null and b/build-staging/de/img/BASE_6.png differ diff --git a/build-staging/de/img/BASE_7.png b/build-staging/de/img/BASE_7.png new file mode 100644 index 00000000..00f730ad Binary files /dev/null and b/build-staging/de/img/BASE_7.png differ diff --git a/build-staging/de/img/BASE_8.png b/build-staging/de/img/BASE_8.png new file mode 100644 index 00000000..3881065e Binary files /dev/null and b/build-staging/de/img/BASE_8.png differ diff --git a/build-staging/de/img/Create_group.svg b/build-staging/de/img/Create_group.svg new file mode 100644 index 00000000..47001a56 --- /dev/null +++ b/build-staging/de/img/Create_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Eye_Closed.svg b/build-staging/de/img/Eye_Closed.svg new file mode 100644 index 00000000..01e6e0b0 --- /dev/null +++ b/build-staging/de/img/Eye_Closed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Eye_Open.svg b/build-staging/de/img/Eye_Open.svg new file mode 100644 index 00000000..3f29f7e1 --- /dev/null +++ b/build-staging/de/img/Eye_Open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/HB_svg_1.svg b/build-staging/de/img/HB_svg_1.svg new file mode 100644 index 00000000..4dd29705 --- /dev/null +++ b/build-staging/de/img/HB_svg_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/HB_svg_2.svg b/build-staging/de/img/HB_svg_2.svg new file mode 100644 index 00000000..4a4f36d3 --- /dev/null +++ b/build-staging/de/img/HB_svg_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/HB_svg_3.svg b/build-staging/de/img/HB_svg_3.svg new file mode 100644 index 00000000..f385b41a --- /dev/null +++ b/build-staging/de/img/HB_svg_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/HB_svg_4.svg b/build-staging/de/img/HB_svg_4.svg new file mode 100644 index 00000000..cf7ee829 --- /dev/null +++ b/build-staging/de/img/HB_svg_4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/OP_eye.svg b/build-staging/de/img/OP_eye.svg new file mode 100644 index 00000000..f12b17e5 --- /dev/null +++ b/build-staging/de/img/OP_eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Onion_Waiting.svg b/build-staging/de/img/Onion_Waiting.svg new file mode 100644 index 00000000..1f4f8005 --- /dev/null +++ b/build-staging/de/img/Onion_Waiting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Onion_off.svg b/build-staging/de/img/Onion_off.svg new file mode 100644 index 00000000..8075d469 --- /dev/null +++ b/build-staging/de/img/Onion_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Onion_on.svg b/build-staging/de/img/Onion_on.svg new file mode 100644 index 00000000..51771b97 --- /dev/null +++ b/build-staging/de/img/Onion_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Screenshot_2022-06-17_13-42-19.png b/build-staging/de/img/Screenshot_2022-06-17_13-42-19.png new file mode 100644 index 00000000..f3bd84ac Binary files /dev/null and b/build-staging/de/img/Screenshot_2022-06-17_13-42-19.png differ diff --git a/build-staging/de/img/Tor_Booting_up.svg b/build-staging/de/img/Tor_Booting_up.svg new file mode 100644 index 00000000..2df93fe0 --- /dev/null +++ b/build-staging/de/img/Tor_Booting_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Tor_OFF.svg b/build-staging/de/img/Tor_OFF.svg new file mode 100644 index 00000000..fd2a714c --- /dev/null +++ b/build-staging/de/img/Tor_OFF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/Tor_icon.png b/build-staging/de/img/Tor_icon.png new file mode 100644 index 00000000..0c871e9f Binary files /dev/null and b/build-staging/de/img/Tor_icon.png differ diff --git a/build-staging/de/img/View_replies.svg b/build-staging/de/img/View_replies.svg new file mode 100644 index 00000000..03cae418 --- /dev/null +++ b/build-staging/de/img/View_replies.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/aar-diff.png b/build-staging/de/img/aar-diff.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/de/img/aar-diff.png differ diff --git a/build-staging/de/img/account_blocked.svg b/build-staging/de/img/account_blocked.svg new file mode 100644 index 00000000..412efcff --- /dev/null +++ b/build-staging/de/img/account_blocked.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/build-staging/de/img/account_circle-24px.svg b/build-staging/de/img/account_circle-24px.svg new file mode 100644 index 00000000..013a30af --- /dev/null +++ b/build-staging/de/img/account_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/account_circle-24px_lines.svg b/build-staging/de/img/account_circle-24px_lines.svg new file mode 100644 index 00000000..9fec981a --- /dev/null +++ b/build-staging/de/img/account_circle-24px_lines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/account_circle-24px_lines_thin - blocked.svg b/build-staging/de/img/account_circle-24px_lines_thin - blocked.svg new file mode 100644 index 00000000..5c3b9b7a --- /dev/null +++ b/build-staging/de/img/account_circle-24px_lines_thin - blocked.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/build-staging/de/img/account_circle-24px_lines_thin.svg b/build-staging/de/img/account_circle-24px_lines_thin.svg new file mode 100644 index 00000000..7ded72ff --- /dev/null +++ b/build-staging/de/img/account_circle-24px_lines_thin.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/build-staging/de/img/account_circle-24px_negative_space.svg b/build-staging/de/img/account_circle-24px_negative_space.svg new file mode 100644 index 00000000..c9c4f83c --- /dev/null +++ b/build-staging/de/img/account_circle-24px_negative_space.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/build-staging/de/img/account_circle-24px_user.svg b/build-staging/de/img/account_circle-24px_user.svg new file mode 100644 index 00000000..3eb8ffc7 --- /dev/null +++ b/build-staging/de/img/account_circle-24px_user.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/build-staging/de/img/add_circle-24px.svg b/build-staging/de/img/add_circle-24px.svg new file mode 100644 index 00000000..e8e583ad --- /dev/null +++ b/build-staging/de/img/add_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/add_group.svg b/build-staging/de/img/add_group.svg new file mode 100644 index 00000000..c4a8658e --- /dev/null +++ b/build-staging/de/img/add_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/add_peer.svg b/build-staging/de/img/add_peer.svg new file mode 100644 index 00000000..0b15edbd --- /dev/null +++ b/build-staging/de/img/add_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/android.png b/build-staging/de/img/android.png new file mode 100644 index 00000000..afee7fce Binary files /dev/null and b/build-staging/de/img/android.png differ diff --git a/build-staging/de/img/android.svg b/build-staging/de/img/android.svg new file mode 100644 index 00000000..f743813f --- /dev/null +++ b/build-staging/de/img/android.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/build-staging/de/img/apple.svg b/build-staging/de/img/apple.svg new file mode 100644 index 00000000..a090c68e --- /dev/null +++ b/build-staging/de/img/apple.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/build-staging/de/img/attach_file-24px.svg b/build-staging/de/img/attach_file-24px.svg new file mode 100644 index 00000000..471fb991 --- /dev/null +++ b/build-staging/de/img/attach_file-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/attached-file-2.svg b/build-staging/de/img/attached-file-2.svg new file mode 100644 index 00000000..0f7b9eb3 --- /dev/null +++ b/build-staging/de/img/attached-file-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/attached-file-3.svg b/build-staging/de/img/attached-file-3.svg new file mode 100644 index 00000000..37e2f74a --- /dev/null +++ b/build-staging/de/img/attached-file-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/attached-file.svg b/build-staging/de/img/attached-file.svg new file mode 100644 index 00000000..28ea8263 --- /dev/null +++ b/build-staging/de/img/attached-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/block-24px.svg b/build-staging/de/img/block-24px.svg new file mode 100644 index 00000000..8636ff6a --- /dev/null +++ b/build-staging/de/img/block-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/block_peer.svg b/build-staging/de/img/block_peer.svg new file mode 100644 index 00000000..fb4a84e7 --- /dev/null +++ b/build-staging/de/img/block_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/block_unknown.svg b/build-staging/de/img/block_unknown.svg new file mode 100644 index 00000000..f5afc576 --- /dev/null +++ b/build-staging/de/img/block_unknown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/card_header.png b/build-staging/de/img/card_header.png new file mode 100644 index 00000000..aaa0368b Binary files /dev/null and b/build-staging/de/img/card_header.png differ diff --git a/build-staging/de/img/change_language.svg b/build-staging/de/img/change_language.svg new file mode 100644 index 00000000..d36e819b --- /dev/null +++ b/build-staging/de/img/change_language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/change_theme.svg b/build-staging/de/img/change_theme.svg new file mode 100644 index 00000000..95bf1fd4 --- /dev/null +++ b/build-staging/de/img/change_theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/check-24px.svg b/build-staging/de/img/check-24px.svg new file mode 100644 index 00000000..c5c42b66 --- /dev/null +++ b/build-staging/de/img/check-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/chevron_left-24px.svg b/build-staging/de/img/chevron_left-24px.svg new file mode 100644 index 00000000..6f78ae79 --- /dev/null +++ b/build-staging/de/img/chevron_left-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/clear-24px.svg b/build-staging/de/img/clear-24px.svg new file mode 100644 index 00000000..08149461 --- /dev/null +++ b/build-staging/de/img/clear-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/clickable_links.png b/build-staging/de/img/clickable_links.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/de/img/clickable_links.png differ diff --git a/build-staging/de/img/clickable_links_experiment.png b/build-staging/de/img/clickable_links_experiment.png new file mode 100644 index 00000000..1d809218 Binary files /dev/null and b/build-staging/de/img/clickable_links_experiment.png differ diff --git a/build-staging/de/img/conversations/settings-full.png b/build-staging/de/img/conversations/settings-full.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/de/img/conversations/settings-full.png differ diff --git a/build-staging/de/img/conversations/settings.png b/build-staging/de/img/conversations/settings.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/de/img/conversations/settings.png differ diff --git a/build-staging/de/img/cwtch phones.png b/build-staging/de/img/cwtch phones.png new file mode 100644 index 00000000..54396db9 Binary files /dev/null and b/build-staging/de/img/cwtch phones.png differ diff --git a/build-staging/de/img/cwtch_handbook_header.jpg b/build-staging/de/img/cwtch_handbook_header.jpg new file mode 100644 index 00000000..7b75a456 Binary files /dev/null and b/build-staging/de/img/cwtch_handbook_header.jpg differ diff --git a/build-staging/de/img/cwtch_knott.svg b/build-staging/de/img/cwtch_knott.svg new file mode 100644 index 00000000..7b16f58f --- /dev/null +++ b/build-staging/de/img/cwtch_knott.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/delete-24px.svg b/build-staging/de/img/delete-24px.svg new file mode 100644 index 00000000..8f6e9a27 --- /dev/null +++ b/build-staging/de/img/delete-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/dev9-host-disabled.png b/build-staging/de/img/dev9-host-disabled.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/de/img/dev9-host-disabled.png differ diff --git a/build-staging/de/img/devlog1.jpg b/build-staging/de/img/devlog1.jpg new file mode 100644 index 00000000..639ccabd Binary files /dev/null and b/build-staging/de/img/devlog1.jpg differ diff --git a/build-staging/de/img/devlog1.png b/build-staging/de/img/devlog1.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/de/img/devlog1.png differ diff --git a/build-staging/de/img/devlog10.png b/build-staging/de/img/devlog10.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/de/img/devlog10.png differ diff --git a/build-staging/de/img/devlog10_small.png b/build-staging/de/img/devlog10_small.png new file mode 100644 index 00000000..d27ea94f Binary files /dev/null and b/build-staging/de/img/devlog10_small.png differ diff --git a/build-staging/de/img/devlog12.png b/build-staging/de/img/devlog12.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/de/img/devlog12.png differ diff --git a/build-staging/de/img/devlog12_small.png b/build-staging/de/img/devlog12_small.png new file mode 100644 index 00000000..425cd4bb Binary files /dev/null and b/build-staging/de/img/devlog12_small.png differ diff --git a/build-staging/de/img/devlog13.png b/build-staging/de/img/devlog13.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/de/img/devlog13.png differ diff --git a/build-staging/de/img/devlog13_small.png b/build-staging/de/img/devlog13_small.png new file mode 100644 index 00000000..e6de7752 Binary files /dev/null and b/build-staging/de/img/devlog13_small.png differ diff --git a/build-staging/de/img/devlog1_small.jpg b/build-staging/de/img/devlog1_small.jpg new file mode 100644 index 00000000..a7ffb46a Binary files /dev/null and b/build-staging/de/img/devlog1_small.jpg differ diff --git a/build-staging/de/img/devlog2.png b/build-staging/de/img/devlog2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/de/img/devlog2.png differ diff --git a/build-staging/de/img/devlog2_small.png b/build-staging/de/img/devlog2_small.png new file mode 100644 index 00000000..0eb53c1f Binary files /dev/null and b/build-staging/de/img/devlog2_small.png differ diff --git a/build-staging/de/img/devlog3.png b/build-staging/de/img/devlog3.png new file mode 100644 index 00000000..b1a2a9a3 Binary files /dev/null and b/build-staging/de/img/devlog3.png differ diff --git a/build-staging/de/img/devlog3_small.png b/build-staging/de/img/devlog3_small.png new file mode 100644 index 00000000..dc99bef2 Binary files /dev/null and b/build-staging/de/img/devlog3_small.png differ diff --git a/build-staging/de/img/devlog4.png b/build-staging/de/img/devlog4.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/de/img/devlog4.png differ diff --git a/build-staging/de/img/devlog4_small.png b/build-staging/de/img/devlog4_small.png new file mode 100644 index 00000000..77354e45 Binary files /dev/null and b/build-staging/de/img/devlog4_small.png differ diff --git a/build-staging/de/img/devlog5.png b/build-staging/de/img/devlog5.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/de/img/devlog5.png differ diff --git a/build-staging/de/img/devlog5_small.png b/build-staging/de/img/devlog5_small.png new file mode 100644 index 00000000..c2a4d835 Binary files /dev/null and b/build-staging/de/img/devlog5_small.png differ diff --git a/build-staging/de/img/devlog6.png b/build-staging/de/img/devlog6.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/de/img/devlog6.png differ diff --git a/build-staging/de/img/devlog6_small.png b/build-staging/de/img/devlog6_small.png new file mode 100644 index 00000000..384738b5 Binary files /dev/null and b/build-staging/de/img/devlog6_small.png differ diff --git a/build-staging/de/img/devlog7.png b/build-staging/de/img/devlog7.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/de/img/devlog7.png differ diff --git a/build-staging/de/img/devlog7_small.png b/build-staging/de/img/devlog7_small.png new file mode 100644 index 00000000..a919c58d Binary files /dev/null and b/build-staging/de/img/devlog7_small.png differ diff --git a/build-staging/de/img/devlog8.png b/build-staging/de/img/devlog8.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/de/img/devlog8.png differ diff --git a/build-staging/de/img/devlog8_small.png b/build-staging/de/img/devlog8_small.png new file mode 100644 index 00000000..64d19eab Binary files /dev/null and b/build-staging/de/img/devlog8_small.png differ diff --git a/build-staging/de/img/devlog9.png b/build-staging/de/img/devlog9.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/de/img/devlog9.png differ diff --git a/build-staging/de/img/devlog9_small.png b/build-staging/de/img/devlog9_small.png new file mode 100644 index 00000000..4a1e749f Binary files /dev/null and b/build-staging/de/img/devlog9_small.png differ diff --git a/build-staging/de/img/dl7-after.png b/build-staging/de/img/dl7-after.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/de/img/dl7-after.png differ diff --git a/build-staging/de/img/dl7-before.png b/build-staging/de/img/dl7-before.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/de/img/dl7-before.png differ diff --git a/build-staging/de/img/docusaurus.png b/build-staging/de/img/docusaurus.png new file mode 100644 index 00000000..f458149e Binary files /dev/null and b/build-staging/de/img/docusaurus.png differ diff --git a/build-staging/de/img/done-24px.svg b/build-staging/de/img/done-24px.svg new file mode 100644 index 00000000..2ee44187 --- /dev/null +++ b/build-staging/de/img/done-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/drag_indicator-24px.svg b/build-staging/de/img/drag_indicator-24px.svg new file mode 100644 index 00000000..0559cf1d --- /dev/null +++ b/build-staging/de/img/drag_indicator-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/edit-24px.svg b/build-staging/de/img/edit-24px.svg new file mode 100644 index 00000000..1a7d71c7 --- /dev/null +++ b/build-staging/de/img/edit-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/enable_experiments.svg b/build-staging/de/img/enable_experiments.svg new file mode 100644 index 00000000..c94642b6 --- /dev/null +++ b/build-staging/de/img/enable_experiments.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/enable_groups.svg b/build-staging/de/img/enable_groups.svg new file mode 100644 index 00000000..94480604 --- /dev/null +++ b/build-staging/de/img/enable_groups.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/favicon.png b/build-staging/de/img/favicon.png new file mode 100644 index 00000000..df58306b Binary files /dev/null and b/build-staging/de/img/favicon.png differ diff --git a/build-staging/de/img/favorite-24px.svg b/build-staging/de/img/favorite-24px.svg new file mode 100644 index 00000000..1c334308 --- /dev/null +++ b/build-staging/de/img/favorite-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/favorite_black_24dp_broken.svg b/build-staging/de/img/favorite_black_24dp_broken.svg new file mode 100644 index 00000000..cf82b44c --- /dev/null +++ b/build-staging/de/img/favorite_black_24dp_broken.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/build-staging/de/img/group_settings-24px.svg b/build-staging/de/img/group_settings-24px.svg new file mode 100644 index 00000000..bc8e0f60 --- /dev/null +++ b/build-staging/de/img/group_settings-24px.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/build-staging/de/img/handbook-banner.png b/build-staging/de/img/handbook-banner.png new file mode 100644 index 00000000..2ef4021b Binary files /dev/null and b/build-staging/de/img/handbook-banner.png differ diff --git a/build-staging/de/img/handbook-banner_small.jpg b/build-staging/de/img/handbook-banner_small.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/de/img/handbook-banner_small.jpg differ diff --git a/build-staging/de/img/handbook-banner_small.png b/build-staging/de/img/handbook-banner_small.png new file mode 100644 index 00000000..c232310d Binary files /dev/null and b/build-staging/de/img/handbook-banner_small.png differ diff --git a/build-staging/de/img/info-24px.svg b/build-staging/de/img/info-24px.svg new file mode 100644 index 00000000..eb2424b5 --- /dev/null +++ b/build-staging/de/img/info-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/join_group.svg b/build-staging/de/img/join_group.svg new file mode 100644 index 00000000..d42dee0a --- /dev/null +++ b/build-staging/de/img/join_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/knott.png b/build-staging/de/img/knott.png new file mode 100644 index 00000000..e50812f7 Binary files /dev/null and b/build-staging/de/img/knott.png differ diff --git a/build-staging/de/img/linux.svg b/build-staging/de/img/linux.svg new file mode 100644 index 00000000..f81c7944 --- /dev/null +++ b/build-staging/de/img/linux.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/build-staging/de/img/lock-24px.svg b/build-staging/de/img/lock-24px.svg new file mode 100644 index 00000000..472bd965 --- /dev/null +++ b/build-staging/de/img/lock-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/lock_open-24px.svg b/build-staging/de/img/lock_open-24px.svg new file mode 100644 index 00000000..b26d7274 --- /dev/null +++ b/build-staging/de/img/lock_open-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/lock_open-24px.webp b/build-staging/de/img/lock_open-24px.webp new file mode 100644 index 00000000..a913757a Binary files /dev/null and b/build-staging/de/img/lock_open-24px.webp differ diff --git a/build-staging/de/img/logo.svg b/build-staging/de/img/logo.svg new file mode 100644 index 00000000..9db6d0d0 --- /dev/null +++ b/build-staging/de/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/manage_files.svg b/build-staging/de/img/manage_files.svg new file mode 100644 index 00000000..13edcfe6 --- /dev/null +++ b/build-staging/de/img/manage_files.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/menu-24px.svg b/build-staging/de/img/menu-24px.svg new file mode 100644 index 00000000..8525078d --- /dev/null +++ b/build-staging/de/img/menu-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/mood-24px.svg b/build-staging/de/img/mood-24px.svg new file mode 100644 index 00000000..655863fa --- /dev/null +++ b/build-staging/de/img/mood-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/more_vert-24px.svg b/build-staging/de/img/more_vert-24px.svg new file mode 100644 index 00000000..49c84995 --- /dev/null +++ b/build-staging/de/img/more_vert-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/negative_heart_24px.svg b/build-staging/de/img/negative_heart_24px.svg new file mode 100644 index 00000000..05f00c83 --- /dev/null +++ b/build-staging/de/img/negative_heart_24px.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/build-staging/de/img/peer_history.svg b/build-staging/de/img/peer_history.svg new file mode 100644 index 00000000..3c618c50 --- /dev/null +++ b/build-staging/de/img/peer_history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/peer_settings-24px.svg b/build-staging/de/img/peer_settings-24px.svg new file mode 100644 index 00000000..86d1c94f --- /dev/null +++ b/build-staging/de/img/peer_settings-24px.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/build-staging/de/img/person_add_alt_1-24px.svg b/build-staging/de/img/person_add_alt_1-24px.svg new file mode 100644 index 00000000..d9f3f0f2 --- /dev/null +++ b/build-staging/de/img/person_add_alt_1-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/picnic.png b/build-staging/de/img/picnic.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/de/img/picnic.png differ diff --git a/build-staging/de/img/picnic1.12.png b/build-staging/de/img/picnic1.12.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/de/img/picnic1.12.png differ diff --git a/build-staging/de/img/profiles/attributes-contact.png b/build-staging/de/img/profiles/attributes-contact.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/de/img/profiles/attributes-contact.png differ diff --git a/build-staging/de/img/profiles/attributes-empty.png b/build-staging/de/img/profiles/attributes-empty.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/de/img/profiles/attributes-empty.png differ diff --git a/build-staging/de/img/profiles/attributes-set.png b/build-staging/de/img/profiles/attributes-set.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/de/img/profiles/attributes-set.png differ diff --git a/build-staging/de/img/profiles/status-busy.png b/build-staging/de/img/profiles/status-busy.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/de/img/profiles/status-busy.png differ diff --git a/build-staging/de/img/profiles/status-tooltip-busy-set.png b/build-staging/de/img/profiles/status-tooltip-busy-set.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/de/img/profiles/status-tooltip-busy-set.png differ diff --git a/build-staging/de/img/profiles/status-tooltip-busy.png b/build-staging/de/img/profiles/status-tooltip-busy.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/de/img/profiles/status-tooltip-busy.png differ diff --git a/build-staging/de/img/profiles/status-tooltip.png b/build-staging/de/img/profiles/status-tooltip.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/de/img/profiles/status-tooltip.png differ diff --git a/build-staging/de/img/sarah.jpg b/build-staging/de/img/sarah.jpg new file mode 100644 index 00000000..ef603626 Binary files /dev/null and b/build-staging/de/img/sarah.jpg differ diff --git a/build-staging/de/img/search-24px.svg b/build-staging/de/img/search-24px.svg new file mode 100644 index 00000000..45ea1457 --- /dev/null +++ b/build-staging/de/img/search-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/send-24px.svg b/build-staging/de/img/send-24px.svg new file mode 100644 index 00000000..ba848bae --- /dev/null +++ b/build-staging/de/img/send-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/signal_cellular_4_bar-24px.svg b/build-staging/de/img/signal_cellular_4_bar-24px.svg new file mode 100644 index 00000000..7fa91cd3 --- /dev/null +++ b/build-staging/de/img/signal_cellular_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/signal_cellular_connected_no_internet_4_bar-24px.svg b/build-staging/de/img/signal_cellular_connected_no_internet_4_bar-24px.svg new file mode 100644 index 00000000..76788f92 --- /dev/null +++ b/build-staging/de/img/signal_cellular_connected_no_internet_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/signal_cellular_off-24px.svg b/build-staging/de/img/signal_cellular_off-24px.svg new file mode 100644 index 00000000..53a569e8 --- /dev/null +++ b/build-staging/de/img/signal_cellular_off-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/stickers-new.jpg b/build-staging/de/img/stickers-new.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/de/img/stickers-new.jpg differ diff --git a/build-staging/de/img/streamer_bunnymask.svg b/build-staging/de/img/streamer_bunnymask.svg new file mode 100644 index 00000000..345e3eae --- /dev/null +++ b/build-staging/de/img/streamer_bunnymask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/streamer_ghost.svg b/build-staging/de/img/streamer_ghost.svg new file mode 100644 index 00000000..c47a41e8 --- /dev/null +++ b/build-staging/de/img/streamer_ghost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/sync-24px.svg b/build-staging/de/img/sync-24px.svg new file mode 100644 index 00000000..514301f8 --- /dev/null +++ b/build-staging/de/img/sync-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/sync_disabled-24px.svg b/build-staging/de/img/sync_disabled-24px.svg new file mode 100644 index 00000000..36a97cbf --- /dev/null +++ b/build-staging/de/img/sync_disabled-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/sync_problem-24px.svg b/build-staging/de/img/sync_problem-24px.svg new file mode 100644 index 00000000..9eb870b0 --- /dev/null +++ b/build-staging/de/img/sync_problem-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/syncing-01.svg b/build-staging/de/img/syncing-01.svg new file mode 100644 index 00000000..f9eb9791 --- /dev/null +++ b/build-staging/de/img/syncing-01.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/de/img/syncing-02.svg b/build-staging/de/img/syncing-02.svg new file mode 100644 index 00000000..4ae41d5c --- /dev/null +++ b/build-staging/de/img/syncing-02.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/de/img/syncing-03.svg b/build-staging/de/img/syncing-03.svg new file mode 100644 index 00000000..d4313757 --- /dev/null +++ b/build-staging/de/img/syncing-03.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/de/img/toggle_on-24px.svg b/build-staging/de/img/toggle_on-24px.svg new file mode 100644 index 00000000..5da416c4 --- /dev/null +++ b/build-staging/de/img/toggle_on-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/de/img/undraw_docusaurus_mountain.svg b/build-staging/de/img/undraw_docusaurus_mountain.svg new file mode 100644 index 00000000..af961c49 --- /dev/null +++ b/build-staging/de/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/de/img/undraw_docusaurus_react.svg b/build-staging/de/img/undraw_docusaurus_react.svg new file mode 100644 index 00000000..94b5cf08 --- /dev/null +++ b/build-staging/de/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/de/img/undraw_docusaurus_tree.svg b/build-staging/de/img/undraw_docusaurus_tree.svg new file mode 100644 index 00000000..d9161d33 --- /dev/null +++ b/build-staging/de/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/de/img/windows.png b/build-staging/de/img/windows.png new file mode 100644 index 00000000..e3ffef93 Binary files /dev/null and b/build-staging/de/img/windows.png differ diff --git a/build-staging/de/img/windows.svg b/build-staging/de/img/windows.svg new file mode 100644 index 00000000..ad0ad190 --- /dev/null +++ b/build-staging/de/img/windows.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + diff --git a/build-staging/de/index.html b/build-staging/de/index.html new file mode 100644 index 00000000..baf023f5 --- /dev/null +++ b/build-staging/de/index.html @@ -0,0 +1,24 @@ + + + + + +The Cwtch Handbook | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/katex/fonts/KaTeX_AMS-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_AMS-Regular.ttf new file mode 100644 index 00000000..c6f9a5e7 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_AMS-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_AMS-Regular.woff b/build-staging/de/katex/fonts/KaTeX_AMS-Regular.woff new file mode 100644 index 00000000..b804d7b3 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_AMS-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_AMS-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 00000000..0acaaff0 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_AMS-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.ttf b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.ttf new file mode 100644 index 00000000..9ff4a5e0 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.woff b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.woff new file mode 100644 index 00000000..9759710d Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.woff2 b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.woff2 new file mode 100644 index 00000000..f390922e Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Bold.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.ttf new file mode 100644 index 00000000..f522294f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.woff new file mode 100644 index 00000000..9bdd534f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 00000000..75344a1f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Caligraphic-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.ttf b/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.ttf new file mode 100644 index 00000000..4e98259c Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.woff b/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.woff new file mode 100644 index 00000000..e7730f66 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 00000000..395f28be Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Fraktur-Bold.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.ttf new file mode 100644 index 00000000..b8461b27 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.woff new file mode 100644 index 00000000..acab069f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.woff2 new file mode 100644 index 00000000..735f6948 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Fraktur-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Bold.ttf b/build-staging/de/katex/fonts/KaTeX_Main-Bold.ttf new file mode 100644 index 00000000..4060e627 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Bold.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Bold.woff b/build-staging/de/katex/fonts/KaTeX_Main-Bold.woff new file mode 100644 index 00000000..f38136ac Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Bold.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Bold.woff2 b/build-staging/de/katex/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 00000000..ab2ad21d Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Bold.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.ttf b/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.ttf new file mode 100644 index 00000000..dc007977 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.woff b/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.woff new file mode 100644 index 00000000..67807b0b Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.woff2 b/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.woff2 new file mode 100644 index 00000000..5931794d Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-BoldItalic.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Italic.ttf b/build-staging/de/katex/fonts/KaTeX_Main-Italic.ttf new file mode 100644 index 00000000..0e9b0f35 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Italic.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Italic.woff b/build-staging/de/katex/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 00000000..6f43b594 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Italic.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Italic.woff2 b/build-staging/de/katex/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 00000000..b50920e1 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Italic.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Main-Regular.ttf new file mode 100644 index 00000000..dd45e1ed Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Main-Regular.woff new file mode 100644 index 00000000..21f58129 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Main-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 00000000..eb24a7ba Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Main-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.ttf b/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.ttf new file mode 100644 index 00000000..728ce7a1 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.woff b/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 00000000..0ae390d7 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 00000000..29657023 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Math-BoldItalic.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Math-Italic.ttf b/build-staging/de/katex/fonts/KaTeX_Math-Italic.ttf new file mode 100644 index 00000000..70d559b4 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Math-Italic.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Math-Italic.woff b/build-staging/de/katex/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 00000000..eb5159d4 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Math-Italic.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Math-Italic.woff2 b/build-staging/de/katex/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 00000000..215c143f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Math-Italic.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.ttf b/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.ttf new file mode 100644 index 00000000..2f65a8a3 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.woff b/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.woff new file mode 100644 index 00000000..8d47c02d Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 00000000..cfaa3bda Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Bold.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.ttf b/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.ttf new file mode 100644 index 00000000..d5850df9 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.woff b/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 00000000..7e02df96 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.woff2 b/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 00000000..349c06dc Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Italic.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.ttf new file mode 100644 index 00000000..537279f6 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.woff b/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.woff new file mode 100644 index 00000000..31b84829 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 00000000..a90eea85 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_SansSerif-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Script-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Script-Regular.ttf new file mode 100644 index 00000000..fd679bf3 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Script-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Script-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 00000000..0e7da821 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Script-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Script-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 00000000..b3048fc1 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Script-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size1-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Size1-Regular.ttf new file mode 100644 index 00000000..871fd7d1 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size1-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size1-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Size1-Regular.woff new file mode 100644 index 00000000..7f292d91 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size1-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size1-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 00000000..c5a8462f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size1-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size2-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Size2-Regular.ttf new file mode 100644 index 00000000..7a212caf Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size2-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size2-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Size2-Regular.woff new file mode 100644 index 00000000..d241d9be Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size2-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size2-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 00000000..e1bccfe2 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size2-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size3-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Size3-Regular.ttf new file mode 100644 index 00000000..00bff349 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size3-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size3-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Size3-Regular.woff new file mode 100644 index 00000000..e6e9b658 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size3-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size3-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Size3-Regular.woff2 new file mode 100644 index 00000000..249a2866 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size3-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size4-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Size4-Regular.ttf new file mode 100644 index 00000000..74f08921 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size4-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size4-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 00000000..e1ec5457 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size4-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Size4-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 00000000..680c1308 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Size4-Regular.woff2 differ diff --git a/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.ttf b/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.ttf new file mode 100644 index 00000000..c83252c5 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.ttf differ diff --git a/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.woff b/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 00000000..2432419f Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.woff differ diff --git a/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.woff2 b/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 00000000..771f1af7 Binary files /dev/null and b/build-staging/de/katex/fonts/KaTeX_Typewriter-Regular.woff2 differ diff --git a/build-staging/de/katex/katex.min.css b/build-staging/de/katex/katex.min.css new file mode 100644 index 00000000..f7ebca1f --- /dev/null +++ b/build-staging/de/katex/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.13.24"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/build-staging/de/katex/katex.min.js b/build-staging/de/katex/katex.min.js new file mode 100644 index 00000000..2d04ed3b --- /dev/null +++ b/build-staging/de/katex/katex.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return _n}});var r=function e(t,r){this.position=void 0;var n,a="KaTeX parse error: "+t,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;n=i.start;var s=i.end;n===o.length?a+=" at end of input: ":a+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332");a+=(n>15?"\u2026"+o.slice(n-15,n):o.slice(0,n))+l+(s+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;var s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(o,(function(e){return i[e]}))},hyphenate:function(e){return e.replace(a,"-$1").toLowerCase()},getBaseElem:s,isCharacterBox:function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"}},h=function(){function e(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},this.displayMode=l.deflt(e.displayMode,!1),this.output=l.deflt(e.output,"htmlAndMathml"),this.leqno=l.deflt(e.leqno,!1),this.fleqn=l.deflt(e.fleqn,!1),this.throwOnError=l.deflt(e.throwOnError,!0),this.errorColor=l.deflt(e.errorColor,"#cc0000"),this.macros=e.macros||{},this.minRuleThickness=Math.max(0,l.deflt(e.minRuleThickness,0)),this.colorIsTextColor=l.deflt(e.colorIsTextColor,!1),this.strict=l.deflt(e.strict,"warn"),this.trust=l.deflt(e.trust,!1),this.maxSize=Math.max(0,l.deflt(e.maxSize,1/0)),this.maxExpand=Math.max(0,l.deflt(e.maxExpand,1e3)),this.globalGroup=l.deflt(e.globalGroup,!1)}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=l.protocolFromUrl(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),m=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return c[u[this.id]]},t.sub=function(){return c[p[this.id]]},t.fracNum=function(){return c[d[this.id]]},t.fracDen=function(){return c[f[this.id]]},t.cramp=function(){return c[g[this.id]]},t.text=function(){return c[v[this.id]]},t.isTight=function(){return this.size>=2},e}(),c=[new m(0,0,!1),new m(1,0,!0),new m(2,1,!1),new m(3,1,!0),new m(4,2,!1),new m(5,2,!0),new m(6,3,!1),new m(7,3,!0)],u=[4,5,4,5,6,7,6,7],p=[5,5,5,5,7,7,7,7],d=[2,3,4,5,6,7,6,7],f=[3,3,5,5,7,7,7,7],g=[1,1,3,3,5,5,7,7],v=[0,1,2,3,2,3,2,3],b={DISPLAY:c[0],TEXT:c[2],SCRIPT:c[4],SCRIPTSCRIPT:c[6]},y=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var x=[];function w(e){for(var t=0;t=x[t]&&e<=x[t+1])return!0;return!1}y.forEach((function(e){return e.blocks.forEach((function(e){return x.push.apply(x,e)}))}));var k=80,S={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},M=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=q[t]={cssEmPerMu:A.quad[t]/18};for(var n in A)A.hasOwnProperty(n)&&(r[n]=A[n][t])}return q[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();R.BASESIZE=6;var O=R,E={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},H={ex:!0,em:!0,mu:!0},L=function(e){return"string"!=typeof e&&(e=e.unit),e in E||e in H||"ex"===e},D=function(e,t){var r;if(e.unit in E)r=E[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},P=function(e){return+e.toFixed(4)+"em"},F=function(e){return e.filter((function(e){return e})).join(" ")},V=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},G=function(e){var t=document.createElement(e);for(var r in t.className=F(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},Y=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"span")},t.toMarkup=function(){return U.call(this,"span")},e}(),W=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"a")},t.toMarkup=function(){return U.call(this,"a")},e}(),X=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+"=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=_[this.text])}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=P(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=F(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=l.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');var a=l.escape(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),$=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r":""},e}(),K=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e="","\\gt",!0),ne(ae,oe,ge,"\u2208","\\in",!0),ne(ae,oe,ge,"\ue020","\\@not"),ne(ae,oe,ge,"\u2282","\\subset",!0),ne(ae,oe,ge,"\u2283","\\supset",!0),ne(ae,oe,ge,"\u2286","\\subseteq",!0),ne(ae,oe,ge,"\u2287","\\supseteq",!0),ne(ae,se,ge,"\u2288","\\nsubseteq",!0),ne(ae,se,ge,"\u2289","\\nsupseteq",!0),ne(ae,oe,ge,"\u22a8","\\models"),ne(ae,oe,ge,"\u2190","\\leftarrow",!0),ne(ae,oe,ge,"\u2264","\\le"),ne(ae,oe,ge,"\u2264","\\leq",!0),ne(ae,oe,ge,"<","\\lt",!0),ne(ae,oe,ge,"\u2192","\\rightarrow",!0),ne(ae,oe,ge,"\u2192","\\to"),ne(ae,se,ge,"\u2271","\\ngeq",!0),ne(ae,se,ge,"\u2270","\\nleq",!0),ne(ae,oe,ve,"\xa0","\\ "),ne(ae,oe,ve,"\xa0","\\space"),ne(ae,oe,ve,"\xa0","\\nobreakspace"),ne(ie,oe,ve,"\xa0","\\ "),ne(ie,oe,ve,"\xa0"," "),ne(ie,oe,ve,"\xa0","\\space"),ne(ie,oe,ve,"\xa0","\\nobreakspace"),ne(ae,oe,ve,null,"\\nobreak"),ne(ae,oe,ve,null,"\\allowbreak"),ne(ae,oe,fe,",",","),ne(ae,oe,fe,";",";"),ne(ae,se,he,"\u22bc","\\barwedge",!0),ne(ae,se,he,"\u22bb","\\veebar",!0),ne(ae,oe,he,"\u2299","\\odot",!0),ne(ae,oe,he,"\u2295","\\oplus",!0),ne(ae,oe,he,"\u2297","\\otimes",!0),ne(ae,oe,be,"\u2202","\\partial",!0),ne(ae,oe,he,"\u2298","\\oslash",!0),ne(ae,se,he,"\u229a","\\circledcirc",!0),ne(ae,se,he,"\u22a1","\\boxdot",!0),ne(ae,oe,he,"\u25b3","\\bigtriangleup"),ne(ae,oe,he,"\u25bd","\\bigtriangledown"),ne(ae,oe,he,"\u2020","\\dagger"),ne(ae,oe,he,"\u22c4","\\diamond"),ne(ae,oe,he,"\u22c6","\\star"),ne(ae,oe,he,"\u25c3","\\triangleleft"),ne(ae,oe,he,"\u25b9","\\triangleright"),ne(ae,oe,de,"{","\\{"),ne(ie,oe,be,"{","\\{"),ne(ie,oe,be,"{","\\textbraceleft"),ne(ae,oe,me,"}","\\}"),ne(ie,oe,be,"}","\\}"),ne(ie,oe,be,"}","\\textbraceright"),ne(ae,oe,de,"{","\\lbrace"),ne(ae,oe,me,"}","\\rbrace"),ne(ae,oe,de,"[","\\lbrack",!0),ne(ie,oe,be,"[","\\lbrack",!0),ne(ae,oe,me,"]","\\rbrack",!0),ne(ie,oe,be,"]","\\rbrack",!0),ne(ae,oe,de,"(","\\lparen",!0),ne(ae,oe,me,")","\\rparen",!0),ne(ie,oe,be,"<","\\textless",!0),ne(ie,oe,be,">","\\textgreater",!0),ne(ae,oe,de,"\u230a","\\lfloor",!0),ne(ae,oe,me,"\u230b","\\rfloor",!0),ne(ae,oe,de,"\u2308","\\lceil",!0),ne(ae,oe,me,"\u2309","\\rceil",!0),ne(ae,oe,be,"\\","\\backslash"),ne(ae,oe,be,"\u2223","|"),ne(ae,oe,be,"\u2223","\\vert"),ne(ie,oe,be,"|","\\textbar",!0),ne(ae,oe,be,"\u2225","\\|"),ne(ae,oe,be,"\u2225","\\Vert"),ne(ie,oe,be,"\u2225","\\textbardbl"),ne(ie,oe,be,"~","\\textasciitilde"),ne(ie,oe,be,"\\","\\textbackslash"),ne(ie,oe,be,"^","\\textasciicircum"),ne(ae,oe,ge,"\u2191","\\uparrow",!0),ne(ae,oe,ge,"\u21d1","\\Uparrow",!0),ne(ae,oe,ge,"\u2193","\\downarrow",!0),ne(ae,oe,ge,"\u21d3","\\Downarrow",!0),ne(ae,oe,ge,"\u2195","\\updownarrow",!0),ne(ae,oe,ge,"\u21d5","\\Updownarrow",!0),ne(ae,oe,pe,"\u2210","\\coprod"),ne(ae,oe,pe,"\u22c1","\\bigvee"),ne(ae,oe,pe,"\u22c0","\\bigwedge"),ne(ae,oe,pe,"\u2a04","\\biguplus"),ne(ae,oe,pe,"\u22c2","\\bigcap"),ne(ae,oe,pe,"\u22c3","\\bigcup"),ne(ae,oe,pe,"\u222b","\\int"),ne(ae,oe,pe,"\u222b","\\intop"),ne(ae,oe,pe,"\u222c","\\iint"),ne(ae,oe,pe,"\u222d","\\iiint"),ne(ae,oe,pe,"\u220f","\\prod"),ne(ae,oe,pe,"\u2211","\\sum"),ne(ae,oe,pe,"\u2a02","\\bigotimes"),ne(ae,oe,pe,"\u2a01","\\bigoplus"),ne(ae,oe,pe,"\u2a00","\\bigodot"),ne(ae,oe,pe,"\u222e","\\oint"),ne(ae,oe,pe,"\u222f","\\oiint"),ne(ae,oe,pe,"\u2230","\\oiiint"),ne(ae,oe,pe,"\u2a06","\\bigsqcup"),ne(ae,oe,pe,"\u222b","\\smallint"),ne(ie,oe,ce,"\u2026","\\textellipsis"),ne(ae,oe,ce,"\u2026","\\mathellipsis"),ne(ie,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u22ef","\\@cdots",!0),ne(ae,oe,ce,"\u22f1","\\ddots",!0),ne(ae,oe,be,"\u22ee","\\varvdots"),ne(ae,oe,le,"\u02ca","\\acute"),ne(ae,oe,le,"\u02cb","\\grave"),ne(ae,oe,le,"\xa8","\\ddot"),ne(ae,oe,le,"~","\\tilde"),ne(ae,oe,le,"\u02c9","\\bar"),ne(ae,oe,le,"\u02d8","\\breve"),ne(ae,oe,le,"\u02c7","\\check"),ne(ae,oe,le,"^","\\hat"),ne(ae,oe,le,"\u20d7","\\vec"),ne(ae,oe,le,"\u02d9","\\dot"),ne(ae,oe,le,"\u02da","\\mathring"),ne(ae,oe,ue,"\ue131","\\@imath"),ne(ae,oe,ue,"\ue237","\\@jmath"),ne(ae,oe,be,"\u0131","\u0131"),ne(ae,oe,be,"\u0237","\u0237"),ne(ie,oe,be,"\u0131","\\i",!0),ne(ie,oe,be,"\u0237","\\j",!0),ne(ie,oe,be,"\xdf","\\ss",!0),ne(ie,oe,be,"\xe6","\\ae",!0),ne(ie,oe,be,"\u0153","\\oe",!0),ne(ie,oe,be,"\xf8","\\o",!0),ne(ie,oe,be,"\xc6","\\AE",!0),ne(ie,oe,be,"\u0152","\\OE",!0),ne(ie,oe,be,"\xd8","\\O",!0),ne(ie,oe,le,"\u02ca","\\'"),ne(ie,oe,le,"\u02cb","\\`"),ne(ie,oe,le,"\u02c6","\\^"),ne(ie,oe,le,"\u02dc","\\~"),ne(ie,oe,le,"\u02c9","\\="),ne(ie,oe,le,"\u02d8","\\u"),ne(ie,oe,le,"\u02d9","\\."),ne(ie,oe,le,"\xb8","\\c"),ne(ie,oe,le,"\u02da","\\r"),ne(ie,oe,le,"\u02c7","\\v"),ne(ie,oe,le,"\xa8",'\\"'),ne(ie,oe,le,"\u02dd","\\H"),ne(ie,oe,le,"\u25ef","\\textcircled");var ye={"--":!0,"---":!0,"``":!0,"''":!0};ne(ie,oe,be,"\u2013","--",!0),ne(ie,oe,be,"\u2013","\\textendash"),ne(ie,oe,be,"\u2014","---",!0),ne(ie,oe,be,"\u2014","\\textemdash"),ne(ie,oe,be,"\u2018","`",!0),ne(ie,oe,be,"\u2018","\\textquoteleft"),ne(ie,oe,be,"\u2019","'",!0),ne(ie,oe,be,"\u2019","\\textquoteright"),ne(ie,oe,be,"\u201c","``",!0),ne(ie,oe,be,"\u201c","\\textquotedblleft"),ne(ie,oe,be,"\u201d","''",!0),ne(ie,oe,be,"\u201d","\\textquotedblright"),ne(ae,oe,be,"\xb0","\\degree",!0),ne(ie,oe,be,"\xb0","\\degree"),ne(ie,oe,be,"\xb0","\\textdegree",!0),ne(ae,oe,be,"\xa3","\\pounds"),ne(ae,oe,be,"\xa3","\\mathsterling",!0),ne(ie,oe,be,"\xa3","\\pounds"),ne(ie,oe,be,"\xa3","\\textsterling",!0),ne(ae,se,be,"\u2720","\\maltese"),ne(ie,se,be,"\u2720","\\maltese");for(var xe='0123456789/@."',we=0;wet&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Ue=function(e,t,r,n){var a=new Y(e,t,r,n);return Ge(a),a},Ye=function(e,t,r,n){return new Y(e,t,r,n)},We=function(e){var t=new M(e);return Ge(t),t},Xe=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},_e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},je={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},$e={fontMap:_e,makeSymbol:Fe,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Pe(e,"Main-Bold",t).metrics?Fe(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===re[t][e].font?Fe(e,"Main-Regular",t,r,n):Fe(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:Ue,makeSvgSpan:Ye,makeLineSpan:function(e,t,r){var n=Ue([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=P(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new W(e,t,r,n);return Ge(a),a},makeFragment:We,wrapFragment:function(e,t){return e instanceof M?Ue([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(xt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(xt(s,t)),r?((i=xt(pt(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var m=lt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=P(m.height+m.depth),m.depth&&(c.style.verticalAlign=P(-m.depth))}return m}function kt(e){return new M(e)}var St=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=F(this.classes));for(var r=0;r0&&(e+=' class ="'+l.escape(F(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),Mt=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return l.escape(this.toText())},t.toText=function(){return this.text},e}(),zt={MathNode:St,TextNode:Mt,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",P(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:kt},At=function(e,t,r){return!re[t][e]||!re[t][e].replace||55349===e.charCodeAt(0)||ye.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(e=re[t][e].replace),new zt.TextNode(e)},Tt=function(e){return 1===e.length?e[0]:new zt.MathNode("mrow",e)},Bt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l.contains(["\\imath","\\jmath"],a)?null:(re[n][a]&&re[n][a].replace&&(a=re[n][a].replace),B(a,$e.fontMap[r].fontName,n)?$e.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var n=Ct(e[0],t);return r&&n instanceof St&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},Nt=function(e,t,r){return Tt(qt(e,t,r))},Ct=function(e,t){if(!e)return new zt.MathNode("mrow");if(nt[e.type])return nt[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function It(e,t,r,n,a){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof St&&l.contains(["mrow","mtable"],o[0].type)?o[0]:new zt.MathNode("mrow",o);var s=new zt.MathNode("annotation",[new zt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new zt.MathNode("semantics",[i,s]),m=new zt.MathNode("math",[h]);m.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&m.setAttribute("display","block");var c=a?"katex":"katex-mathml";return $e.makeSpan([c],[m])}var Rt=function(e){return new O({style:e.displayMode?b.DISPLAY:b.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Ot=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=$e.makeSpan(r,[e])}return e},Et=function(e,t,r){var n,a=Rt(r);if("mathml"===r.output)return It(e,t,a,r.displayMode,!0);if("html"===r.output){var i=wt(e,a);n=$e.makeSpan(["katex"],[i])}else{var o=It(e,t,a,r.displayMode,!1),s=wt(e,a);n=$e.makeSpan(["katex"],[o,s])}return Ot(n,r)},Ht={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Lt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Dt=function(e,t,r,n,a){var i,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(i=$e.makeSpan(["stretchy",t],[],a),"fbox"===t){var s=a.color&&a.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new K({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new K({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new $(l,{width:"100%",height:P(o)});i=$e.makeSvgSpan([],[h],a)}return i.height=o,i.style.height=P(o),i},Pt=function(e){var t=new zt.MathNode("mo",[new zt.TextNode(Ht[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var r=function(){var r=4e5,n=e.label.substr(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var m=new Z(i),c=new $([m],{width:"100%",height:P(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:$e.makeSvgSpan([],[c],t),minWidth:0,height:o}}var u,p,d,f=[],g=Lt[n],v=g[0],b=g[1],y=g[2],x=y/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=P(a)),n};function Vt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Gt(e){var t=Ut(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Ut(e){return e&&("atom"===e.type||ee.hasOwnProperty(e.type))?e:null}var Yt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Vt(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof Y)return e;throw new Error("Expected span but got "+String(e)+".")}(yt(e,t)),e.base=n):r=(n=Vt(e,"accent")).base;var i=yt(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&l.isCharacterBox(r)){var s=l.getBaseElem(r);o=J(yt(s,t.havingCrampedStyle())).skew}var h,m="\\c"===n.label,c=m?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)h=Ft(n,t),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+P(2*o)+")",marginLeft:P(2*o)}:void 0}]},t);else{var u,p;"\\vec"===n.label?(u=$e.staticSvg("vec",t),p=$e.svgData.vec[1]):((u=J(u=$e.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,p=u.width,m&&(c+=u.depth)),h=$e.makeSpan(["accent-body"],[u]);var d="\\textcircled"===n.label;d&&(h.classes.push("accent-full"),c=i.height);var f=o;d||(f-=p/2),h.style.left=P(f),"\\textcircled"===n.label&&(h.style.top=".2em"),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}var g=$e.makeSpan(["mord","accent"],[h],t);return a?(a.children[0]=g,a.height=Math.max(g.height,a.height),a.classes[0]="mord",a):g},Wt=function(e,t){var r=e.isStretchy?Pt(e.label):new zt.MathNode("mo",[At(e.label,e.mode)]),n=new zt.MathNode("mover",[Ct(e.base,t),r]);return n.setAttribute("accent","true"),n},Xt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));at({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=ot(t[0]),n=!Xt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=yt(e.base,t),n=Ft(e,t),a="\\utilde"===e.label?.12:0,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Pt(e.label),n=new zt.MathNode("munder",[Ct(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var _t=function(e){var t=new zt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};at({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=$e.wrapFragment(yt(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=$e.wrapFragment(yt(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),$e.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Pt(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=_t(Ct(e.body,t));if(e.below){var i=_t(Ct(e.below,t));r=new zt.MathNode("munderover",[n,i,a])}else r=new zt.MathNode("mover",[n,a])}else if(e.below){var o=_t(Ct(e.below,t));r=new zt.MathNode("munder",[n,o])}else r=_t(),r=new zt.MathNode("mover",[n,r]);return r}});var jt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},$t=function(e){return"textord"===e.type&&"@"===e.text};function Zt(e,t,r){var n=jt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}at({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=$e.wrapFragment(yt(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=P(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new zt.MathNode("mrow",[Ct(e.label,t)]);return(r=new zt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new zt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),at({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=$e.wrapFragment(yt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new zt.MathNode("mrow",[Ct(e.fragment,t)])}}),at({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Vt(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var Kt=function(e,t){var r=pt(e.body,t.withColor(e.color),!1);return $e.makeFragment(r)},Jt=function(e,t){var r=qt(e.body,t.withColor(e.color)),n=new zt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};at({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Vt(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:st(a)}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Vt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=r[0],i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Vt(a,"size").value}},htmlBuilder:function(e,t){var r=$e.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=P(D(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new zt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",P(D(e.size,t)))),r}});var Qt={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},er=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},tr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};at({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(Qt[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=Qt[a.text]),Vt(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),at({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===Qt[r]),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return tr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return tr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var rr=function(e,t,r){var n=B(re.math[e]&&re.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},nr=function(e,t,r,n){var a=r.havingBaseStyle(t),i=$e.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},ar=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=P(a),e.height-=a,e.depth+=a},ir=function(e,t,r,n,a,i){var o=function(e,t,r,n){return $e.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=nr($e.makeSpan(["delimsizing","size"+t],[o],n),b.TEXT,n,i);return r&&ar(s,n,b.TEXT),s},or=function(e,t,r){var n;return n="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:$e.makeSpan(["delimsizinginner",n],[$e.makeSpan([],[$e.makeSymbol(e,t,r)])])}},sr=function(e,t,r){var n=z["Size4-Regular"][e.charCodeAt(0)]?z["Size4-Regular"][e.charCodeAt(0)][4]:z["Size1-Regular"][e.charCodeAt(0)][4],a=new Z("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new $([a],{width:P(n),height:P(t),style:"width:"+P(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=$e.makeSvgSpan([],[i],r);return o.height=t,o.style.height=P(t),o.style.width=P(n),{type:"elem",elem:o}},lr={type:"kern",size:-.008},hr=["|","\\lvert","\\rvert","\\vert"],mr=["\\|","\\lVert","\\rVert","\\Vert"],cr=function(e,t,r,n,a,i){var o,s,h,m;o=h=m=e,s=null;var c="Size1-Regular";"\\uparrow"===e?h=m="\u23d0":"\\Uparrow"===e?h=m="\u2016":"\\downarrow"===e?o=h="\u23d0":"\\Downarrow"===e?o=h="\u2016":"\\updownarrow"===e?(o="\\uparrow",h="\u23d0",m="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="\u2016",m="\\Downarrow"):l.contains(hr,e)?h="\u2223":l.contains(mr,e)?h="\u2225":"["===e||"\\lbrack"===e?(o="\u23a1",h="\u23a2",m="\u23a3",c="Size4-Regular"):"]"===e||"\\rbrack"===e?(o="\u23a4",h="\u23a5",m="\u23a6",c="Size4-Regular"):"\\lfloor"===e||"\u230a"===e?(h=o="\u23a2",m="\u23a3",c="Size4-Regular"):"\\lceil"===e||"\u2308"===e?(o="\u23a1",h=m="\u23a2",c="Size4-Regular"):"\\rfloor"===e||"\u230b"===e?(h=o="\u23a5",m="\u23a6",c="Size4-Regular"):"\\rceil"===e||"\u2309"===e?(o="\u23a4",h=m="\u23a5",c="Size4-Regular"):"("===e||"\\lparen"===e?(o="\u239b",h="\u239c",m="\u239d",c="Size4-Regular"):")"===e||"\\rparen"===e?(o="\u239e",h="\u239f",m="\u23a0",c="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",m="\u23a9",h="\u23aa",c="Size4-Regular");var u=rr(o,c,a),p=u.height+u.depth,d=rr(h,c,a),f=d.height+d.depth,g=rr(m,c,a),v=g.height+g.depth,y=0,x=1;if(null!==s){var w=rr(s,c,a);y=w.height+w.depth,x=2}var k=p+v+y,S=k+Math.max(0,Math.ceil((t-k)/(x*f)))*x*f,M=n.fontMetrics().axisHeight;r&&(M*=n.sizeMultiplier);var z=S/2-M,A=[];if(A.push(or(m,c,a)),A.push(lr),null===s){var T=S-p-v+.016;A.push(sr(h,T,n))}else{var B=(S-p-v-y)/2+.016;A.push(sr(h,B,n)),A.push(lr),A.push(or(s,c,a)),A.push(lr),A.push(sr(h,B,n))}A.push(lr),A.push(or(o,c,a));var q=n.havingBaseStyle(b.TEXT),N=$e.makeVList({positionType:"bottom",positionData:z,children:A},q);return nr($e.makeSpan(["delimsizing","mult"],[N],q),b.TEXT,n,i)},ur=.08,pr=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,k);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,k,r)}return n}(e,n,r),o=new Z(e,i),s=new $([o],{width:"400em",height:P(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return $e.makeSvgSpan(["hide-tail"],[s],a)},dr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],fr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],gr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],vr=[0,1.2,1.8,2.4,3],br=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],yr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"stack"}],xr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],wr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},kr=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},Sr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=l.contains(gr,e)?br:l.contains(dr,e)?xr:yr;var s=kr(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=$e.makeSymbol(e,"Main-Regular",a,n),s=nr(o,t,n,i);return r&&ar(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?ir(e,s.size,r,n,a,i):cr(e,t,r,n,a,i)},Mr={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=kr("\\surd",e*a.sizeMultiplier,xr,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=pr("sqrtMain",l=(1+s+ur)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(m=1080*vr[i.size],h=(vr[i.size]+s)/o,l=(vr[i.size]+s+ur)/o,(r=pr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+ur,h=e+s,m=Math.floor(1e3*e+s)+80,(r=pr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=P(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(dr,e)||l.contains(gr,e))return ir(e,t,!1,r,a,i);if(l.contains(fr,e))return cr(e,vr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:vr,customSizedDelim:Sr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Sr(e,h,!0,n,a,i)}},zr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Ar=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Tr(e,t){var r=Ut(e);if(r&&l.contains(Ar,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Br(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}at({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Tr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:zr[e.funcName].size,mclass:zr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?$e.makeSpan([e.mclass]):Mr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(At(e.delim,e.mode));var r=new zt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=P(Mr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),at({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Tr(t[0],e).text,color:r}}}),at({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Tr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Vt(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){Br(e);for(var r,n,a=pt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Ct(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};at({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=Vt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),at({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Cr={};function Ir(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!c)&&g.pop(),b.length0&&(x+=.25),m.push({pos:x,isDashed:e[t]})}for(w(o[0]),r=0;r0&&(M<(B+=y)&&(M=B),B=0),e.addJot&&(M+=f),z.height=S,z.depth=M,x+=S,z.pos=x,x+=M+B,h[r]=z,w(o[r+1])}var q,N,C=x/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],O=[];if(e.addEqnNum)for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=l.deflt(F.pregap,p))&&((q=$e.makeSpan(["arraycolsep"],[])).style.width=P(W),R.push(q));var X=[];for(r=0;r0){for(var Z=$e.makeLineSpan("hline",t,c),K=$e.makeLineSpan("hdashline",t,c),J=[{type:"elem",elem:h,shift:0}];m.length>0;){var Q=m.pop(),ee=Q.pos-C;Q.isDashed?J.push({type:"elem",elem:K,shift:ee}):J.push({type:"elem",elem:Z,shift:ee})}h=$e.makeVList({positionType:"individualShift",children:J},t)}if(e.addEqnNum){var te=$e.makeVList({positionType:"individualShift",children:O},t);return te=$e.makeSpan(["tag"],[te],t),$e.makeFragment([h,te])}return $e.makeSpan(["mord"],[h],t)},Dr={c:"center ",l:"left ",r:"right "},Pr=function(e,t){for(var r=[],n=new zt.MathNode("mtd",[],["mtr-glue"]),a=new zt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(c+="top ",g=1),"separator"===p[p.length-1].type&&(c+="bottom ",v-=1);for(var b=g;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o=Er(e.parser,{cols:a,addJot:!0,addEqnNum:"align"===e.envName||"alignat"===e.envName,emptySingleRow:!0,colSeparationType:i,maxNumCols:"split"===e.envName?2:void 0,leqno:e.parser.settings.leqno},"display"),s=0,l={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var h="",m=0;m0&&c&&(d=1),a[u]={type:"align",align:p,pregap:d,postgap:0}}return o.colSeparationType=c?"align":"alignat",o};Ir({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Er(e.parser,a,Hr(e.envName))},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Er(e.parser,a,Hr(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Er(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Hr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l.contains(["gather","gather*"],e.envName)&&Or(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",addEqnNum:"gather"===e.envName,emptySingleRow:!0,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Or(e);var t={addEqnNum:"equation"===e.envName,emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Or(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var f=!0,g=c+1;g=b.SCRIPT.id?r.text():b.DISPLAY:"text"===e&&r.size===b.DISPLAY.size?r=b.TEXT:"script"===e?r=b.SCRIPT:"scriptscript"===e&&(r=b.SCRIPTSCRIPT),r},Zr=function(e,t){var r,n=$r(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=yt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(u=t.fontMetrics().num2,p=c):(u=t.fontMetrics().num3,p=3*c),d=t.fontMetrics().denom2),h){var w=t.fontMetrics().axisHeight;u-o.depth-(w+.5*m)0&&(t="."===(t=e)?null:t),t};at({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=ot(t[0]),s="atom"===o.type&&"open"===o.family?Qr(o.text):null,l=ot(t[1]),h="atom"===l.type&&"close"===l.family?Qr(l.text):null,m=Vt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Vt(p.body[0],"textord");u=Jr[Number(d.text)]}}else p=Vt(p,"textord"),u=Jr[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:Zr,mathmlBuilder:Kr}),at({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Vt(t[0],"size").value,token:n}}}),at({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Vt(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Zr,mathmlBuilder:Kr});var en=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?yt(e.sup,t.havingStyle(a.sup()),t):yt(e.sub,t.havingStyle(a.sub()),t),n=Vt(e.base,"horizBrace")):n=Vt(e,"horizBrace");var i,o=yt(n.base,t.havingBaseStyle(b.DISPLAY)),s=Ft(n,t);if(n.isOver?(i=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=$e.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=$e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):$e.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return $e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};at({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:en,mathmlBuilder:function(e,t){var r=Pt(e.label);return new zt.MathNode(e.isOver?"mover":"munder",[Ct(e.base,t),r])}}),at({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Vt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:st(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=pt(e.body,t,!1);return $e.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=Nt(e.body,t);return r instanceof St||(r=new St("mrow",[r])),r.setAttribute("href",e.href),r}}),at({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Vt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=D(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=D(e.width,t));var i={height:P(r+n)};a>0&&(i.width=P(a)),n>0&&(i.verticalAlign=P(-n));var o=new X(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new zt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=D(e.height,t),a=0;if(e.totalheight.number>0&&(a=D(e.totalheight,t)-n,r.setAttribute("valign",P(-a))),r.setAttribute("height",P(n+a)),e.width.number>0){var i=D(e.width,t);r.setAttribute("width",P(i))}return r.setAttribute("src",e.src),r}}),at({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Vt(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return $e.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=D(e.dimension,t);return new zt.SpaceNode(r)}}),at({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=$e.makeSpan([],[yt(e.body,t)]),r=$e.makeSpan(["inner"],[r],t)):r=$e.makeSpan(["inner"],[yt(e.body,t)]);var n=$e.makeSpan(["fix"],[]),a=$e.makeSpan([e.alignment],[r,n],t),i=$e.makeSpan(["strut"]);return i.style.height=P(a.height+a.depth),a.depth&&(i.style.verticalAlign=P(-a.depth)),a.children.unshift(i),a=$e.makeSpan(["thinbox"],[a],t),$e.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mpadded",[Ct(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),at({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),at({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var rn=function(e,t){switch(t.style.size){case b.DISPLAY.size:return e.display;case b.TEXT.size:return e.text;case b.SCRIPT.size:return e.script;case b.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};at({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:st(t[0]),text:st(t[1]),script:st(t[2]),scriptscript:st(t[3])}},htmlBuilder:function(e,t){var r=rn(e,t),n=pt(r,t,!1);return $e.makeFragment(n)},mathmlBuilder:function(e,t){var r=rn(e,t);return Nt(r,t)}});var nn=function(e,t,r,n,a,i,o){e=$e.makeSpan([],[e]);var s,h,m,c=r&&l.isCharacterBox(r);if(t){var u=yt(t,n.havingStyle(a.sup()),n);h={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-u.depth)}}if(r){var p=yt(r,n.havingStyle(a.sub()),n);s={elem:p,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-p.height)}}if(h&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;m=$e.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!h)return e;var g=e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[m];if(s&&0!==i&&!c){var b=$e.makeSpan(["mspace"],[],n);b.style.marginRight=P(i),v.unshift(b)}return $e.makeSpan(["mop","op-limits"],v,n)},an=["\\smallint"],on=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Vt(e.base,"op"),i=!0):a=Vt(e,"op");var o,s=t.style,h=!1;if(s.size===b.DISPLAY.size&&a.symbol&&!l.contains(an,a.name)&&(h=!0),a.symbol){var m=h?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(c=a.name.substr(1),a.name="oiint"===c?"\\iint":"\\iiint"),o=$e.makeSymbol(a.name,m,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),c.length>0){var u=o.italic,p=$e.staticSvg(c+"Size"+(h?"2":"1"),t);o=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+c,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=pt(a.body,t,!0);1===d.length&&d[0]instanceof j?(o=d[0]).classes[0]="mop":o=$e.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=pt(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",P(a)):(s.setAttribute("height",P(a)),s.setAttribute("depth",P(-a))),s.setAttribute("voffset",P(a)),s}});var dn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];at({type:"sizing",names:dn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:dn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return pn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=qt(e.body,r),a=new zt.MathNode("mstyle",n);return a.setAttribute("mathsize",P(r.sizeMultiplier)),a}}),at({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Vt(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=P(m);var p=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(b.SCRIPTSCRIPT),f=yt(e.index,d,t),g=.6*(p.height-p.depth),v=$e.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),y=$e.makeSpan(["root"],[v]);return $e.makeSpan(["mord","sqrt"],[y,p],t)}return $e.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new zt.MathNode("mroot",[Ct(r,t),Ct(n,t)]):new zt.MathNode("msqrt",[Ct(r,t)])}});var fn={display:b.DISPLAY,text:b.TEXT,script:b.SCRIPT,scriptscript:b.SCRIPTSCRIPT};at({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r).withFont("");return pn(e.body,n,t)},mathmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r),a=qt(e.body,n),i=new zt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});var gn=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===b.DISPLAY.size||r.alwaysHandleSupSub)?on:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===b.DISPLAY.size||r.limits)?un:null:"accent"===r.type?l.isCharacterBox(r.base)?Yt:null:"horizBrace"===r.type&&!e.sub===r.isOver?en:null:null};it({type:"supsub",htmlBuilder:function(e,t){var r=gn(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,h=e.sub,m=yt(o,t),c=t.fontMetrics(),u=0,p=0,d=o&&l.isCharacterBox(o);if(s){var f=t.havingStyle(t.style.sup());n=yt(s,f,t),d||(u=m.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(h){var g=t.havingStyle(t.style.sub());a=yt(h,g,t),d||(p=m.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===b.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,y=t.sizeMultiplier,x=P(.5/c.ptPerEm/y),w=null;if(a){var k=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(m instanceof j||k)&&(w=P(-m.italic))}if(n&&a){u=Math.max(u,i,n.depth+.25*c.xHeight),p=Math.max(p,c.sub2);var S=4*c.defaultRuleThickness;if(u-n.depth-(a.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:a,shift:p,marginRight:x,marginLeft:w},{type:"elem",elem:n,shift:-u,marginRight:x}];v=$e.makeVList({positionType:"individualShift",children:z},t)}else if(a){p=Math.max(p,c.sub1,a.height-.8*c.xHeight);var A=[{type:"elem",elem:a,marginLeft:w,marginRight:x}];v=$e.makeVList({positionType:"shift",positionData:p,children:A},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,n.depth+.25*c.xHeight),v=$e.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:n,marginRight:x}]},t)}var T=vt(m,"right")||"mord";return $e.makeSpan([T],[m,$e.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Ct(e.base,t)];if(e.sub&&i.push(Ct(e.sub,t)),e.sup&&i.push(Ct(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===b.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===b.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===b.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===b.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===b.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===b.DISPLAY)?"mover":"msup"}return new zt.MathNode(a,i)}}),it({type:"atom",htmlBuilder:function(e,t){return $e.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[At(e.text,e.mode)]);if("bin"===e.family){var n=Bt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var vn={mi:"italic",mn:"normal",mtext:"normal"};it({type:"mathord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new zt.MathNode("mi",[At(e.text,e.mode,t)]),n=Bt(e,t)||"italic";return n!==vn[r.type]&&r.setAttribute("mathvariant",n),r}}),it({type:"textord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=At(e.text,e.mode,t),a=Bt(e,t)||"normal";return r="text"===e.mode?new zt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new zt.MathNode("mn",[n]):"\\prime"===e.text?new zt.MathNode("mo",[n]):new zt.MathNode("mi",[n]),a!==vn[r.type]&&r.setAttribute("mathvariant",a),r}});var bn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},yn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};it({type:"spacing",htmlBuilder:function(e,t){if(yn.hasOwnProperty(e.text)){var r=yn[e.text].className||"";if("text"===e.mode){var a=$e.makeOrd(e,t,"textord");return a.classes.push(r),a}return $e.makeSpan(["mspace",r],[$e.mathsym(e.text,e.mode,t)],t)}if(bn.hasOwnProperty(e.text))return $e.makeSpan(["mspace",bn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!yn.hasOwnProperty(e.text)){if(bn.hasOwnProperty(e.text))return new zt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new zt.MathNode("mtext",[new zt.TextNode("\xa0")])}});var xn=function(){var e=new zt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};it({type:"tag",mathmlBuilder:function(e,t){var r=new zt.MathNode("mtable",[new zt.MathNode("mtr",[xn(),new zt.MathNode("mtd",[Nt(e.body,t)]),xn(),new zt.MathNode("mtd",[Nt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},kn={"\\textbf":"textbf","\\textmd":"textmd"},Sn={"\\textit":"textit","\\textup":"textup"},Mn=function(e,t){var r=e.font;return r?wn[r]?t.withTextFontFamily(wn[r]):kn[r]?t.withTextFontWeight(kn[r]):t.withTextFontShape(Sn[r]):t};at({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:st(a),font:n}},htmlBuilder:function(e,t){var r=Mn(e,t),n=pt(e.body,r,!0);return $e.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Mn(e,t);return Nt(e.body,r)}}),at({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=$e.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[new zt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var n=new zt.MathNode("munder",[Ct(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),at({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return $e.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new zt.MathNode("mpadded",[Ct(e.body,t)],["vcenter"])}}),at({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=zn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}this.current[e]=t},e}(),In=mn;cn("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),cn("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),cn("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),cn("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),cn("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),cn("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),cn("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Rn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};cn("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Rn[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=Rn[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};cn("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in En?t=En[r]:("\\not"===r.substr(0,4)||r in re.math&&l.contains(["bin","rel"],re.math[r].group))&&(t="\\dotsb"),t}));var Hn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};cn("\\dotso",(function(e){return e.future().text in Hn?"\\ldots\\,":"\\ldots"})),cn("\\dotsc",(function(e){var t=e.future().text;return t in Hn&&","!==t?"\\ldots\\,":"\\ldots"})),cn("\\cdots",(function(e){return e.future().text in Hn?"\\@cdots\\,":"\\@cdots"})),cn("\\dotsb","\\cdots"),cn("\\dotsm","\\cdots"),cn("\\dotsi","\\!\\cdots"),cn("\\dotsx","\\ldots\\,"),cn("\\DOTSI","\\relax"),cn("\\DOTSB","\\relax"),cn("\\DOTSX","\\relax"),cn("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),cn("\\,","\\tmspace+{3mu}{.1667em}"),cn("\\thinspace","\\,"),cn("\\>","\\mskip{4mu}"),cn("\\:","\\tmspace+{4mu}{.2222em}"),cn("\\medspace","\\:"),cn("\\;","\\tmspace+{5mu}{.2777em}"),cn("\\thickspace","\\;"),cn("\\!","\\tmspace-{3mu}{.1667em}"),cn("\\negthinspace","\\!"),cn("\\negmedspace","\\tmspace-{4mu}{.2222em}"),cn("\\negthickspace","\\tmspace-{5mu}{.277em}"),cn("\\enspace","\\kern.5em "),cn("\\enskip","\\hskip.5em\\relax"),cn("\\quad","\\hskip1em\\relax"),cn("\\qquad","\\hskip2em\\relax"),cn("\\tag","\\@ifstar\\tag@literal\\tag@paren"),cn("\\tag@paren","\\tag@literal{({#1})}"),cn("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),cn("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),cn("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),cn("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),cn("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),cn("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),cn("\\newline","\\\\\\relax"),cn("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Ln=P(z["Main-Regular"]["T".charCodeAt(0)][1]-.7*z["Main-Regular"]["A".charCodeAt(0)][1]);cn("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),cn("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),cn("\\hspace","\\@ifstar\\@hspacer\\@hspace"),cn("\\@hspace","\\hskip #1\\relax"),cn("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),cn("\\ordinarycolon",":"),cn("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),cn("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),cn("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),cn("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),cn("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),cn("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),cn("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),cn("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),cn("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),cn("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),cn("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),cn("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),cn("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),cn("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),cn("\u2237","\\dblcolon"),cn("\u2239","\\eqcolon"),cn("\u2254","\\coloneqq"),cn("\u2255","\\eqqcolon"),cn("\u2a74","\\Coloneqq"),cn("\\ratio","\\vcentcolon"),cn("\\coloncolon","\\dblcolon"),cn("\\colonequals","\\coloneqq"),cn("\\coloncolonequals","\\Coloneqq"),cn("\\equalscolon","\\eqqcolon"),cn("\\equalscoloncolon","\\Eqqcolon"),cn("\\colonminus","\\coloneq"),cn("\\coloncolonminus","\\Coloneq"),cn("\\minuscolon","\\eqcolon"),cn("\\minuscoloncolon","\\Eqcolon"),cn("\\coloncolonapprox","\\Colonapprox"),cn("\\coloncolonsim","\\Colonsim"),cn("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),cn("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),cn("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),cn("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),cn("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),cn("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),cn("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),cn("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),cn("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),cn("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),cn("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),cn("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),cn("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),cn("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),cn("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),cn("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),cn("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),cn("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),cn("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),cn("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),cn("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),cn("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),cn("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),cn("\\imath","\\html@mathml{\\@imath}{\u0131}"),cn("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),cn("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),cn("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),cn("\u27e6","\\llbracket"),cn("\u27e7","\\rrbracket"),cn("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),cn("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),cn("\u2983","\\lBrace"),cn("\u2984","\\rBrace"),cn("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),cn("\u29b5","\\minuso"),cn("\\darr","\\downarrow"),cn("\\dArr","\\Downarrow"),cn("\\Darr","\\Downarrow"),cn("\\lang","\\langle"),cn("\\rang","\\rangle"),cn("\\uarr","\\uparrow"),cn("\\uArr","\\Uparrow"),cn("\\Uarr","\\Uparrow"),cn("\\N","\\mathbb{N}"),cn("\\R","\\mathbb{R}"),cn("\\Z","\\mathbb{Z}"),cn("\\alef","\\aleph"),cn("\\alefsym","\\aleph"),cn("\\Alpha","\\mathrm{A}"),cn("\\Beta","\\mathrm{B}"),cn("\\bull","\\bullet"),cn("\\Chi","\\mathrm{X}"),cn("\\clubs","\\clubsuit"),cn("\\cnums","\\mathbb{C}"),cn("\\Complex","\\mathbb{C}"),cn("\\Dagger","\\ddagger"),cn("\\diamonds","\\diamondsuit"),cn("\\empty","\\emptyset"),cn("\\Epsilon","\\mathrm{E}"),cn("\\Eta","\\mathrm{H}"),cn("\\exist","\\exists"),cn("\\harr","\\leftrightarrow"),cn("\\hArr","\\Leftrightarrow"),cn("\\Harr","\\Leftrightarrow"),cn("\\hearts","\\heartsuit"),cn("\\image","\\Im"),cn("\\infin","\\infty"),cn("\\Iota","\\mathrm{I}"),cn("\\isin","\\in"),cn("\\Kappa","\\mathrm{K}"),cn("\\larr","\\leftarrow"),cn("\\lArr","\\Leftarrow"),cn("\\Larr","\\Leftarrow"),cn("\\lrarr","\\leftrightarrow"),cn("\\lrArr","\\Leftrightarrow"),cn("\\Lrarr","\\Leftrightarrow"),cn("\\Mu","\\mathrm{M}"),cn("\\natnums","\\mathbb{N}"),cn("\\Nu","\\mathrm{N}"),cn("\\Omicron","\\mathrm{O}"),cn("\\plusmn","\\pm"),cn("\\rarr","\\rightarrow"),cn("\\rArr","\\Rightarrow"),cn("\\Rarr","\\Rightarrow"),cn("\\real","\\Re"),cn("\\reals","\\mathbb{R}"),cn("\\Reals","\\mathbb{R}"),cn("\\Rho","\\mathrm{P}"),cn("\\sdot","\\cdot"),cn("\\sect","\\S"),cn("\\spades","\\spadesuit"),cn("\\sub","\\subset"),cn("\\sube","\\subseteq"),cn("\\supe","\\supseteq"),cn("\\Tau","\\mathrm{T}"),cn("\\thetasym","\\vartheta"),cn("\\weierp","\\wp"),cn("\\Zeta","\\mathrm{Z}"),cn("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),cn("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),cn("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),cn("\\bra","\\mathinner{\\langle{#1}|}"),cn("\\ket","\\mathinner{|{#1}\\rangle}"),cn("\\braket","\\mathinner{\\langle{#1}\\rangle}"),cn("\\Bra","\\left\\langle#1\\right|"),cn("\\Ket","\\left|#1\\right\\rangle"),cn("\\angln","{\\angl n}"),cn("\\blue","\\textcolor{##6495ed}{#1}"),cn("\\orange","\\textcolor{##ffa500}{#1}"),cn("\\pink","\\textcolor{##ff00af}{#1}"),cn("\\red","\\textcolor{##df0030}{#1}"),cn("\\green","\\textcolor{##28ae7b}{#1}"),cn("\\gray","\\textcolor{gray}{#1}"),cn("\\purple","\\textcolor{##9d38bd}{#1}"),cn("\\blueA","\\textcolor{##ccfaff}{#1}"),cn("\\blueB","\\textcolor{##80f6ff}{#1}"),cn("\\blueC","\\textcolor{##63d9ea}{#1}"),cn("\\blueD","\\textcolor{##11accd}{#1}"),cn("\\blueE","\\textcolor{##0c7f99}{#1}"),cn("\\tealA","\\textcolor{##94fff5}{#1}"),cn("\\tealB","\\textcolor{##26edd5}{#1}"),cn("\\tealC","\\textcolor{##01d1c1}{#1}"),cn("\\tealD","\\textcolor{##01a995}{#1}"),cn("\\tealE","\\textcolor{##208170}{#1}"),cn("\\greenA","\\textcolor{##b6ffb0}{#1}"),cn("\\greenB","\\textcolor{##8af281}{#1}"),cn("\\greenC","\\textcolor{##74cf70}{#1}"),cn("\\greenD","\\textcolor{##1fab54}{#1}"),cn("\\greenE","\\textcolor{##0d923f}{#1}"),cn("\\goldA","\\textcolor{##ffd0a9}{#1}"),cn("\\goldB","\\textcolor{##ffbb71}{#1}"),cn("\\goldC","\\textcolor{##ff9c39}{#1}"),cn("\\goldD","\\textcolor{##e07d10}{#1}"),cn("\\goldE","\\textcolor{##a75a05}{#1}"),cn("\\redA","\\textcolor{##fca9a9}{#1}"),cn("\\redB","\\textcolor{##ff8482}{#1}"),cn("\\redC","\\textcolor{##f9685d}{#1}"),cn("\\redD","\\textcolor{##e84d39}{#1}"),cn("\\redE","\\textcolor{##bc2612}{#1}"),cn("\\maroonA","\\textcolor{##ffbde0}{#1}"),cn("\\maroonB","\\textcolor{##ff92c6}{#1}"),cn("\\maroonC","\\textcolor{##ed5fa6}{#1}"),cn("\\maroonD","\\textcolor{##ca337c}{#1}"),cn("\\maroonE","\\textcolor{##9e034e}{#1}"),cn("\\purpleA","\\textcolor{##ddd7ff}{#1}"),cn("\\purpleB","\\textcolor{##c6b9fc}{#1}"),cn("\\purpleC","\\textcolor{##aa87ff}{#1}"),cn("\\purpleD","\\textcolor{##7854ab}{#1}"),cn("\\purpleE","\\textcolor{##543b78}{#1}"),cn("\\mintA","\\textcolor{##f5f9e8}{#1}"),cn("\\mintB","\\textcolor{##edf2df}{#1}"),cn("\\mintC","\\textcolor{##e0e5cc}{#1}"),cn("\\grayA","\\textcolor{##f6f7f7}{#1}"),cn("\\grayB","\\textcolor{##f0f1f2}{#1}"),cn("\\grayC","\\textcolor{##e3e5e6}{#1}"),cn("\\grayD","\\textcolor{##d6d8da}{#1}"),cn("\\grayE","\\textcolor{##babec2}{#1}"),cn("\\grayF","\\textcolor{##888d93}{#1}"),cn("\\grayG","\\textcolor{##626569}{#1}"),cn("\\grayH","\\textcolor{##3b3e40}{#1}"),cn("\\grayI","\\textcolor{##21242c}{#1}"),cn("\\kaBlue","\\textcolor{##314453}{#1}"),cn("\\kaGreen","\\textcolor{##71B307}{#1}");var Dn={"\\relax":!0,"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Pn=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Cn(In,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new Nn(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Bn("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof Bn){if("\\relax"!==e.text&&!e.treatAsRelax)return this.stack.pop();this.stack.pop()}}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Bn(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof Bn&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new Nn(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||An.hasOwnProperty(e)||re.math.hasOwnProperty(e)||re.text.hasOwnProperty(e)||Dn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:An.hasOwnProperty(e)&&!An[e].primitive},e}(),Fn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Vn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Gn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Pn(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&An[a.text]&&An[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=re[this.mode][t].group,h=Tn.range(e);if(Q.hasOwnProperty(l)){var m=l;s={type:"atom",mode:this.mode,family:m,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(w(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Tn.range(e),text:t}}if(this.consume(),o)for(var c=0;c + + + + +Verbindung & Tor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/security/category/cwtch-components/index.html b/build-staging/de/security/category/cwtch-components/index.html new file mode 100644 index 00000000..474024f4 --- /dev/null +++ b/build-staging/de/security/category/cwtch-components/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Komponenten | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/security/category/cwtch-ui/index.html b/build-staging/de/security/category/cwtch-ui/index.html new file mode 100644 index 00000000..05fc5f26 --- /dev/null +++ b/build-staging/de/security/category/cwtch-ui/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch-UI | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/de/security/category/cwtch/index.html b/build-staging/de/security/category/cwtch/index.html new file mode 100644 index 00000000..e88cc768 --- /dev/null +++ b/build-staging/de/security/category/cwtch/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/security/category/tapir/index.html b/build-staging/de/security/category/tapir/index.html new file mode 100644 index 00000000..b1c99556 --- /dev/null +++ b/build-staging/de/security/category/tapir/index.html @@ -0,0 +1,24 @@ + + + + + +Tapir | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/de/security/components/connectivity/intro/index.html b/build-staging/de/security/components/connectivity/intro/index.html new file mode 100644 index 00000000..b5207b28 --- /dev/null +++ b/build-staging/de/security/components/connectivity/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Verbindung | The Cwtch Handbook + + + + + + + + + + + + +
+

Verbindung

Cwtch nutzt Tor Onion Services (v3) für die Kommunikation zwischen Knoten.

Wir stellen das openprivacy/connectivity Paket zur Verfügung, um den Tor-Daemon zu verwalten und Onion Dienste durch Tor einzurichten und abzubauen.

Bekannte Risiken

Privater Schlüssel dem Tor Prozess ausgesetzt

Status: Teilweise gemildert (Erfordert physischen Zugriff oder Privilegierte Eskalation zum ausnutzen)

Wir müssen den privaten Schlüssel eines Onion Dienstes an die Konnektivitätsbibliothek übergeben über die Listen Schnittstelle (und damit zum Tor Prozess). Dies ist einer der kritischsten Bereiche, der außerhalb unserer Kontrolle liegt. Jede Bindung an einen Rogue-Tor-Prozess oder ein Binary führt zur Kompromittierung des privaten Schlüssels von Onion führen.

Eindämmung

Verbindungsversuche als Standard an den vom System bereitgestellten Tor-Prozess zu binden, nur wenn ihm ein Authentifizierungs-Token zur Verfügung gestellt wurde.

Andernfalls versucht die Konnektivität immer einen eigenen Tor-Prozess mit einem bekannten guten Binärpaket, das mit dem System gepackt wurde (außerhalb des Geltungsbereichs des Konnektivitäts-Paketes)

Langfristig hoffen wir, dass eine integrierte Bibliothek verfügbar sein wird und die direkte Verwaltung über eine In-Prozessoberfläche ermöglicht, um zu verhindern, dass der private Schlüssel die Prozessgrenze verlässt (oder andere alternative Pfade, die es uns erlauben, die volle Kontrolle über den privaten Schlüssel im Speicher zu erhalten.)

Tor-Prozess-Management

Status: Teilweise gemildert (Erfordert physischen Zugriff oder Privilegierte Eskalation zum ausnutzen)

Viele Probleme können sich aus der Verwaltung eines separaten Prozesses ergeben, einschließlich der Notwendigkeit, neu zu starten, zu beenden und anderweitig eine angemessene Verwaltung zu gewährleisten.

Die ACN Schnittstelle bietet Restart, Close und GetBootstrapStatus Schnittstellen die es Anwendungen erlauben, den zugrunde liegenden Tor-Prozess zu verwalten. Zusätzlich kann die SetStatusCallback Methode verwendet werden, um eine Anwendung zu benachrichtigen, wenn der Status des Tor-Prozesses sich ändert.

Wenn jedoch genügend privilegierte Benutzer es wünschen, können sie diesen Mechanismus stören, und als solches ist der Tor-Prozess eine zerbrechlichere Komponente in der Interaktion als andere.

Teststatus

Die aktuelle Konnektivität hat begrenzte Test Möglichkeiten keine davon wird während Pull-Requests oder Zusammenschlüssen ausgeführt. Es gibt keine Integrationstests.

Es ist anzumerken, dass die Konnektivität sowohl von Tapir als auch von Cwtch in ihren Integrationstests verwendet wird (und dies trotz fehlender Tests auf Paketebene ist systemweiten Prüfbedingungen ausgesetzt)

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/cwtch/groups/index.html b/build-staging/de/security/components/cwtch/groups/index.html new file mode 100644 index 00000000..39f022e9 --- /dev/null +++ b/build-staging/de/security/components/cwtch/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Gruppen | The Cwtch Handbook + + + + + + + + + + + + +
+

Gruppen

Das Cwtch Risikomodell für Gruppen ist größtenteils in zwei unterschiedliche Profile aufgeteilt:

  • Gruppen aus gegenseitig vertrauenswürdigen Teilnehmern, in denen Peers als ehrlich angenommen werden.
  • Gruppen, die aus Fremden bestehen, in denen von Peers angenommen wird, dass sie potenziell bösartig sind.

Die meisten der in diesem Abschnitt beschriebenen Eindämmungen beziehen sich auf den letztgenannten Fall, aber wirken sich natürlich auch auf den Ersteren aus. Selbst wenn angenommen wird, dass ehrliche Peers später böswillig werden, gibt es Mechanismen, die solches Böse erkennen und verhindern können, dass es in der Zukunft passiert.

Überblick über die Risiken: Schlüssel-Ableitung

Im Idealfall würden wir ein Protokoll wie OTR verwenden, die Einschränkungen, die uns im Moment daran hindern, sind:

  • Offline-Nachrichten sind nicht garantiert, dass sie alle Peers erreichen, und als solche können alle Metadaten in Bezug auf Schlüsselmaterial verloren gehen. Wir benötigen einen Schlüsselableitungs-Prozess, der robust ist für fehlende Nachrichten oder unvollständige Übertragungen.

Risiko: Schädlicher Peer- verrät Gruppenschlüssel und/oder Unterhaltung

Status: Teilweise gemildert (aber unmöglich vollständig zu mildern)

Ob mit vertrauenswürdigen kleineren Gruppen oder partiell öffentliche größeren Gruppen, es gibt immer die Möglichkeit, dass ein böswilliger Akteur Gruppe Nachrichten verraten kann.

Wir planen, es den Peers zu erleichtern, Gruppen zu fork, den gleichen Schlüssel zu entschärfen, der zur Verschlüsselung vieler sensibler Informationen verwendet wird und ein gewisses Maß an Weiterleitungsgeheimhaltung für frühere Gruppengespräche bereitzustellen.

Risiko: Aktive Angriffe von Gruppenmitgliedern

Status: Teilweise gemildert

Gruppenmitglieder, die Zugang zum Schlüsselmaterial der Gruppe haben, können sich mit einem Server oder anderen Gruppenmitgliedern verschwören, um die Konsistenz des Transkripts zu unterbrechen.

Während wir die Zensur angesichts dieser aktiven Absprachen nicht direkt verhindern können, so verfügen wir doch über eine Reihe von Mechanismen, die ehrlichen Gruppen-Mitgliedern das Vorhandensein einer Zensur offenbaren sollten.

Eindämmung:

  • Weil jede Nachricht vom öffentlichen Schlüssel der Peers signiert ist, es sollte nicht möglich sein (innerhalb der kryptographischen Annahmen der zugrunde liegenden Kryptographie) für ein Gruppenmitglied ein anderes nachzuahmen.
  • Jede Nachricht enthält eine eindeutige Identifikation, die aus dem Inhalt abgeleitet wird und den vorherigen Hash der Nachrichten - wodurch es Kollaborateuren unmöglich gemacht wird, Nachrichten von nicht geheimen Mitgliedern einzufügen, ohne eine implizite Meldungs-Kette zu enthüllen (die wenn sie versuchen andere Nachrichten zu zensieren würde eine solche Zensur offenbaren)

Abschließend: Wir arbeiten aktiv daran, den Cwtch-Servern eine Nichtabstreitbarkeit hinzuzufügen, so dass dass sie selbst in dem, was sie effizient zensieren können, eingeschränkt sind.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/cwtch/key_bundles/index.html b/build-staging/de/security/components/cwtch/key_bundles/index.html new file mode 100644 index 00000000..f98060c5 --- /dev/null +++ b/build-staging/de/security/components/cwtch/key_bundles/index.html @@ -0,0 +1,24 @@ + + + + + +Schlüsselbündel | The Cwtch Handbook + + + + + + + + + + + + +
+

Schlüsselbündel

Cwtch-Server identifizieren sich mit signierten Schlüsselbündeln. Diese Schlüsselbündel enthalten eine Liste der benötigten Schlüssel, um die Kommunikation der Cwtch-Gruppe sicher zu machen und Metadaten widerstandsfähig zu machen.

Zum Zeitpunkt des Schreibens wird erwartet, dass Schlüsselbündel 3 Schlüssel enthalten:

  1. Ein öffentlicher Tor v3 Onion Service Public Key für das Token Board (ed25519)- verwendet um sich über Tor mit dem Dienst zu verbinden und Nachrichten zu empfangen.
  2. Ein öffentlicher Schlüssel des Tor-v3-Onion Service für den Token Service (ed25519) - der verwendet wird, um Tokens zu erwerben, um über eine kleine Proof-Work-Übung auf den Dienst zu posten.
  3. Ein Public Key für den Privacy-Pass - verwendet im Token-Akquisitionsprozess (ein ristretto Kurvenpunkt) . Siehe: OPTR2019-01

Das Schlüsselbündel ist signiert und kann über den ersten v3-Onion Service Schlüssel verifiziert werden, so dass es an die onion-Adresse gebunden wird.

Überprüfe Schlüsselbündel

Profile, die Server-Schlüsselpakete importieren, überprüfen sie anhand des folgenden "trust-on-first-use"-Algorithmus (TOFU):

  1. Überprüfung der angehängten Signatur mit der v3-Onion Adresse des Servers. (Wenn dies fehlschlägt, wird der Importprozess gestoppt)
  2. Überprüfung, ob jeder Schlüsseltyp existiert. (Wenn dies fehlschlägt, wird der Importprozess gestoppt)
  3. Wenn das Profil zuvor das Server-Schlüsselbündel importiert hat, Sicherstellung, dass alle Schlüssel gleich sind. (Wenn dies fehlschlägt, wird der Importprozess gestoppt)
  4. Speichern der Schlüssel im Kontakt-Eintrag des Servers.

In Zukunft wird dieser Algorithmus wahrscheinlich so geändert, dass neue öffentliche Schlüssel hinzugefügt werden können (z.B. um Tokens über eine Zcash Adresse zu erwerben.)

Technisch gesehen kann der Server in den Schritten (2) und (3() als bösartig angesehen werden, weil er ein gültiges Schlüsselbündel unterzeichnet hat, das nicht den Spezifikationen entspricht. Wenn Gruppen von "experimentell" in "stable" verschoben werden, führt eine solche Aktion dazu, dass eine Warnung an das Profil kommuniziert wird.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/cwtch/message_formats/index.html b/build-staging/de/security/components/cwtch/message_formats/index.html new file mode 100644 index 00000000..81fa54f7 --- /dev/null +++ b/build-staging/de/security/components/cwtch/message_formats/index.html @@ -0,0 +1,24 @@ + + + + + +Nachrichtenformate | The Cwtch Handbook + + + + + + + + + + + + +
+

Nachrichtenformate

Peer-to-Peer Nachrichten

PeerMessage {
ID string // A unique Message ID (primarily used for acknowledgments)
Context string // A unique context identifier i.e. im.cwtch.chat
Data []byte // The context-dependent serialized data packet.
}

Kontext-Bezeichner

  • im.cwtch.raw - Daten enthalten eine Klartext-Chat-Nachricht (siehe: Overlays für weitere Informationen)

  • im.cwtch.acknowledgement - Daten sind leer und ID verweist auf eine zuvor gesendete Nachricht

  • im.cwtch.getVal und im.cwtch.retVal - Wird für die Abfrage / Rückgabe spezifischer Informationen über einen Peer verwendet. Daten enthalten eine serialisierte peerGetVal und peerRetVal Struktur.

      peerGetVal struct {
    Scope string
    Path string
    }

    type peerRetVal struct {
    Val string // Serialized path-dependent value
    Exists bool
    }

Klartext / Entschlüsselte Gruppennachrichten

type DecryptedGroupMessage struct {
Text string // plaintext of the message
Onion string // The Cwtch address of the sender
Timestamp uint64 // A user specified timestamp
// NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages
// We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.
// respect particular group constitutions) can be built on top of group messages, but the underlying groups are
// now agnostic to those models.
SignedGroupID []byte
PreviousMessageSig []byte // A reference to a previous message
Padding []byte // random bytes of length = 1800 - len(Text)
}

Entschlüsselte Gruppennachrichten enthalten zufällige Füllung zu einer festen Größe, die der Länge aller Felder mit fester Länge + 1800 entspricht. Dies stellt sicher, dass alle verschlüsselten Gruppen-Nachrichten gleich lang sind.

Verschlüsselte Gruppennachrichten

// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server
type EncryptedGroupMessage struct {
Ciphertext []byte
Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key
}

Die Berechnung der Signatur erfordert das Wissen über die Gruppen-Id der Nachricht, des Servers, mit dem die Gruppe verbunden ist und der entschlüsselten Gruppennachricht (und damit der Gruppenschlüssel). Es ist vom Absender der Nachricht (ed25519) signiert und kann mit ihrem öffentlichen Cwtch-Adressschlüssel verifiziert werden.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/cwtch/server/index.html b/build-staging/de/security/components/cwtch/server/index.html new file mode 100644 index 00000000..10bbb474 --- /dev/null +++ b/build-staging/de/security/components/cwtch/server/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Server | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Server

Ziel des Cwtch-Protokolls ist es, die Gruppenkommunikation über Nicht vertrauenswürdige Infrastruktur zu aktivieren.

Im Gegensatz zu Relay basierten Schemata, bei denen die Gruppen einen Führer, einen Satz von Führern, oder ein vertrauenswürdiger Server von Drittanbietern zuweisen, um sicherzustellen, dass jedes Mitglied der Gruppe Nachrichten zeitnah senden und empfangen kann (selbst wenn Mitglieder offline sind) - hat die nicht vertrauenswürdige Infrastruktur das Ziel, diese Eigenschaften zu realisieren ohne Vertrauen anzunehmen.

Das ursprüngliche Cwtch-Papier hat eine Reihe von Eigenschaften definiert, die Cwtch-Server erwartbar zur Verfügung stellen sollten:

  • Cwtch Server kann von mehreren Gruppen oder nur einer verwendet werden.
  • Ein Cwtch Server, ohne Zusammenarbeit mit einem Gruppenmitglied, sollte niemals die Identität der Teilnehmer innerhalb einer Gruppe erlernen.
  • Ein Cwtch Server sollte niemals den Inhalt einer Kommunikation erlernen.
  • Ein Cwtch-Server sollte niemals in der Lage sein, Nachrichten als einer bestimmten Gruppe zugehörig unterscheiden zu können.

Wir stellen hier fest, dass diese Eigenschaften ein Superset der Designziele der privaten Informationsabfrage sind.

Bösartige Server

Wir erwarten das Vorhandensein bösartiger Entitäten innerhalb des Cwtch-Ökosystems.

Wir legen auch Wert auf Dezentralisierung und erlaubnisfreien Zugang zum Ökosystem und stützen daher keine Sicherheitsansprüche auf die folgenden Punkte:

  • Jede Nicht-Kollusionsannahme zwischen einer Reihe von Cwtch-Servern
  • Jedes von Dritten definierte Prüfverfahren

Die Peers selbst werden ermutigt, Cwtch-Server einzurichten und zu betreiben, wo sie effizientere Eigenschaften garantieren können, indem sie die Vertrauens- und Sicherheits Annahmen voraussetzen - standardmäßig ist das Protokoll jedoch so konzipiert, dass es auch ohne diese Annahmen sicher ist - auf Kosten der Effizienz, wo es nötig ist.

Erkennbare Fehler

  • Wenn ein Cwtch-Server eine bestimmte Nachricht nicht an eine Gruppe von Gruppenmitgliedern weiterleitet, wird es eine erkennbare Lücke im Nachrichtenbaum einiger Peers geben, die durch Peer-to-Peer Klatsch entdeckt werden kann.
  • Ein Cwtch-Server kann keine Nachricht ohne das Schlüsselmaterial, das der Gruppe bekannt ist, ändern (jeder Versuch, dies für eine Teilmenge von Gruppenmitgliedern zu tun, führt dazu, dass es das gleiche Verhalten hat, wie wenn keine Nachricht weitergeleitet wird).
  • Während ein Server Nachrichten duplizieren kann, haben diese keine Auswirkungen auf den Gruppen-Nachrichtenbaum (aufgrund der Verschlüsselung, Nonces und Nachrichtenidentitäten) - die Quelle der Vervielfältigung ist für einen Peer nicht bekannt.

Effizienz

Zum Zeitpunkt des Schreibens dieser Seite ist nur ein Protokoll für das Erreichen der gewünschten Eigenschaften bekannt, naive PIR oder "der Server sendet alles, und die Peers sichten es".

Dies hat einen offensichtlichen Einfluss auf die Effizienz der Bandbreite, insbesondere für Peers mit mobilen Geräten, als solche entwickeln wir aktiv neue Protokolle, in denen die Datenschutz- und Effizienzgarantien auf unterschiedliche Weise ausgehandelt werden können.

Beim Zeitpunkt des Schreibens dieser Seite erlauben die Server sowohl einen vollständigen Download aller gespeicherten Nachrichten, und eine Anfrage, um Nachrichten von einer bestimmten Nachricht herunterzuladen.

Alle Peers, wenn sie einer Gruppe auf einem neuen Server beitreten, laden alle Nachrichten vom Server herunter und von dann an laden sie nur neue Nachrichten.

Hinweis: Dieses Verhalten erlaubt eine milde Form der Metadatenanalyse. Der Server kann neue Nachrichten für jedes verdächtige eindeutige Profil anzeigen und dann diese eindeutigen Signaturen benutzen um eindeutige Sitzungen im Laufe der Zeit zu verfolgen (über Anfragen für neue Nachrichten).

Dies wird durch 2 Verwirrungsfaktoren gemildert:

  1. Profile können ihre Verbindungen jederzeit aktualisieren - was zu einer neuen Serversitzung führt.
  2. Profile können jederzeit von einem Server "synchronisieren" - was zu einem neuen Aufruf führt, um alle Nachrichten herunterzuladen. Die am meisten verbreitete Benutzungsgrundlage für dieses Verhalten ist das Abrufen älterer Nachrichten aus einer Gruppe.

In Kombination setzen diese 2 Abschwächungen Grenzen auf das, was der Server herausfinden kann, aber wir können noch keine vollständige Metadatenresistenz bieten.

Für mögliche zukünftige Lösungen für dieses Problem siehe Niwl

Den Server wird vor böswilligen Peers schützen

Das Hauptrisiko für Server besteht in Form von Spam, der von Peers erzeugt wird. Im Prototyp von Cwtch wurde ein Spamschutzmechanismus eingeführt, der von anderen Peers verlangte, einen willkürlichen Nachweis der Arbeit mit einem server-spezifizierten Parameter durchzuführen.

Dies ist keine robuste Lösung in Anwesenheit eines bestimmten Gegners mit einer beträchtlichen Menge an Ressourcen und damit wird eines der wichtigsten externen Risiken für das Cwtch-System wird Zensur-Via-Ressourcen-Erschöpfung.

Wir haben eine mögliche Lösung dafür in Token basierten Diensten skizziert, aber beachte, dass dies ebenfalls weiterentwickelt werden muss.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/ecosystem-overview/index.html b/build-staging/de/security/components/ecosystem-overview/index.html new file mode 100644 index 00000000..b05e9ba9 --- /dev/null +++ b/build-staging/de/security/components/ecosystem-overview/index.html @@ -0,0 +1,24 @@ + + + + + +Komponenten Ecosystem Übersicht | The Cwtch Handbook + + + + + + + + + + + + +
+

Komponenten Ecosystem Übersicht

Cwtch besteht aus mehreren kleineren Komponenten-Bibliotheken. Dieses Kapitel gibt einen kurzen Überblick über jede Komponente und wie sie sich auf das größere Cwtch-Ökosystem bezieht.

offene Privatsphäre/Konnektivität

Zusammenfassung: Eine Bibliothek, die eine ACN (Anonymous Communication Network ) Netzwerkabstraktion zur Verfügung stellt.

Das Ziel der Konnektivität ist es, die zugrunde liegenden Bibliotheken/Software zu abstrahieren, die für die Kommunikation mit einer spezifischen ACN benötigt wird. Zurzeit unterstützen wir nur Tor und deshalb ist die Aufgabe der Verbindung folgendes:

  • Start und Stopp des Tor Prozesses
  • Bereitstellen der Konfiguration des Tor-Prozesses
  • Erlaube unveränderte Verbindungen zu Endpunkten über den Tor-Prozess (z.B. Verbindung mit Onion-Diensten)
  • Endpunkte über den Tor-Prozess zur Verfügung stellen (z.B. Host-Onion-Dienste)
  • Statusaktualisierungen über den zugrunde liegenden Tor-Prozess bereitstellen

Für weitere Informationen siehe Konnektivität

cwtch.im/tapir

Zusammenfassung: Tapir ist eine kleine Bibliothek für das Erstellen von p2p Anwendungen über anonyme Kommunikationssysteme.

Das Ziel von Tapir ist es, Anwendungen über eine bestimmte ACN zu abstrahieren. Tapir unterstützt:

Für weitere Informationen siehe Tapir

cwtch.im/cwtch

Zusammenfassung: Cwtch ist die Hauptbibliothek für die Implementierung des Cwtch-Protokolls / System.

Das Ziel von Cwtch ist die Bereitstellung von Implementierungen für cwtch-spezifische Anwendungen wie z.B. Nachrichtensendung, Gruppen und Dateifreigabe (implementiert als Tapir Anwendungen), Schnittstellen zur Verwaltung und Speicherung von Cwtch Profilen, bietet neben der Verwaltung anderer Kernfunktionen auch einen Eventbus für Subsystem Splitting und das Erstellen von Plugins mit neuen Funktionen.

Die Cwtch Bibliothek ist auch für die Pflege kanonischer Modelldarstellungen für Formate und Overlays zuständig.

cwtch.im/libcwtch-go

Zusammenfassung: libcwtch-go stellt C (auch für Android) Bindungen für Cwtch bereit für die Benutzung in UI Implementierungen.

Das Ziel von libcwtch-go ist es, die Lücke zwischen der Backend Cwtch Bibliothek und allen Frontend-Systemen zu überbrücken, die in einer anderen Sprache geschrieben werden können.

Die von libcwtch bereitgestellte API ist wesentlich eingeschränkter als die von Cwtch direkt bereitgestellte API, jede libcwtch API paketiert normalerweise mehrere Aufrufe an Cwtch.

libcwtch-go ist auch für die Verwaltung der UI-Einstellungen und des experimentellen Gateways zuständig. Es wird auch oft als Staging-Boden für experimentelle Funktionen und Code verwendet, die möglicherweise am Ende in Cwtch enden.

cwtch-ui

Zusammenfassung: Eine flutterbasierte Oberfläche (UI) für Cwtch.

Cwtch UI verwendet libcwtch-go um ein vollständiges UI für Cwtch bereitzustellen, das es Leuten ermöglicht, Profile zu erstellen und zu verwalten, Kontakte und Gruppen hinzuzufügen, Nachrichten zu versenden, Dateien freizugeben (bald) und vieles mehr.

Das UI ist auch für die Verwaltung von Lokalisierung und Übersetzungen zuständig.

Für weitere Informationen siehe Cwtch UI

Zusätzliche Komponenten

Gelegentlich wird Open Privacy Teile von Cwtch in eigenständige Bibliotheken einbeziehen, die nicht Cwtch spezifisch sind. Diese werden hier kurz zusammengefasst:

openprivacy/log

Ein Open Privacy spezifisches Logging-Framework, das in allen Cwtch Paketen verwendet wird.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/intro/index.html b/build-staging/de/security/components/intro/index.html new file mode 100644 index 00000000..beb0879d --- /dev/null +++ b/build-staging/de/security/components/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch technische Grundlagen | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch technische Grundlagen

Diese Seite bietet einen kurzen technischen Überblick über das Cwtch-Protokoll.

Ein Cwtch Profil

Benutzer können eines von mehreren Cwtch Profilen erstellen. Jedes Profil erzeugt ein zufälliges ed25519 Schlüsselpaar, welches kompatibel mit Tor ist.

Zusätzlich zum kryptographischen Material enthält ein Profil auch eine Liste von Kontakten (öffentliche Schlüssel für das Cwtch-Profil + zugeordnete Daten über dieses Profil wie Nickname und (optional) historische Nachrichten), eine Liste von Gruppen (mit kryptographischem Gruppenmaterial zusätzlich zu anderen zugehörigen Daten wie dem Gruppennickname und historischen Nachrichten).

2-Parteien-Konversionen: Peer to Peer

Damit 2 Parteien ein Peer-to-Peer-Gespräch führen können, müssen beide online sein, aber nur eine Partei muss über ihren Onion-Dienst erreichbar sein. Um der Klarheit willen kennzeichnen wir oft eine Partei als den "eingehenden Peer" (die Person, die den Onion-Dienst beherbergt) und die andere Partei den "ausgehenden Peer" (der sich mit dem Onion-Dienst verbindet).

Nach einer Verbindung beteiligen sich beide Seiten an einem -Authentifizierungsprotokoll von:

  • Behauptet, dass jede Partei Zugriff auf den privaten Schlüssel hat, der mit ihrer öffentlichen Identität verbunden ist.
  • Erzeugt einen kurzlebigen Sitzungs-Schlüssel, der zur Verschlüsselung aller weiteren Kommunikation während der Sitzung verwendet wird.

Dieser Austausch (detailliert im -Authentifizierungsprotokolldokumentiert) ist offline verweigerbar d. h. es ist möglich für jede Seite Transkripte dieses Protokoll-Austausches zu fälschen und daher ist es unmöglich definitiv zu beweisen, dass der Austausch überhaupt stattgefunden hat.

Nach dem Authentifizierungsprotokoll können beide Parteien frei miteinander kommunizieren.

Mehrparteien-Unterhaltungen: Gruppen und Kommunikation zwischen Peer to Server

Hinweis: Metadaten resistente Kommunikation ist noch ein aktives Entwicklungsfeld und was hier dokumentiert ist wird sehr wahrscheinlich in der Zukunft sich ändern.

Wenn eine Person eine Gruppendiskussion starten möchte, generiert sie einen zufälligen geheimen Gruppenschlüssel. Alle Gruppenkommunikation wird mit diesem Schlüssel verschlüsselt.

Zusammen mit dem Gruppenschlüssel entscheidet der Gruppenersteller sich auch für einen Cwtch Server als Host der Gruppe zu verwenden. Weitere Informationen darüber, wie Server sich selbst authentifizieren, findest du unter Schlüsselbündel.

Ein Gruppen Identifikator wird mit dem Gruppenschlüssel und dem Gruppenserver generiert und diese drei Elemente sind in einer Einladung verpackt, die an potenzielle Gruppenmitglieder gesendet werden kann (z.B. über existierende Peer-to-Peer-Verbindungen).

Um eine Nachricht an die Gruppe zu senden, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt (siehe unten), und verschlüsselt deine Nachricht mit dem Gruppenschlüssel und erzeugt eine kryptographische Signatur über die Gruppen-Id, Gruppen Server und die entschlüsselte Nachricht (siehe: Nachrichtenformate für weitere Informationen).

Um Nachrichten von der Gruppe zu erhalten, verbindet sich ein Profil mit dem Server, der die Gruppe beherbergt und lädt alle Nachrichten (seit seiner vorherigen Verbindung) herunter. Die Profile versuchen dann jede Nachricht mit dem Gruppenschlüssel zu entschlüsseln und wenn dies erfolgreich war, dann die Signatur zu verifizieren (siehe Cwtch Server Cwtch Gruppen für einen Überblick über Attacken und Abschwächungen).

Server sind Peers

In vielerlei Hinsicht ist die Kommunikation mit einem Server identisch mit einer regulären Cwtch Gegenstelle, die gleichen Schritte oben werden durchgeführt, aber der Server fungiert immer als eingehender Peer, und der ausgehende Peer verwendet immer neu generierte kurzlebige Schlüsselpaare als "Langfristige Identität".

Somit unterscheidet sich die Peer zu Server Konversation nur in der Art der Nachrichten, die zwischen zwei Seiten gesendet werden, mit dem Server, der alle Nachrichten, die er erhält, weiterleitet und außerdem den Clients erlaubt den Server nach älteren Nachrichten abzufragen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/tapir/authentication_protocol/index.html b/build-staging/de/security/components/tapir/authentication_protocol/index.html new file mode 100644 index 00000000..a879ade6 --- /dev/null +++ b/build-staging/de/security/components/tapir/authentication_protocol/index.html @@ -0,0 +1,24 @@ + + + + + +Authentifizierungsprotokoll | The Cwtch Handbook + + + + + + + + + + + + +
+

Authentifizierungsprotokoll

Jeder Peer erhält eine offene Verbindung CC:

I=InitializeIdentity()Ie=InitializeEphemeralIdentity()I,IeCP,eCk=KDF(Pei+Pie+Peie)c=E(k,transkript.ommit())cCcpCD(k,cp)=?transcript.LatestCommit()I = \mathrm{InitializeIdentity()} \\ I_e = \mathrm{InitializeEphemeralIdentity()} \\ I,I_e \rightarrow C \\ P, _e \leftarrow C \\ k = \mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\ c = \mathrm{E}(k, transkript. ommit()) \\ c \rightarrow C \\ c_p \leftarrow C\\ \mathrm{D}(k, c_p) \stackrel{?}{=} transcript.LatestCommit()

Das obige stellt ein Skizzenprotokoll dar, in Wirklichkeit gibt es ein paar Implementierungsdetails die es zu erwähnen gilt:

Einmal von der Schlüssel-Ableitungsfunktion (KDF\mathrm{KDF}) abgeleitet, wird der Schlüssel (kk) auf an gesetzt. Dies bedeutet, dass die Authentifizierungs-App die Verschlüsselung oder Entschlüsselung nicht explizit durchführt.

Die Verkettung von Teilen des 3DH Austauschs ist streng geregelt:

  • DH der langfristigen Identität der ausgehenden Verbindung durch den flüchtigen Schlüssel der eingehenden Verbindung.
  • DH der langfristigen Identität der eingehenden Verbindung durch den flüchtigen Schlüssel der ausgehenden Verbindung.
  • DH der beiden ephemeren Identitäten der eingehenden und ausgehenden Verbindungen.

Diese strikte Reihenfolge stellt sicher, dass beide Seiten der Verbindung den gleichen Sitzungsschlüssel ableiten.

Kryptographische Eigenschaften

Während einer Online-Sitzung können alle mit dem Sitzungsschlüssel verschlüsselten Nachrichten von den Peers als von ihrem Peers kommend authentifiziert werden (oder zumindest jemand, der über einen geheimen Schlüssel der Peers verfügt, da dies mit der Onion Adresse in Verbindung steht).

Sobald die Sitzung beendet ist, ein Transkript mit den langfristigen und kurzlebigen öffentlichen Schlüsseln, ein abgeleiteter Session-Schlüssel und alle verschlüsselten Nachrichten in der Sitzung können nicht als authentisch bewiesen werden. dieses Protokoll bietet die Nachricht & Teilnehmer Zurückweisung (offline verweigerbar) zusätzlich zur Nachrichtenunverlinkbarkeit (offline verweigerbar) für den Fall, dass jemand damit zufrieden ist, dass eine einzelne Nachricht im Transkript von einem Peer stammt, es gibt keine Möglichkeit, eine andere Nachricht mit zu verknüpfen.

Intuition für die obigen Ausführungen: Das einzige kryptographische Material, das mit dem Transkript zusammenhängt, ist der abgeleitete Sitzungsschlüssel - wenn der Sitzungsschlüssel veröffentlicht wird, kann er verwendet werden, um neue Nachrichten im Transkript zu schmieden - und als solche unterliegt jede eigenständige Transkription der Möglichkeit einer Fälschung und kann daher nicht verwendet werden, um einen Peer kryptographisch an eine Unterhaltung zu binden.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/tapir/packet_format/index.html b/build-staging/de/security/components/tapir/packet_format/index.html new file mode 100644 index 00000000..d844562f --- /dev/null +++ b/build-staging/de/security/components/tapir/packet_format/index.html @@ -0,0 +1,24 @@ + + + + + +Paketformat | The Cwtch Handbook + + + + + + + + + + + + +
+

Paketformat

Alle Tapir-Pakete haben eine feste Länge (8192 Bytes) und die ersten 2 Bytes zeigen die tatsächliche Länge der Nachricht, len Bytes an Daten und der Rest mit null aufgefüllt:

| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|

Einmal verschlüsselt, ist das gesamte 8192-Byte-Datenpaket mit libsodium secretbox verschlüsselt unter Verwendung der Standardstruktur ( beachte in diesem Fall die tatsächlich benutzbare Größe des Datenpakets ist 8190-14, um die Nonce in der Geheimbox zu unterbringen)

Informationen darüber, wie der geheime Schlüssel abgeleitet wird, findest du im Authentifizierungsprotokoll

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/ui/android/index.html b/build-staging/de/security/components/ui/android/index.html new file mode 100644 index 00000000..de47fc75 --- /dev/null +++ b/build-staging/de/security/components/ui/android/index.html @@ -0,0 +1,24 @@ + + + + + +Android Dienst | The Cwtch Handbook + + + + + + + + + + + + +
+

Android Dienst

Angepasst von: Discreet Log #11: Integration von FFI-Prozessen mit Android-Diensten

Zusätzlich zu der Notwendigkeit, einfache Methodenaufrufe in die Cwtch-Bibliothek zu machen, müssen wir auch in der Lage sein, mit langlaufenden Cwtch-Go-Routinen zu kommunizieren (und Ereignisse von ihnen zu empfangen), die den Tor-Prozess im Hintergrund laufen lassen, den Verbindungs- und Gesprächsstatus für alle deine Kontakte verwalten und einige andere Überwachungs- und Wartungsaufgaben erledigen. Auf herkömmlichen Multitasking-Desktop-Betriebssystemen ist dies kein wirkliches Problem, aber auf mobilen Geräten mit Android müssen wir mit kürzeren Sitzungen, häufigen Entladevorgängen sowie Netzwerk- und Energiebeschränkungen zurechtkommen, die sich im Laufe der Zeit ändern können. Da Cwtch metadatenresistent und datenschutzorientiert sein soll, wollen wir auch Benachrichtigungen bereitstellen, ohne den Google-Push-Benachrichtigungsdienst zu nutzen.

Die Lösung für langlaufende Netzwerkanwendungen wie Cwtch besteht darin, unseren FFI-Code in einen Android Foreground Service zu integrieren. (Und nein, es ist mir nicht entgangen, dass der Code für unser Backend in einem sogenannten ForegroundService untergebracht ist) Die WorkManager-API ermöglicht es uns, mit ein wenig Fingerspitzengefühl verschiedene Arten von Diensten zu erstellen und zu verwalten, darunter auch ForegroundServices. Dies erwies sich als eine gute Wahl für uns, da unser gomobile FFI-Handler bereits in Kotlin geschrieben war und WorkManager uns erlaubt, eine Kotlin-Coroutine zu spezifizieren, die als Dienst aufgerufen wird.

Wenn Sie uns folgen wollen, unsere WorkManager-Spezifikationen werden in der handleCwtch()-Methode von MainActivity.kt erstellt, und die Worker selbst sind in FlwtchWorker.kt definiert.

Unsere einfachen Methodenaufrufe an FFI-Routinen werden auch als WorkManager-Arbeitsanforderungen aktualisiert, so dass wir die Rückgabewerte bequem über den Ergebnis-Callback zurückgeben können.

Ein erster Aufruf (passenderweise Start genannt) wird von FlwtchWorker gekapert, um unsere Eventbus-Schleife zu werden. Da es sich bei FlwtchWorker um eine Co-Routine handelt, ist es für sie ein Leichtes, bei Bedarf aufzugeben und fortzufahren, während sie darauf wartet, dass Ereignisse erzeugt werden. Die Goroutinen von Cwtch können dann Ereignisse ausgeben, die von FlwtchWorker aufgegriffen und entsprechend weitergeleitet werden.

Die Eventbus-Schleife von FlwtchWorker ist nicht nur ein langweiliger Forwarder. Es muss auf bestimmte Nachrichtentypen geprüft werden, die den Android-Status beeinflussen. So sollten beispielsweise bei neuen Nachrichtenereignissen normalerweise Benachrichtigungen angezeigt werden, auf die der Benutzer klicken kann, um das entsprechende Konversationsfenster aufzurufen, auch wenn die App nicht im Vordergrund läuft. Wenn es an der Zeit ist, das Ereignis an die Anwendung weiterzuleiten, verwenden wir LocalBroadcastManager, um die Benachrichtigung an MainActivity.onIntent zu erhalten. Von dort aus verwenden wir wiederum Flutter MethodChannels, um die Ereignisdaten von Kotlin an die Flutter-Engine des Frontends weiterzuleiten, wo das Ereignis schließlich von Dart-Code geparst wird, der die Benutzeroberfläche nach Bedarf aktualisiert.

Nachrichten und andere permanente Zustände werden vom Dienst auf der Festplatte gespeichert, so dass das Frontend nicht aktualisiert werden muss, wenn die Anwendung nicht geöffnet ist. Einige Dinge (wie z. B. Daten und ungelesene Nachrichten) können dann jedoch zu Desynchronisationen zwischen Front- und Backend führen, so dass wir dies beim Starten/Fortsetzen der Anwendung überprüfen, um zu sehen, ob wir Cwtch neu initialisieren und/oder den UI-Status neu synchronisieren müssen.

Schließlich haben wir bei der Implementierung dieser Dienste unter Android festgestellt, dass WorkManager sehr gut darin ist, alte Warteschlangen aufrechtzuerhalten, und zwar so gut, dass alte Worker sogar nach einer Neuinstallation der Anwendung wieder aufgenommen wurden! Das Hinzufügen von Aufrufen zu pruneWork() hilft, dies abzumildern, solange die Anwendung ordnungsgemäß heruntergefahren wurde und alte Aufträge ordnungsgemäß abgebrochen wurden. Dies ist unter Android jedoch häufig nicht der Fall, so dass wir es als zusätzliche Abschwächung für sinnvoll erachten, die Arbeit mit dem Namen des nativen Bibliotheksverzeichnisses zu kennzeichnen:

private fun getNativeLibDir(): String {
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
"im.cwtch.flwtch", // Must be app name
PackageManager.GET_SHARED_LIBRARY_FILES)
return ainfo.nativeLibraryDir
}

... dann brechen wir bei jedem Start der Anwendung alle Aufträge ab, die nicht mit dem richtigen aktuellen Bibliotheksverzeichnis gekennzeichnet sind. Da sich der Name dieses Verzeichnisses bei jeder Installation der Anwendung ändert, verhindert diese Technik, dass wir versehentlich mit einem veralteten Service Worker fortfahren.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/ui/image_previews/index.html b/build-staging/de/security/components/ui/image_previews/index.html new file mode 100644 index 00000000..0d43f58b --- /dev/null +++ b/build-staging/de/security/components/ui/image_previews/index.html @@ -0,0 +1,24 @@ + + + + + +Bildervorschau | The Cwtch Handbook + + + + + + + + + + + + +
+

Bildervorschau

Basierend auf dem Filesharing in Cwtch 1.3 werden die Bildvorschauen durch die Erweiterung des vorgeschlagenen Dateinamens (und nein, wir sind nicht daran interessiert, MIME-Typen oder magische Zahlen zu verwenden) und die angezeigte Größe bestimmt. Wenn diese Option aktiviert ist, lädt das Vorschausystem automatisch freigegebene Bilder in einen konfigurierten Download-Ordner herunter und zeigt sie als Teil der Nachricht selbst an. (Aufgrund von Beschränkungen auf Android werden sie im privaten Cache der App gespeichert und Sie haben die Möglichkeit, sie später an anderer Stelle zu speichern) Die Dateigrößenbeschränkung ist noch nicht festgelegt, wird aber deutlich niedriger sein als die allgemeine Größenbeschränkung für die gemeinsame Nutzung von Dateien, die derzeit bei 10 Gigabyte liegt.

Im Moment unterstützen wir nur Einzelbildnachrichten und jede Bildbearbeitung/jeder Bildausschnitt muss in einer separaten Anwendung erfolgen. Wie in den FAQ zum Filesharing erwähnt, enthalten Bilddateien häufig auch wichtige versteckte Metadaten und du solltest sie nur mit Personen teilen, denen du vertraust.

Bekannte Risiken

Andere Anwendungen und/oder das Betriebssystem, die Informationen aus Bildern ableiten

Bilder müssen irgendwo gespeichert werden und wir haben uns dafür entschieden, sie zunächst unverschlüsselt im Dateisystem zu speichern. Wir haben dies aus 2 Gründen gemacht:

  1. Um leistungsfähigere Dateifreigabeverfahren wie Rehosting zu unterstützen, müssen wir in der Lage sein, Dateien effizient zu scannen und Chunks zu liefern - dies über eine verschlüsselte Datenbankschicht zu tun, würde die Leistung beeinträchtigen.
  2. Diese Informationen müssen immer die Anwendungsgrenze passieren (entweder über Anzeigetreiber oder durch Speichern und Anzeigen der Datei in einer externen Anwendung) - es gibt nichts, was Cwtch nach diesem Punkt tun kann.

Bösartige Bilder, die Cwtch zum Absturz bringen oder anderweitig kompromittieren

Flutter verwendet Skia, um Bilder zu rendern. Der zugrundeliegende Code ist zwar speicherunsicher, wird aber im Rahmen der regulären Entwicklung ausführlich zerfusselt.

Wir führen auch unsere eigenen Fuzz-Tests von Cwtch-Komponenten durch. Bei dieser Analyse haben wir einen einzigen Absturzfehler gefunden, der mit einer fehlerhaften GIF-Datei, die den Renderer dazu veranlasste, eine lächerliche Menge an Speicher zuzuweisen (und schließlich vom Kernel abgelehnt wurde). Um zu verhindern, dass sich dies auf Cwtch auswirkt, haben wir die Richtlinie eingeführt, immer eine maximale cacheWidth und/oder cacheHeight für Bild-Widgets.

Bösartige Bilder werden auf verschiedenen Plattformen unterschiedlich gerendert, was zur Offenlegung von Metadaten führen kann

Vor kurzem wurde ein Fehler in Apples png-Parser gefunden, der dazu führte, dass ein Bild auf Apple-Geräten anders dargestellt wurde als auf Nicht-Apple-Geräten.

Wir haben einige Tests mit unseren Mac-Builds durchgeführt und konnten dieses Problem für Flutter nicht replizieren (da alle Flutter-Builds Skia für das Rendering verwenden), aber wir werden solche Fälle weiterhin in unseren Testkorpus aufnehmen.

Die Bildvorschau bleibt vorerst experimentell und auf freiwilliger Basis.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/ui/input/index.html b/build-staging/de/security/components/ui/input/index.html new file mode 100644 index 00000000..511cea9c --- /dev/null +++ b/build-staging/de/security/components/ui/input/index.html @@ -0,0 +1,24 @@ + + + + + +Eingabe | The Cwtch Handbook + + + + + + + + + + + + +
+

Eingabe

Risiko: Abfangen von Cwtch-Inhalten oder Metadaten durch eine IME auf mobilen Geräten

Status: Teilweise gemildert

Jede Komponente, die die Möglichkeit hat, Daten zwischen einer Person und der Cwtch-App abzufangen, stellt ein potenzielles Sicherheitsrisiko.

Einer der wahrscheinlichsten Abfangjäger ist ein IME (Input Method Editor) eines Drittanbieters, der häufig um Zeichen zu erzeugen, die von ihrem Gerät nicht unterstützt werden.

Selbst gutartige und standardmäßige IME-Anwendungen können unbeabsichtigt Informationen über den Inhalt einer Person preisgeben, z. B. durch Cloud-Synchronisierung, Cloud-Übersetzung oder persönliche Wörterbücher.

Letztlich kann dieses Problem nicht von Cwtch allein gelöst werden, sondern stellt ein größeres Risiko dar, welches auf das gesamte mobile Ökosystem auswirkt.

Ein ähnliches Risiko besteht auf dem Desktop durch die Verwendung ähnlicher Eingabeanwendungen (zusätzlich zu den Software-Keyloggern), Wir sind jedoch der Ansicht, dass dies völlig außerhalb des Rahmens der Cwtch-Risikobewertung liegt (in Übereinstimmung mit anderen Angriffen auf die Sicherheit des zugrunde liegenden Betriebssystems selbst).

Dies wird in Cwtch 1.2 teilweise durch die Verwendung von enableIMEPersonalizedLearning: false entschärft. Siehe diesen PR für weitere Informationen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/components/ui/overlays/index.html b/build-staging/de/security/components/ui/overlays/index.html new file mode 100644 index 00000000..a36b6a01 --- /dev/null +++ b/build-staging/de/security/components/ui/overlays/index.html @@ -0,0 +1,24 @@ + + + + + +Nachrichten Overlays | The Cwtch Handbook + + + + + + + + + + + + +
+

Nachrichten Overlays

Angepasst von: Discreet Log #8: Anmerkungen zur Cwtch Chat API

Hinweis: Dieser Abschnitt behandelt Overlay-Protokolle, die auf das Cwtch-Protokoll aufsetzen. Für Informationen über das Cwtch-Protokoll Nachrichten selbst schaue unter Nachrichtenformate

Wir sehen Cwtch als eine Plattform für die Bereitstellung einer authentifizierten Transportschicht für Anwendungen auf höherer Ebene. Es steht den Entwicklern frei, selbst zu entscheiden, welche Protokolle der Anwendungsschicht sie verwenden wollen, ob sie maßgeschneiderte binäre Nachrichtenformate wünschen oder einfach nur eine HTTP-Bibliothek aufsetzen und die Sache abhaken wollen. Cwtch kann neue Schlüsselpaare für Sie generieren (die zu Onion-Adressen werden; es sind keine DNS-Registrierungen erforderlich!) und du kannst mit REST sicher sein, dass alle Daten, die deine Anwendung vom (anonymen Kommunikations-) Netz empfängt, bereits authentifiziert wurden.

In unserem aktuellen Stack sind die Nachrichten in einen minimalen JSON-Rahmen verpackt, der einige kontextbezogene Informationen über den Nachrichtentyp hinzufügt. Und da es sich bei serialisierten JSON-Objekten nur um Wörterbücher handelt, können wir später bei Bedarf problemlos weitere Metadaten hinzufügen.

Chat-Overlays, Listen und Bulletins

Das ursprüngliche Cwtch alpha zeigte "Overlays": verschiedene Arten, denselben Datenkanal zu interpretieren, abhängig von der Struktur der atomaren Daten selbst. Wir haben einfache Checklisten und BBS/Klassifizierungsanzeigen als Overlays eingefügt, die mit jedem Cwtch-Kontakt angeschaut und geteilt werden konnten, sei es mit einem einzelnen Peer oder einer Gruppe. Das Übertragungsformat sah wie folgt aus:

{o:1,d:"hey there!"}
{o:2,d:"bread",l:"groceries"}
{o:3,d:"garage sale",p:"[parent message signature]"}

Overlay-Feld o bestimmt, ob es ein Chat (1), Liste (2), oder Bulletin (3) Nachricht war. Das Datenfeld d ist überladen und Listen/Bulletins benötigen zusätzliche Informationen darüber, welcher Gruppe/Beitrag sie angehören. (Wir verwenden Nachrichtensignaturen anstelle von IDs, um Probleme wie Ordnungsprobleme und böswillig erstellte IDs zu vermeiden. Auf diese Weise teilt auch das Cwtch-Protokoll dem Frontend mit, welche Nachricht abgeholt wird)

Datenstruktur

Die Implementierung von baumstrukturierten Daten auf einem sequentiellen Nachrichtenspeicher hat offensichtliche Leistungsnachteile. Betrachte z. B. die Nachrichtenansicht, die die neuesten Nachrichten zuerst lädt und nur so weit zurückgeht, dass sie das aktuelle Ansichtsfenster ausfüllt, im Vergleich zu einem (etwas pathologischen) Forum, in dem fast jede Nachricht ein Kind der allerersten Nachricht in der Historie ist, die Gigabytes an Daten enthalten kann. Wenn die Benutzeroberfläche nur Beiträge der obersten Ebene anzeigt, bis der Benutzer sie erweitert, müssen wir den gesamten Verlauf analysieren, bevor wir genügend Informationen erhalten, um überhaupt etwas anzuzeigen.

Ein weiteres Problem besteht darin, dass das Multiplexen all dieser Überlagerungen in einem Datenspeicher "Löcher" in den Daten erzeugt, die lazy-loaded listviews und Scrollbars verwirren. Die Anzahl der Nachrichten kann darauf hinweisen, dass es eine Menge weiterer Informationen gibt, die angezeigt werden können, wenn der Benutzer einfach scrollt, aber wenn sie tatsächlich abgerufen und geparst werden, könnten wir feststellen, dass nichts davon für das aktuelle Overlay relevant ist.

Keines dieser Probleme ist unüberwindbar, aber sie zeigen einen Fehler in unseren ursprünglichen Annahmen über die Art des kollaborativen Nachrichtenflusses und die Art und Weise, wie wir mit diesen Daten umgehen sollten.

Overlay Typen

Wie oben erwähnt, werden Overlays in einem sehr einfachen JSON-Format mit der folgenden Struktur angegeben:

type ChatMessage struct {
O int `json:"o"`
D string `json:"d"`
}

Wo O für Overlay mit den unten dokumentierten unterstützten Overlays steht:

1: data is a chat string
2: data is a list state/delta
3: data is a bulletin state/delta
100: contact suggestion; data is a peer onion address
101: contact suggestion; data is a group invite string

Chat-Nachrichten (Overlay 1)

Die einfachste Variante ist eine Chat-Nachricht, die einfach nur rohe, unverarbeitete Informationen über die Chat-Nachricht enthält.

{o:1,d:"got milk?"}

Einladungen (Overlays 100 und 101)

Anstatt die Einladung als eingehende Kontaktanfrage auf Profilebene zu erhalten, werden neue Inline-Einladungen mit einem bestimmten Kontakt/einer bestimmten Gruppe geteilt, wo sie später eingesehen und/oder angenommen werden können, auch wenn sie zunächst (möglicherweise versehentlich) abgelehnt wurden.

Das Format ist für diese gleichermaßen einfach:

{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}
{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}

Dies stellt eine Abkehr von unserem ursprünglichen "Overlays"-Denken hin zu einer stärker handlungsorientierten Darstellung dar. Das Chat-"Overlay" kann mitteilen, dass jemand etwas getan hat, selbst wenn es auf "ein Element zu einer Liste hinzugefügt" umschrieben wird, und die Listen und Bulletins und andere schön chaotische Daten können ihren Zustand vorberechnet und separat gespeichert haben.

Listen / Bulletin Boards

Hinweis: Wird voraussichtlich in Cwtch Beta 1.5 definiert werden

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/deployment/index.html b/build-staging/de/security/deployment/index.html new file mode 100644 index 00000000..92038c7d --- /dev/null +++ b/build-staging/de/security/deployment/index.html @@ -0,0 +1,24 @@ + + + + + +Veröffentlichung | The Cwtch Handbook + + + + + + + + + + + + +
+

Veröffentlichung

Risiko: Binärdateien werden auf der Website durch böswillige Versionen ersetzt

Status: Teilweise gemildert

Während dieser Prozess jetzt größtenteils automatisiert ist, sollte diese Automatisierung jemals kompromittiert sein, dann gibt es in unserem aktuellen Prozess nichts, was dies erkennen würde.

Wir benötigen:

  • Reproduzierbare Builds - derzeit verwenden wir öffentliche Docker-Container für alle Builds, was jedem erlauben sollte, verteilte Builds mit denen aus dem Quellcode zu vergleichen.
  • Signierte Veröffentlichungen - Open Privacy verwaltet noch keinen öffentlichen Datensatz von Mitarbeitern öffentlichen Schlüsseln. Dies ist wahrscheinlich eine Notwendigkeit um veröffentlichte Builds zu signieren und eine Audit-Kette zu erstellen, die von der Organisation unterstützt wird. Dieser Prozess muss per Definition manuell sein.
+ + + + \ No newline at end of file diff --git a/build-staging/de/security/development/index.html b/build-staging/de/security/development/index.html new file mode 100644 index 00000000..c811f700 --- /dev/null +++ b/build-staging/de/security/development/index.html @@ -0,0 +1,24 @@ + + + + + +Entwicklung | The Cwtch Handbook + + + + + + + + + + + + +
+

Entwicklung

Der Hauptprozess gegen böswillige Akteure bei der Entwicklung von Cwtch ist die Offenheit des Prozesses.

Um diese Offenheit zu verstärken, werden automatisierte buidls, Tests und Paketierungen als Teil der Repositories definiert - Verbesserung der Robustheit der Codebasis in jeder Phase.

Während die einzelnen Tests nicht perfekt sind und alle Prozesse Lücken haben, sollten wir verpflichtet sein, es so einfach wie möglich machen, etwas zu Cwtch beizutragen und gleichzeitig Pipelines und Prozesse so erstellen, dass Fehler (unabsichtlich oder bösartig) so früh wie möglich abgefangen werden.

Risiko: Entwickler liefert bösartigen Code direkt aus

Status: Gemildert

trunk ist derzeit gesperrt und nur 3 Open Privacy Mitarbeiter haben die Berechtigung um es zu überschreiben und darüber hinaus die Verantwortung für die Überwachung der Änderungen.

Darüber hinaus löst jeder neue Pull-Request und Merge automatisierte Builds & Tests aus, die E-Mails und Audit Protokolle auslösen.

Der Code ist auch Open Source und von jedem überprüfbar.

Risiko: Code Regressionen

Status: Teilweise gemildert (Siehe einzelne Projekteinträge in diesem Handbuch für weitere Informationen)

Unsere automatisierten Pipelines haben die Möglichkeit, Regressionen zu erfassen, wenn dieses Verhalten erkennbar ist.

Die größte Herausforderung besteht darin, festzulegen, wie solche Regressionen für die UI erkannt werden - wo das Verhalten nicht so streng definiert ist wie für die einzelnen Bibliotheken.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/intro/index.html b/build-staging/de/security/intro/index.html new file mode 100644 index 00000000..9857a1c3 --- /dev/null +++ b/build-staging/de/security/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Sicherheitshandbuch | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Sicherheitshandbuch

Willkommen im Cwtch Sicherheitshandbuch! Der Zweck dieses Handbuchs ist es, eine Anleitung für die verschiedenen Komponenten des Cwtch Ökosystems zu liefern um die bekannten Risiken und Abschwächungen zu dokumentieren und Diskussionen über Verbesserungen und Aktualisierungen für Cwtch sichere Entwicklungsprozesse zu ermöglichen.

Was ist Cwtch?

Cwtch (/kʊtʃ/ - ein walisisches Wort, das in etwa mit "eine Umarmung, die einen sicheren Ort schafft" übersetzt werden kann) ist ein dezentralisiertes, datenschutzfreundliches Mehrparteien-Nachrichtenprotokoll, das zum Aufbau metadatenresistenter Anwendungen verwendet werden kann.

  • Dezentralisiert und offen: Es gibt keinen „Cwtch-Dienst“ oder „Cwtch-Netzwerk“. Die Cwtch Teilnehmer können ihre eigenen sicheren Räume hosten oder ihre Infrastruktur anderen anbieten, die auf der Suche nach einem sicheren Raum sind. Das Cwtch-Protokoll ist offen und jeder kann Bots, Dienste und Benutzeroberflächen erstellen und in Cwtch integrieren und interagieren.
  • Datenschutz wahrend: Alle Kommunikation in Cwtch ist Ende-zu-Ende verschlüsselt und findet über Tor v3 onion Dienste statt.
  • Metadaten resistent: Cwtch wurde so konzipiert, dass ohne deine ausdrückliche Zustimmung keine Informationen ausgetauscht oder zugänglich sind einschließlich On-the-wire Nachrichten und Protokoll-Metadaten.

Eine (kurze) Geschichte des metadatenresistenten Chats

In den letzten Jahren ist das öffentliche Bewusstsein für die Notwendigkeit und Vorteile von Ende-zu-Ende-verschlüsselten Lösungen mit Anwendungen wie Signal, Whatsapp und Wire gestiegen. Diese bieten Benutzern jetzt sichere Kommunikation.

Diese Werkzeuge benötigen jedoch verschiedene Ebenen von Metadaten, um zu funktionieren und viele dieser Metadaten können verwendet werden, um Details darüber zu erfahren, wie und warum eine Person ein Kommunikationstool nutzt. [rottermanner2015privacy].

Ein Werkzeug, das versucht hat, Metadaten zu reduzieren, ist Ricochet welches 2014 zum ersten Mal veröffentlicht wurde. Ricochet nutzte die Onion-Dienste von Tor v2, um eine sichere Ende-zu-Ende-verschlüsselte Kommunikation zu gewährleisten und die Metadaten der Kommunikation zu schützen.

Es gab keine zentralisierten Server, die beim Routen von Ricochet Unterhaltungen helfen. Keine andere als die an einem Gespräch beteiligten Parteien konnte wissen, dass ein solches Gespräch stattfindet.

Ricochet war nicht ohne Einschränkungen, es gab weder eine Multidevice Unterstützung noch einen Mechanismus zur Unterstützung der Gruppenkommunikation oder eine Unterstützung zum Senden von Nachrichten, während ein Kontakt offline ist.

Dies machte die Annahme von Ricochet zu einer schwierigen Angelegenheit. selbst diejenigen in Umgebungen, die am besten von Metadatenresistenz profitieren würden, wissen nicht, dass es [ermoshina2017can] gibt [renaud2014doesn].

Darüber hinaus ist jede Lösung für dezentralisierte, metadatenresistente Kommunikation mit grundlegenden Problemen konfrontiert, wenn es um Effizienz, Datenschutz und Gruppensicherheit geht (wie von Konsens und Konsistenz der Transkription definiert).

Moderne Alternativen zu Ricochet sind Briar, Zbay und Ricochet Refresh - Jedes Tool versucht, für eine andere Reihe von Kompromissen zu optimieren, z. Briar möchte es Menschen ermöglichen, auch dann zu kommunizieren, wenn die zugrunde liegende Netzwerkinfrastruktur ausgefallen ist, und bietet gleichzeitig Schutz vor Metadatenüberwachung.


Das Cwtch-Projekt begann 2017 als ein Erweiterungsprotokoll für Ricochet, das Gruppengespräche über nicht vertrauenswürdige Server, um dezentrale, metadatenresistente Anwendungen zu ermöglichen (wie gemeinsame Listen und Bulletin Board)

Eine Alpha-Version von Cwtch wurde im Februar 2019 gestartet und seitdem hat das Cwtch-Team ( betrieben von der Open Privacy Research Society) Forschung und Entwicklung zu Cwtch und den zugrunde liegenden Protokollen und Bibliotheken und Problembereichen durchgeführt.

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/references/index.html b/build-staging/de/security/references/index.html new file mode 100644 index 00000000..ec59c2af --- /dev/null +++ b/build-staging/de/security/references/index.html @@ -0,0 +1,24 @@ + + + + + +Referenzen | The Cwtch Handbook + + + + + + + + + + + + +
+

Referenzen

  • Atwater, Erinn und Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."

  • Brooks, John. Ricochet: Anonymous instant messaging for real privacy. https://ricochet.im . Zugriffen: 2018-03-10

  • Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.

  • Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.

  • Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).

  • Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata—New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.

  • Langley, Adam. Pond. https://github.com/agl/pond. Zugriffen: 2018-05-21.

  • Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).

  • Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).

  • Kalysch, A., Bove, D. and Müller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).

  • Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn’t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.

  • Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).

  • Unger, Nik et al. “SoK: secure messaging”. In: Security and Privacy (SP), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232–249 link

+ + + + \ No newline at end of file diff --git a/build-staging/de/security/risk/index.html b/build-staging/de/security/risk/index.html new file mode 100644 index 00000000..cd7f88d6 --- /dev/null +++ b/build-staging/de/security/risk/index.html @@ -0,0 +1,24 @@ + + + + + +Risiko-Modell | The Cwtch Handbook + + + + + + + + + + + + +
+

Risiko-Modell

Es ist bekannt, dass Kommunikationsmetadaten von verschiedenen Gegnern ausgenutzt werden, um die Sicherheit von Systemen zu untergraben, Opfer zu verfolgen und groß angelegte Analysen sozialer Netzwerke durchzuführen, um die Massenüberwachung zu unterstützen. Metadaten-resistente Tools stecken noch in den Kinderschuhen und es fehlt an Forschung zur Konstruktion und Benutzererfahrung solcher Tools.

Cwtch wurde ursprünglich als Erweiterung des Metadaten-resistenten Protokolls Ricochet konzipiert, um die asynchrone Multi-Peer-Gruppenkommunikation durch die Verwendung einer verwerfbaren, nicht vertrauenswürdigen, anonymen Infrastruktur zu unterstützen.

Seitdem hat sich Cwtch zu einem eigenständigen Protokoll entwickelt. In diesem Abschnitt werden die verschiedenen bekannten Risiken beschrieben, die Cwtch zu mindern versucht, und es wird im Rest des Dokuments stark darauf verwiesen, wenn die verschiedenen Unterkomponenten der Cwtch-Architektur erörtert werden.

Bedrohungsmodell

Es ist wichtig zu erkennen und zu verstehen, dass Metadaten in Kommunikationsprotokollen allgegenwärtig sind, es ist in der Tat notwendig, dass solche Protokolle effizient und in großem Umfang funktionieren. Informationen, die für die Unterstützung von Peers und Servern nützlich sind, sind jedoch auch für Gegner, die solche Informationen ausnutzen möchten, von großer Bedeutung.

Für unsere Problemstellung gehen wir davon aus, dass der Inhalt einer Kommunikation so verschlüsselt ist, dass ein Angreifer sie praktisch nicht knacken kann (siehe tapir und cwtch für Details zu der von uns verwendeten Verschlüsselung) und daher konzentrieren wir uns auf den Kontext der Kommunikationsmetadaten.

Wir bemühen uns, die folgenden Kommunikationskontexte zu schützen:

  • Wer ist an einer Kommunikation beteiligt? Es kann möglich sein, Personen oder einfach Geräte- oder Netzwerkkennungen zu identifizieren. Beispiel: „An dieser Kommunikation sind Alice, eine Journalistin, und Bob, ein Regierungsangestellter, beteiligt.“.
  • Wo sind die Gesprächsteilnehmer? Beispiel: „Während dieser Kommunikation war Alice in Frankreich und Bob in Kanada.“
  • Wann hat ein Gespräch stattgefunden? Der Zeitpunkt und die Länge der Kommunikation können viel über die Art eines Anrufs verraten, z. B. „Bob, ein Regierungsangestellter, hat gestern Abend eine Stunde lang mit Alice telefoniert. Dies ist das erste Mal, dass sie kommuniziert haben.“ *Wie wurde das Gespräch vermittelt? Ob eine Konversation über eine verschlüsselte oder unverschlüsselte E-Mail stattgefunden hat, kann nützliche Informationen liefern. Beispiel: „Alice hat gestern eine verschlüsselte E-Mail an Bob gesendet, während sie normalerweise nur Klartext-E-Mails aneinander senden.“
  • Worum geht es in dem Gespräch? Selbst wenn der Inhalt der Kommunikation verschlüsselt ist, ist es manchmal möglich, einen wahrscheinlichen Kontext eines Gesprächs abzuleiten, ohne genau zu wissen, was gesagt wird, z. „Eine Person hat zum Abendessen in einem Pizzaladen angerufen“ oder „Jemand hat um 3 Uhr morgens eine bekannte Selbstmord-Hotline angerufen.“

Über einzelne Konversationen hinaus versuchen wir auch, uns gegen Kontextkorrelationsangriffe zu verteidigen, wobei mehrere Konversationen analysiert werden, um Informationen auf höherer Ebene abzuleiten:

  • Beziehungen: Entdeckung sozialer Beziehungen zwischen zwei Entitäten durch Analyse der Häufigkeit und Länge ihrer Kommunikation über einen bestimmten Zeitraum. z.B. Carol und Eve telefonieren jeden Tag mehrere Stunden am Stück.
  • Cliquen: Entdeckung sozialer Beziehungen zwischen einer Gruppe von Einheiten, die alle miteinander interagieren. z.B. Alice, Bob und Eve kommunizieren alle miteinander.
  • Lose verbundene Cliquen und Brücken-Individuen: Entdeckung von Gruppen, die über Vermittler miteinander kommunizieren, indem Kommunikationsketten analysiert werden (z. B. jedes Mal, wenn Alice mit Bob spricht, spricht sie fast unmittelbar danach mit Carol; Bob und Carol kommunizieren nie.)
  • Muster des Lebens: Entdecken, welche Kommunikation zyklisch und vorhersehbar ist. z.B. Alice ruft Eve jeden Montagabend etwa eine Stunde lang an.

Aktive Angriffe

Falschdarstellungsangriffe

Cwtch bietet keine globale Anzeigenamenregistrierung und daher sind Personen, die Cwtch verwenden, anfälliger für Angriffe, die auf falscher Darstellung beruhen, d. h. Personen, die vorgeben, andere Personen zu sein:

Ein grundlegender Ablauf eines dieser Angriffe sieht wie folgt aus, obwohl auch andere Abläufe existieren:

  • Alice hat einen Freund namens Bob und einen anderen namens Eve
  • Eve findet heraus, dass Alice einen Freund namens Bob hat
  • Eve erstellt Tausende neuer Konten, um eines zu finden, das ein ähnliches Bild / einen ähnlichen öffentlichen Schlüssel wie Bob hat (wird nicht identisch sein, könnte aber jemanden für ein paar Minuten täuschen)
  • Eve nennt dieses neue Konto "Eve Neues Konto" und fügt Alice als Freundin hinzu.
  • Eve ändert dann ihren Namen auf "Eve Neues Konto" in "Bob"
  • Alice sendet Nachrichten, die für „Bob“ bestimmt sind, an Eves gefälschtes Bob-Konto

Da es bei Angriffen mit falscher Darstellung an sich um Vertrauen und Verifizierung geht, besteht die einzige absolute Möglichkeit, sie zu verhindern, darin, dass Benutzer den öffentlichen Schlüssel absolut validieren. Das ist offensichtlich nicht ideal und wird in vielen Fällen einfach nicht passieren.

Daher möchten wir einige Hinweise zur Benutzererfahrung in der ui bereitstellen, um Menschen bei der Entscheidung zu helfen, Konten zu vertrauen und/oder Konten zu unterscheiden die möglicherweise versuchen, sich als andere Benutzer auszugeben.

Eine Anmerkung zu physischen Angriffen

Cwtch betrachtet Angriffe, die physischen Zugriff (oder gleichwertigen Zugriff) auf den Computer des Benutzers erfordern, nicht als praktisch verteidigbar. Im Interesse einer guten Sicherheitstechnik werden wir jedoch in diesem Dokument immer noch auf Angriffe oder Bedingungen verweisen, die ein solches Privileg erfordern und darauf hinweisen, wo von uns eingerichtete Minderungsmaßnahmen fehlschlagen.

+ + + + \ No newline at end of file diff --git a/build-staging/de/sitemap.xml b/build-staging/de/sitemap.xml new file mode 100644 index 00000000..6cbb72e8 --- /dev/null +++ b/build-staging/de/sitemap.xml @@ -0,0 +1 @@ +https://docs.cwtch.im/de/blogweekly0.5https://docs.cwtch.im/de/blog/archiveweekly0.5https://docs.cwtch.im/de/blog/autobindingsweekly0.5https://docs.cwtch.im/de/blog/autobindings-iiweekly0.5https://docs.cwtch.im/de/blog/availability-status-profile-attributesweekly0.5https://docs.cwtch.im/de/blog/cwtch-android-reproducibilityweekly0.5https://docs.cwtch.im/de/blog/cwtch-bindings-reproducibleweekly0.5https://docs.cwtch.im/de/blog/cwtch-developer-documentationweekly0.5https://docs.cwtch.im/de/blog/cwtch-documentationweekly0.5https://docs.cwtch.im/de/blog/cwtch-nightly-1-11weekly0.5https://docs.cwtch.im/de/blog/cwtch-nightly-1-12weekly0.5https://docs.cwtch.im/de/blog/cwtch-nightly-v.11-74weekly0.5https://docs.cwtch.im/de/blog/cwtch-platform-supportweekly0.5https://docs.cwtch.im/de/blog/cwtch-stable-api-designweekly0.5https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-updateweekly0.5https://docs.cwtch.im/de/blog/cwtch-stable-roadmap-update-juneweekly0.5https://docs.cwtch.im/de/blog/cwtch-testing-iweekly0.5https://docs.cwtch.im/de/blog/cwtch-testing-iiweekly0.5https://docs.cwtch.im/de/blog/page/2weekly0.5https://docs.cwtch.im/de/blog/path-to-cwtch-stableweekly0.5https://docs.cwtch.im/de/blog/tagsweekly0.5https://docs.cwtch.im/de/blog/tags/apiweekly0.5https://docs.cwtch.im/de/blog/tags/autobindingsweekly0.5https://docs.cwtch.im/de/blog/tags/bindingsweekly0.5https://docs.cwtch.im/de/blog/tags/cwtchweekly0.5https://docs.cwtch.im/de/blog/tags/cwtch-stableweekly0.5https://docs.cwtch.im/de/blog/tags/cwtch-stable/page/2weekly0.5https://docs.cwtch.im/de/blog/tags/cwtch/page/2weekly0.5https://docs.cwtch.im/de/blog/tags/developer-documentationweekly0.5https://docs.cwtch.im/de/blog/tags/documentationweekly0.5https://docs.cwtch.im/de/blog/tags/libcwtchweekly0.5https://docs.cwtch.im/de/blog/tags/nightlyweekly0.5https://docs.cwtch.im/de/blog/tags/planningweekly0.5https://docs.cwtch.im/de/blog/tags/releaseweekly0.5https://docs.cwtch.im/de/blog/tags/repliqateweekly0.5https://docs.cwtch.im/de/blog/tags/reproducible-buildsweekly0.5https://docs.cwtch.im/de/blog/tags/security-handbookweekly0.5https://docs.cwtch.im/de/blog/tags/supportweekly0.5https://docs.cwtch.im/de/blog/tags/testingweekly0.5https://docs.cwtch.im/de/developing/building-a-cwtch-app/building-an-echobotweekly0.5https://docs.cwtch.im/de/developing/building-a-cwtch-app/core-conceptsweekly0.5https://docs.cwtch.im/de/developing/building-a-cwtch-app/introweekly0.5https://docs.cwtch.im/de/developing/category/building-a-cwtch-appweekly0.5https://docs.cwtch.im/de/developing/introweekly0.5https://docs.cwtch.im/de/developing/releaseweekly0.5https://docs.cwtch.im/de/docs/category/appearanceweekly0.5https://docs.cwtch.im/de/docs/category/behaviourweekly0.5https://docs.cwtch.im/de/docs/category/contributeweekly0.5https://docs.cwtch.im/de/docs/category/conversationsweekly0.5https://docs.cwtch.im/de/docs/category/experimentsweekly0.5https://docs.cwtch.im/de/docs/category/getting-startedweekly0.5https://docs.cwtch.im/de/docs/category/groupsweekly0.5https://docs.cwtch.im/de/docs/category/platformsweekly0.5https://docs.cwtch.im/de/docs/category/profilesweekly0.5https://docs.cwtch.im/de/docs/category/serversweekly0.5https://docs.cwtch.im/de/docs/category/settingsweekly0.5https://docs.cwtch.im/de/docs/chat/accept-deny-new-conversationweekly0.5https://docs.cwtch.im/de/docs/chat/add-contactweekly0.5https://docs.cwtch.im/de/docs/chat/block-contactweekly0.5https://docs.cwtch.im/de/docs/chat/conversation-settingsweekly0.5https://docs.cwtch.im/de/docs/chat/delete-contactweekly0.5https://docs.cwtch.im/de/docs/chat/introductionweekly0.5https://docs.cwtch.im/de/docs/chat/message-formattingweekly0.5https://docs.cwtch.im/de/docs/chat/reply-to-messageweekly0.5https://docs.cwtch.im/de/docs/chat/save-conversation-historyweekly0.5https://docs.cwtch.im/de/docs/chat/share-address-with-friendsweekly0.5https://docs.cwtch.im/de/docs/chat/share-fileweekly0.5https://docs.cwtch.im/de/docs/chat/unblock-contactweekly0.5https://docs.cwtch.im/de/docs/contribute/developingweekly0.5https://docs.cwtch.im/de/docs/contribute/documentationweekly0.5https://docs.cwtch.im/de/docs/contribute/stickersweekly0.5https://docs.cwtch.im/de/docs/contribute/testingweekly0.5https://docs.cwtch.im/de/docs/contribute/translateweekly0.5https://docs.cwtch.im/de/docs/getting-started/supported_platformsweekly0.5https://docs.cwtch.im/de/docs/groups/accept-group-inviteweekly0.5https://docs.cwtch.im/de/docs/groups/create-groupweekly0.5https://docs.cwtch.im/de/docs/groups/edit-group-nameweekly0.5https://docs.cwtch.im/de/docs/groups/introductionweekly0.5https://docs.cwtch.im/de/docs/groups/leave-groupweekly0.5https://docs.cwtch.im/de/docs/groups/manage-known-serversweekly0.5https://docs.cwtch.im/de/docs/groups/send-inviteweekly0.5https://docs.cwtch.im/de/docs/introweekly0.5https://docs.cwtch.im/de/docs/platforms/tailsweekly0.5https://docs.cwtch.im/de/docs/profiles/availability-statusweekly0.5https://docs.cwtch.im/de/docs/profiles/change-nameweekly0.5https://docs.cwtch.im/de/docs/profiles/change-passwordweekly0.5https://docs.cwtch.im/de/docs/profiles/change-profile-imageweekly0.5https://docs.cwtch.im/de/docs/profiles/create-a-profileweekly0.5https://docs.cwtch.im/de/docs/profiles/delete-profileweekly0.5https://docs.cwtch.im/de/docs/profiles/exporting-profileweekly0.5https://docs.cwtch.im/de/docs/profiles/importing-a-profileweekly0.5https://docs.cwtch.im/de/docs/profiles/introductionweekly0.5https://docs.cwtch.im/de/docs/profiles/profile-infoweekly0.5https://docs.cwtch.im/de/docs/profiles/unlock-profileweekly0.5https://docs.cwtch.im/de/docs/servers/create-serverweekly0.5https://docs.cwtch.im/de/docs/servers/delete-serverweekly0.5https://docs.cwtch.im/de/docs/servers/edit-serverweekly0.5https://docs.cwtch.im/de/docs/servers/introductionweekly0.5https://docs.cwtch.im/de/docs/servers/share-keyweekly0.5https://docs.cwtch.im/de/docs/servers/unlock-serverweekly0.5https://docs.cwtch.im/de/docs/settings/appearance/change-languageweekly0.5https://docs.cwtch.im/de/docs/settings/appearance/light-dark-modeweekly0.5https://docs.cwtch.im/de/docs/settings/appearance/streamer-modeweekly0.5https://docs.cwtch.im/de/docs/settings/appearance/ui-columnsweekly0.5https://docs.cwtch.im/de/docs/settings/behaviour/block-unknown-connectionsweekly0.5https://docs.cwtch.im/de/docs/settings/behaviour/notification-contentweekly0.5https://docs.cwtch.im/de/docs/settings/behaviour/notification-policyweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/clickable-linksweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/file-sharingweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/group-experimentweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/image-previews-and-profile-picturesweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/message-formattingweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/qrcodesweekly0.5https://docs.cwtch.im/de/docs/settings/experiments/server-hostingweekly0.5https://docs.cwtch.im/de/docs/settings/introductionweekly0.5https://docs.cwtch.im/de/docs/torweekly0.5https://docs.cwtch.im/de/security/category/connectivity--torweekly0.5https://docs.cwtch.im/de/security/category/cwtchweekly0.5https://docs.cwtch.im/de/security/category/cwtch-componentsweekly0.5https://docs.cwtch.im/de/security/category/cwtch-uiweekly0.5https://docs.cwtch.im/de/security/category/tapirweekly0.5https://docs.cwtch.im/de/security/components/connectivity/introweekly0.5https://docs.cwtch.im/de/security/components/cwtch/groupsweekly0.5https://docs.cwtch.im/de/security/components/cwtch/key_bundlesweekly0.5https://docs.cwtch.im/de/security/components/cwtch/message_formatsweekly0.5https://docs.cwtch.im/de/security/components/cwtch/serverweekly0.5https://docs.cwtch.im/de/security/components/ecosystem-overviewweekly0.5https://docs.cwtch.im/de/security/components/introweekly0.5https://docs.cwtch.im/de/security/components/tapir/authentication_protocolweekly0.5https://docs.cwtch.im/de/security/components/tapir/packet_formatweekly0.5https://docs.cwtch.im/de/security/components/ui/androidweekly0.5https://docs.cwtch.im/de/security/components/ui/image_previewsweekly0.5https://docs.cwtch.im/de/security/components/ui/inputweekly0.5https://docs.cwtch.im/de/security/components/ui/overlaysweekly0.5https://docs.cwtch.im/de/security/deploymentweekly0.5https://docs.cwtch.im/de/security/developmentweekly0.5https://docs.cwtch.im/de/security/introweekly0.5https://docs.cwtch.im/de/security/referencesweekly0.5https://docs.cwtch.im/de/security/riskweekly0.5https://docs.cwtch.im/de/weekly0.5 \ No newline at end of file diff --git a/build-staging/de/video/Group_Create.mp4 b/build-staging/de/video/Group_Create.mp4 new file mode 100644 index 00000000..ae82be93 Binary files /dev/null and b/build-staging/de/video/Group_Create.mp4 differ diff --git a/build-staging/de/video/Group_Invite.mp4 b/build-staging/de/video/Group_Invite.mp4 new file mode 100644 index 00000000..cae8629e Binary files /dev/null and b/build-staging/de/video/Group_Invite.mp4 differ diff --git a/build-staging/de/video/Group_Leave.mp4 b/build-staging/de/video/Group_Leave.mp4 new file mode 100644 index 00000000..ecc5a20b Binary files /dev/null and b/build-staging/de/video/Group_Leave.mp4 differ diff --git a/build-staging/de/video/Group_acceptinvite.mp4 b/build-staging/de/video/Group_acceptinvite.mp4 new file mode 100644 index 00000000..a5d4c740 Binary files /dev/null and b/build-staging/de/video/Group_acceptinvite.mp4 differ diff --git a/build-staging/de/video/Server_Delete.mp4 b/build-staging/de/video/Server_Delete.mp4 new file mode 100644 index 00000000..14831661 Binary files /dev/null and b/build-staging/de/video/Server_Delete.mp4 differ diff --git a/build-staging/de/video/Server_Keys.mp4 b/build-staging/de/video/Server_Keys.mp4 new file mode 100644 index 00000000..d9498451 Binary files /dev/null and b/build-staging/de/video/Server_Keys.mp4 differ diff --git a/build-staging/de/video/Server_Manage.mp4 b/build-staging/de/video/Server_Manage.mp4 new file mode 100644 index 00000000..3c812baa Binary files /dev/null and b/build-staging/de/video/Server_Manage.mp4 differ diff --git a/build-staging/de/video/Server_New.mp4 b/build-staging/de/video/Server_New.mp4 new file mode 100644 index 00000000..af57ff12 Binary files /dev/null and b/build-staging/de/video/Server_New.mp4 differ diff --git a/build-staging/de/video/group_edit.mp4 b/build-staging/de/video/group_edit.mp4 new file mode 100644 index 00000000..55f6af2b Binary files /dev/null and b/build-staging/de/video/group_edit.mp4 differ diff --git a/build-staging/de/video/server_edit.mp4 b/build-staging/de/video/server_edit.mp4 new file mode 100644 index 00000000..4ef7b18c Binary files /dev/null and b/build-staging/de/video/server_edit.mp4 differ diff --git a/build-staging/developing/building-a-cwtch-app/building-an-echobot/index.html b/build-staging/developing/building-a-cwtch-app/building-an-echobot/index.html new file mode 100644 index 00000000..9a5cc6de --- /dev/null +++ b/build-staging/developing/building-a-cwtch-app/building-an-echobot/index.html @@ -0,0 +1,25 @@ + + + + + +Building a Cwtch Echobot | The Cwtch Handbook + + + + + + + + + + + + +
+

Building a Cwtch Echobot

In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.

For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or +framework.

Using CwtchBot (Go)

CwtchBot Framework

This tutorial uses the CwtchBot framework.

Start by creating a new Go project, and a file main.go. In the main function:

package main

import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
"fmt"
"git.openprivacy.ca/sarah/cwtchbot"
_ "github.com/mutecomm/go-sqlcipher/v4"
"os/user"
"path"
)

func main() {
user, _ := user.Current()
cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")
cwtchbot.Launch()

// Set Some Profile Information
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")

fmt.Printf("echobot address: %v\n", cwtchbot.Peer.GetOnion())

for {
message := cwtchbot.Queue.Next()
cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])
switch message.EventType {
case event.NewMessageFromPeer:
msg := cwtchbot.UnpackMessage(message.Data[event.Data])
fmt.Printf("Message: %v\n", msg)
reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))
cwtchbot.Peer.SendMessage(cid.ID, reply)
case event.ContactCreated:
fmt.Printf("Auto approving stranger %v %v\n", cid, message.Data[event.RemotePeer])
// accept the stranger as a new contact
cwtchbot.Peer.AcceptConversation(cid.ID)
// Send Hello...
reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))
cwtchbot.Peer.SendMessage(cid.ID, reply)
}
}
}

Using Imp (Rust)

Imp (Rust) Bot Framework

This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.

use std::borrow::BorrowMut;
use std::thread;
use chrono::{DateTime, FixedOffset};
use libcwtch;
use libcwtch::CwtchLib;
use libcwtch::structs::*;
use libcwtch::event::*;
use cwtch_imp::imp;
use cwtch_imp::behaviour::*;
use cwtch_imp::imp::Imp;

const BOT_HOME: &str = "~/.cwtch/bots/echobot";
const BOT_NAME: &str = "echobot";

struct Echobot {}

fn main() {
let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();
let event_loop_handle = thread::spawn(move || {
let mut echobot = Echobot {};
let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());
bot.event_loop::<Echobot>(echobot.borrow_mut());
});
event_loop_handle.join().expect("Error running event loop");
}

impl imp::EventHandler for Echobot {
fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {
let response = Message {
o: MessageType::TextMessage,
d: message.d,
};
cwtch.send_message(&profile.profile_id, conversation_id, &response);
}

fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {
match event {
Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {
println!(
"\n***** {} at {} *****\n",
name, profile_id.as_str()
);
}
_ => (),
};
}
}
+ + + + \ No newline at end of file diff --git a/build-staging/developing/building-a-cwtch-app/core-concepts/index.html b/build-staging/developing/building-a-cwtch-app/core-concepts/index.html new file mode 100644 index 00000000..8b5d9f92 --- /dev/null +++ b/build-staging/developing/building-a-cwtch-app/core-concepts/index.html @@ -0,0 +1,24 @@ + + + + + +Core Concepts | The Cwtch Handbook + + + + + + + + + + + + +
+

Core Concepts

This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.

Cwtch Home Directory

Often referred to as $CWTCH_HOME, the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application.

Profiles

Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations.

The Event Bus

Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. NewMessageFromPeer and setup an event handler to run code in response to such a message.

For an example see the Echo Bot tutorial.

Settings

Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration.

Experiments

Certain Cwtch features are gated behind experiments. These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all.

+ + + + \ No newline at end of file diff --git a/build-staging/developing/building-a-cwtch-app/intro/index.html b/build-staging/developing/building-a-cwtch-app/intro/index.html new file mode 100644 index 00000000..9eac6ea1 --- /dev/null +++ b/build-staging/developing/building-a-cwtch-app/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Getting Started | The Cwtch Handbook + + + + + + + + + + + + +
+

Getting Started

Choosing A Cwtch Library

Cwtch Go Lib

The official Cwtch library is written in Go and can be found at https://git.openprivacy.ca/cwtch.im/cwtch. This library allows access to all Cwtch functionality.

CwtchBot

We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the building an echobot tutorial.

Autobindings (C-bindings)

The official c-bindings for Cwtch are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI.

libCwtch-rs (Rust)

An experimental rust-fied version of Cwtch Autobindings is available in libCwtch-rs. While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem.

+ + + + \ No newline at end of file diff --git a/build-staging/developing/category/building-a-cwtch-app/index.html b/build-staging/developing/category/building-a-cwtch-app/index.html new file mode 100644 index 00000000..90e23675 --- /dev/null +++ b/build-staging/developing/category/building-a-cwtch-app/index.html @@ -0,0 +1,24 @@ + + + + + +Building a Cwtch App | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/developing/intro/index.html b/build-staging/developing/intro/index.html new file mode 100644 index 00000000..0e5856e6 --- /dev/null +++ b/build-staging/developing/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Introduction to Cwtch Development | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/developing/release/index.html b/build-staging/developing/release/index.html new file mode 100644 index 00000000..fc26c467 --- /dev/null +++ b/build-staging/developing/release/index.html @@ -0,0 +1,24 @@ + + + + + +Release and Packaging Process | The Cwtch Handbook + + + + + + + + + + + + +
+

Release and Packaging Process

Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.

Automated Testing

Drone carries out a suite of automated tests at various stages of the release pipeline.

Test SuiteRepositoryNotes
Integration Testcwtch.im/cwtchA full exercise of peer-to-peer and group messaging
File Sharing Testcwtch.im/cwtchTests that file sharing and image downloading work as expected
Automated Download Testcwtch.im/cwtchTests that automated image downloading (e.g. profile pictures) work as expected
UI Integration Testcwtch.im/cwtch-uiA suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings

Cwtch Autobindings

Drone produces the following build artifacts for all Cwtch autobindings builds.

Build ArtifactPlatformNotes
android/cwtch-sources.jarAndroidgomobile derived source code for the Android Cwtch library
android/cwtch.aarAndroidAndroid Cwtch library. Supports arm, arm64, and amd64.
linux/libCwtch.hLinuxC header file
linux/libCwtch.soLinuxx64 shared library
windows/libCwtch.hWindowsC header file
windows/libCwtch.dllWindowsx64 bit shared library
macos/libCwtch.arm64.dylibMacOSArm64 shared library
macos/libCwtch.x64.dylibMacOSx64 shared library

UI Nightly Builds

We make unreleased versions of Cwtch available for testing as Cwtch Nightlies.

Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:

Build ArtifactPlatformNotes
cwtch-VERSION.apkAndroidSupports arm, arm64, and amd64. Can be sideloaded.
cwtch-VERSION.aabAndroidAndroid App Bundle for publishing to appstores
Cwtch-VERSION.dmgMacOS
cwtch-VERSION.tar.gzLinuxContains the code, libs, and assets in addition to install scripts for various devices
cwtch-VERSION.zipWindows
cwtch-installer-VERSION.exeWindowsNSIS powered installation wizard

Nightly builds are regularly purged from the system

Official Releases

The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps.

When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. v.1.12.0. The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder.

Reproducible Builds

We use repliqate to provide reproducible build scripts for Cwtch.

We update the repliqate-scripts repository with scripts for all official releases. Currently only Cwtch bindings are reproducible

+ + + + \ No newline at end of file diff --git a/build-staging/docs/category/appearance/index.html b/build-staging/docs/category/appearance/index.html new file mode 100644 index 00000000..9e1deeea --- /dev/null +++ b/build-staging/docs/category/appearance/index.html @@ -0,0 +1,24 @@ + + + + + +Appearance | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/behaviour/index.html b/build-staging/docs/category/behaviour/index.html new file mode 100644 index 00000000..affaaffe --- /dev/null +++ b/build-staging/docs/category/behaviour/index.html @@ -0,0 +1,24 @@ + + + + + +Behaviour | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/contribute/index.html b/build-staging/docs/category/contribute/index.html new file mode 100644 index 00000000..ceb7d409 --- /dev/null +++ b/build-staging/docs/category/contribute/index.html @@ -0,0 +1,24 @@ + + + + + +Contribute | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/conversations/index.html b/build-staging/docs/category/conversations/index.html new file mode 100644 index 00000000..eca421f7 --- /dev/null +++ b/build-staging/docs/category/conversations/index.html @@ -0,0 +1,24 @@ + + + + + +Conversations | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/docs/category/experiments/index.html b/build-staging/docs/category/experiments/index.html new file mode 100644 index 00000000..94d4f8f6 --- /dev/null +++ b/build-staging/docs/category/experiments/index.html @@ -0,0 +1,24 @@ + + + + + +Experiments | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/getting-started/index.html b/build-staging/docs/category/getting-started/index.html new file mode 100644 index 00000000..a37881de --- /dev/null +++ b/build-staging/docs/category/getting-started/index.html @@ -0,0 +1,24 @@ + + + + + +Getting started | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/groups/index.html b/build-staging/docs/category/groups/index.html new file mode 100644 index 00000000..89512445 --- /dev/null +++ b/build-staging/docs/category/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Groups | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/platforms/index.html b/build-staging/docs/category/platforms/index.html new file mode 100644 index 00000000..ae0213e9 --- /dev/null +++ b/build-staging/docs/category/platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Platforms | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/profiles/index.html b/build-staging/docs/category/profiles/index.html new file mode 100644 index 00000000..7ecb52f2 --- /dev/null +++ b/build-staging/docs/category/profiles/index.html @@ -0,0 +1,24 @@ + + + + + +Profiles | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/docs/category/servers/index.html b/build-staging/docs/category/servers/index.html new file mode 100644 index 00000000..a7d64c5a --- /dev/null +++ b/build-staging/docs/category/servers/index.html @@ -0,0 +1,24 @@ + + + + + +Servers | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/category/settings/index.html b/build-staging/docs/category/settings/index.html new file mode 100644 index 00000000..2b57216d --- /dev/null +++ b/build-staging/docs/category/settings/index.html @@ -0,0 +1,24 @@ + + + + + +Settings | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/chat/accept-deny-new-conversation/index.html b/build-staging/docs/chat/accept-deny-new-conversation/index.html new file mode 100644 index 00000000..bde934bb --- /dev/null +++ b/build-staging/docs/chat/accept-deny-new-conversation/index.html @@ -0,0 +1,24 @@ + + + + + +Accepting/Denying New Conversations | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/chat/add-contact/index.html b/build-staging/docs/chat/add-contact/index.html new file mode 100644 index 00000000..a6041c44 --- /dev/null +++ b/build-staging/docs/chat/add-contact/index.html @@ -0,0 +1,25 @@ + + + + + +Starting a New Conversation | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/chat/block-contact/index.html b/build-staging/docs/chat/block-contact/index.html new file mode 100644 index 00000000..ce8e5d76 --- /dev/null +++ b/build-staging/docs/chat/block-contact/index.html @@ -0,0 +1,25 @@ + + + + + +Blocking a Contact | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/chat/conversation-settings/index.html b/build-staging/docs/chat/conversation-settings/index.html new file mode 100644 index 00000000..74f51cf1 --- /dev/null +++ b/build-staging/docs/chat/conversation-settings/index.html @@ -0,0 +1,24 @@ + + + + + +Accessing Conversation Settings | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/chat/delete-contact/index.html b/build-staging/docs/chat/delete-contact/index.html new file mode 100644 index 00000000..849d2ab3 --- /dev/null +++ b/build-staging/docs/chat/delete-contact/index.html @@ -0,0 +1,25 @@ + + + + + +Removing a Conversation | The Cwtch Handbook + + + + + + + + + + + + +
+

Removing a Conversation

danger

This feature will result in irreversible deletion. This cannot be undone.

  • In a chat with a contact, go to the conversation settings on the top right
  • Scroll to the leave this conversation button, and press it.
  • You will be prompted to confirm if you want to leave the conversation. This action cannot be undone.
info

This documentation page is a stub. You can help +by expanding it.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/chat/introduction/index.html b/build-staging/docs/chat/introduction/index.html new file mode 100644 index 00000000..b9f8a482 --- /dev/null +++ b/build-staging/docs/chat/introduction/index.html @@ -0,0 +1,27 @@ + + + + + +An Introduction to Cwtch P2P Chat | The Cwtch Handbook + + + + + + + + + + + + +
+

An Introduction to Cwtch P2P Chat

Cwtch uses Tor v3 Onion Services to establish anonymous, peer-to-peer connections between Profiles.

How P2P Chat Works Under the Hood

In order to chat with your friends in a peer-to-peer conversation both must be online.

After a successful connection both parties engage in an authentication protocol which:

  • Asserts that each party has access to the private key associated with their public identity.
  • Generates an ephemeral session key used to encrypt all further communication during the session.

This exchange (documented in further detail in authentication protocol) is offline deniable +i.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the +fact - it is impossible to definitely prove that the exchange happened at all.

Once the authentication process is successful then both you and your friend can communicate away assured that no one else +can learn anything about the contents or the metadata of your conversation.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/chat/message-formatting/index.html b/build-staging/docs/chat/message-formatting/index.html new file mode 100644 index 00000000..ca063f01 --- /dev/null +++ b/build-staging/docs/chat/message-formatting/index.html @@ -0,0 +1,26 @@ + + + + + +Message Formatting | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Formatting

Experiments Required

This feature requires Experiments Enabled and +the Message Formatting Experiment turned on.

Optionally, you can enable Clickable Links to +make URLs in messages clickable in Cwtch.

Cwtch currently supports the following formatting markdown for messages:

  • **bold** which will render bold
  • *italic* which will render italic
  • code which will render code
  • ^superscript^ which will render superscript
  • _subscript_ which will render subscript
  • ~~strikthrough~~ which will render strikethrough
+ + + + \ No newline at end of file diff --git a/build-staging/docs/chat/reply-to-message/index.html b/build-staging/docs/chat/reply-to-message/index.html new file mode 100644 index 00000000..03828345 --- /dev/null +++ b/build-staging/docs/chat/reply-to-message/index.html @@ -0,0 +1,24 @@ + + + + + +Replying to a Message | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/chat/save-conversation-history/index.html b/build-staging/docs/chat/save-conversation-history/index.html new file mode 100644 index 00000000..53da00d5 --- /dev/null +++ b/build-staging/docs/chat/save-conversation-history/index.html @@ -0,0 +1,24 @@ + + + + + +Saving Conversation History | The Cwtch Handbook + + + + + + + + + + + + +
+

Saving Conversation History

By default, for privacy, Cwtch does not preserve conversation history between sessions.

To enable history for a specific conversation:

  1. On a conversation window go to Settings
  2. Go to Save History
  3. Click the dropdown menu
  4. Pick Save History
  5. Now your history will be saved

Conversation history can be turned off at any point by selecting "Delete History" from the drop down menu.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/chat/share-address-with-friends/index.html b/build-staging/docs/chat/share-address-with-friends/index.html new file mode 100644 index 00000000..86c12968 --- /dev/null +++ b/build-staging/docs/chat/share-address-with-friends/index.html @@ -0,0 +1,25 @@ + + + + + +Sharing Cwtch Addresses | The Cwtch Handbook + + + + + + + + + + + + +
+

Sharing Cwtch Addresses

There are many ways to share a Cwtch address.

Sharing Your Cwtch Address

  1. Go to your profile
  2. Click the copy address icon

You can now share this address. People with this address will be able to add you as a Cwtch contact.

For information on blocking connections from people you don't know please see Settings: Block Unknown Connections

Sharing A Friends Cwtch Address

Inside of Cwtch there is another mechanism for exchanging Cwtch addresses.

info

This documentation page is a stub. You can help +by expanding it.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/chat/share-file/index.html b/build-staging/docs/chat/share-file/index.html new file mode 100644 index 00000000..4f1b41d2 --- /dev/null +++ b/build-staging/docs/chat/share-file/index.html @@ -0,0 +1,25 @@ + + + + + +Sharing a File | The Cwtch Handbook + + + + + + + + + + + + +
+

Sharing a File

Experiments Required

This feature requires Experiments Enabled and +the File Sharing Experiment turned on.

Optionally, you can enable Image Previews and Profile Pictures to see display shared image previews in the conversation window.

In a Conversation,

  1. Click on the attachment icon
  2. Find the file you want to send
  3. Confirm you want to send it

How does file sharing with groups work? Are my files stored on a server somewhere?

Files are sent through onion-to-onion Cwtch connections directly from the person offering the file to the person receiving it. The initial offer to send a file is posted as a standard Cwtch conversation/overlay message. For groups, this means that the initial offer (containing the filename, size, hash, and a nonce) is posted to the group server, but then each recipient connects to you individually to receive the actual file contents.

Does that mean I have to be online to send a file?

Yes. If the person offering the file goes offline, you will have to wait for them to come online to resume the file transfer. The underlying protocol splits the files into individually-requestable, verifiable chunks, so that in a future release you will be able to "rehost" a file posted to a group, and even download from multiple hosts at once (sort of like bittorrent).

Why are new contacts popping up in my list?

This is due to how Cwtch currently handles connections from unknown addresses. Since posting a file to a group results in group members connecting to you directly, some of those members might not be in your contact list already and so their download connection to you will appear in your list as a contact request.

What is "SHA512"?

SHA512 is a cryptographic hash that can be used to verify that the file you downloaded is a correct copy of the file that was offered. Cwtch does this verification for you automatically, but you're welcome to try it yourself! Note that we also include a random nonce with file offers, so people can't just ask you for any random hash you might have, or files from conversations they're not part of.

Is there a file size limit?

The current limit is 10 gigabytes per file.

What are these .manifest files?

The .manifest files are used while downloading the file to verify that individual chunks are received correctly, and support resuming interrupted transfers. They also contain the info from the original file offer. You can safely delete them once the download is complete. On Android, the manifests are stored in the app's cache, and can be cleared through your system settings.

What about file metadata?

We send the file's name as a suggestion and to help distinguish it from other file offers. The full path is stripped before sending the offer. You should be wary of hidden metadata that might be stored in the file itself, which varies depending on the file's format. For example, images might contain geolocation info and information about the camera that took them, and PDF files are notorious for containing hidden information such as the author's name or the machine they were created on. In general, you should only send and receive files with people you trust.

Can I download files automatically?

If the Image Previews and Profile Pictures experiment is enabled then Cwtch will automatically download images from accepted conversations

+ + + + \ No newline at end of file diff --git a/build-staging/docs/chat/unblock-contact/index.html b/build-staging/docs/chat/unblock-contact/index.html new file mode 100644 index 00000000..1e2c80d8 --- /dev/null +++ b/build-staging/docs/chat/unblock-contact/index.html @@ -0,0 +1,25 @@ + + + + + +Unblocking a Contact | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/contribute/developing/index.html b/build-staging/docs/contribute/developing/index.html new file mode 100644 index 00000000..d6e7538b --- /dev/null +++ b/build-staging/docs/contribute/developing/index.html @@ -0,0 +1,24 @@ + + + + + +Developing Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Developing Cwtch

This section documents some ways to get started with Cwtch Development.

Cwtch Issues Tracking Process

All Cwtch issues are tracked from the cwtch-ui git repository, even if the bug/feature originates in an upstream library. This allows us to keep everything in one place.

Issues are generally divided into 4 distinct categories:

  • Unprocessed - These are new issues that have not been discussed by the Cwtch team.
  • Scheduled - These issues have been planned for an upcoming release. They are usually tagged with the release they are expected to be fixed in e.g. cwtch-1.11. A core Cwtch team member is likely working on the issue, or is expecting to work on the issue in the coming weeks.
  • Desired - These are issues that we would like to fix but for some reason we are unable to schedule. This might be because the feature is large and requires a lot of effort, or because there is some blocker (e.g. a missing feature in Flutter or some other library) that prevents work on the feature.
  • Help Wanted - These are generally small issues that we would like to fix but that have been designated low priority. These are ideal first issues for volunteers.

If you would like to work on an open bug/feature, please comment on the issue and a member of the Cwtch team will follow up with advice on where to go from there. This helps us keep track of who is working on what problems, and reduces the amount of duplicate work. We aim to answer most queries within 24 hours, feel free to "bump" an issue if it takes longer than that.

note

Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)

Cwtch Pull-Request Process

All pull-requests must be reviewed and approved by a core Cwtch team member prior to merging. Sarah reviews all new and active pull requests multiple times a week.

Build Bot

All Cwtch projects are set up with automated builds and testing. Every pull request is expected to be able to pass through these pipelines prior to being merged. If buildbot reports a failure then Sarah will work with you to determine the issue, and any necessary fixes.

Buildbot can fail for reasons beyond your control e.g. many of our integration tests rely setting up Tor connections, these can be brittle on occasion and result in timeouts and failures. Always confirm the root cause of a test failure before deciding what to do next.

Useful Resources

note

All contributions are eligible for stickers

+ + + + \ No newline at end of file diff --git a/build-staging/docs/contribute/documentation/index.html b/build-staging/docs/contribute/documentation/index.html new file mode 100644 index 00000000..d9f3a1d3 --- /dev/null +++ b/build-staging/docs/contribute/documentation/index.html @@ -0,0 +1,26 @@ + + + + + +Documentation Style Guide | The Cwtch Handbook + + + + + + + + + + + + +
+

Documentation Style Guide

This section documents the expected structure and quality of Cwtch documentation.

Screenshots and Cast of Characters

Most Cwtch documentation should feature at least one screenshot or animated image. Screenshots of the Cwtch application should be focused on the feature being described by the documentation.

To ensure consistency between screenshots we suggest that the profile involved should serve particular, constant, roles.

  • Alice - used to represent the primary profile.
  • Bob - the primary contact, useful when demonstrating peer-to-peer features
  • Carol - a secondary contact, useful when demonstrating group features
  • Mallory - representing a malicious peer (to be used when demonstrating blocking functionality)

Dialogue and Content

Where screenshots and demonstrations show dialogue, conversations, and/or images please keep the conversations short, on a casual topic. Examples include:

  • Organizing a picnic
  • Sharing photos from a vacation
  • Sending a document for review

Experiments

All features that rely on an experiment being enabled should all this out prominently at the top of the page e.g.:

Experiments Required

This feature requires Experiments Enabled and +the Example Experiment turned on.

Risks

If a feature might result in destruction of key material or permanent deletion of state, then these should also be called out +at the top of the documentation e.g.:

danger

This feature will result in irreversible deletion of key material. This cannot be undone.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/contribute/stickers/index.html b/build-staging/docs/contribute/stickers/index.html new file mode 100644 index 00000000..e7c1048e --- /dev/null +++ b/build-staging/docs/contribute/stickers/index.html @@ -0,0 +1,24 @@ + + + + + +Stickers | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/contribute/testing/index.html b/build-staging/docs/contribute/testing/index.html new file mode 100644 index 00000000..aff7b0ba --- /dev/null +++ b/build-staging/docs/contribute/testing/index.html @@ -0,0 +1,26 @@ + + + + + +Testing Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Testing Cwtch

This section documents some ways to get started with Cwtch Testing.

Running Fuzzbot

FuzzBot is our development testing bot. You can add FuzzBot as a contact: cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad.

FuzzBot Help

Sending FuzzBot a help message will trigger it to send a reply with all the currently available testing commands.

For more information on FuzzBot see our Discreet Log development blog.

Join the Cwtch Release Candidate Testers Group

Sending Fuzzbot the command testgroup-invite will cause FuzzBot to invite you to the Cwtch Testers Group! There +you can ask questions, post bug reports and offer feedback.

Cwtch Nightlies

Cwtch Nightly builds are development builds that contain new features that are ready for testing.

The most recent few development versions of Cwtch are available from our build server.

We do not recommend that testers always upgrade to the latest nightly, Instead, we will post a message to the Cwtch Release Candidate Testers group +when a significant nightly becomes available. A nightly is considered significant if it contains a new feature or a major bug fix.

note

All contributions are eligible for stickers

Submitting Feedback

There are three main ways of submitting testing feedback to the team:

  • Via Cwtch: Either via the Release Candidate Testers Group or directly to a Cwtch team member.
  • Via Gitea: Please open an issue in https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues - please do not worry about duplicate issues, we will de-duplicate as part of our triage process.
  • Via Email: Email team@cwtch.im with the bug report and one of our team will look into it.
note

Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)

+ + + + \ No newline at end of file diff --git a/build-staging/docs/contribute/translate/index.html b/build-staging/docs/contribute/translate/index.html new file mode 100644 index 00000000..498ea46d --- /dev/null +++ b/build-staging/docs/contribute/translate/index.html @@ -0,0 +1,24 @@ + + + + + +Translating Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Translating Cwtch

If you would like to contribute translations to Cwtch the application or this handbook here is how

Contributing Translations to the Cwtch Application

There are two ways to contribute to Cwtch applications.

Join our Lokalise Team

We use Lokalise for managing translations for the Cwtch application.

  1. Sign up for a Lokalise account
  2. Email team@cwtch.im with the language you are interested in translating and an email we can use to invite you to our Lokalise team.

Directly via Git

For new translations, you can make a copy of https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb and begin translating - you can then either submit pull requests or directly send updates to us (team@cwtch.im) and we will merge them in.

For adding to existing translations you can make pull requests directly on any file in https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/ and we will review and merge them in.

Cwtch User's Handbook

This handbook is translated through Crowdin.

To join our Crowdin project:

  1. Sign up for an account on Crowdin.
  2. Join the cwtch-users-handbook project.

We bundle up changes to the documentation in batches and sync them with the Crowdin project on a regular basis.

note

All contributions are eligible for stickers

+ + + + \ No newline at end of file diff --git a/build-staging/docs/getting-started/supported_platforms/index.html b/build-staging/docs/getting-started/supported_platforms/index.html new file mode 100644 index 00000000..5fde32b5 --- /dev/null +++ b/build-staging/docs/getting-started/supported_platforms/index.html @@ -0,0 +1,25 @@ + + + + + +Supported Platforms | The Cwtch Handbook + + + + + + + + + + + + +
+

Supported Platforms

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. If you are interested in testing Cwtch on a specific platform, or want to volunteer to help us official support a platform +not listed here, then check out Contibuting to Cwtch.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOSOfficial SDK supprts arm, arm64, and amd64 architectures.
Other Android Distributions🟡🟡Testing Needed.
+ + + + \ No newline at end of file diff --git a/build-staging/docs/groups/accept-group-invite/index.html b/build-staging/docs/groups/accept-group-invite/index.html new file mode 100644 index 00000000..89cf28a7 --- /dev/null +++ b/build-staging/docs/groups/accept-group-invite/index.html @@ -0,0 +1,25 @@ + + + + + +Accepting a Group Invite | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/groups/create-group/index.html b/build-staging/docs/groups/create-group/index.html new file mode 100644 index 00000000..c2065714 --- /dev/null +++ b/build-staging/docs/groups/create-group/index.html @@ -0,0 +1,25 @@ + + + + + +Creating a New Group | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/groups/edit-group-name/index.html b/build-staging/docs/groups/edit-group-name/index.html new file mode 100644 index 00000000..47a8df04 --- /dev/null +++ b/build-staging/docs/groups/edit-group-name/index.html @@ -0,0 +1,25 @@ + + + + + +Editing a Group Name | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/groups/introduction/index.html b/build-staging/docs/groups/introduction/index.html new file mode 100644 index 00000000..811af2bf --- /dev/null +++ b/build-staging/docs/groups/introduction/index.html @@ -0,0 +1,39 @@ + + + + + +An Introduction to Cwtch Groups | The Cwtch Handbook + + + + + + + + + + + + +
+

An Introduction to Cwtch Groups

Experiments Required

This feature requires Experiments Enabled and +the Group Experiment turned on.

Note: Metadata Resistant Group Communication is still an active research area and what is documented here +will likely change in the future.

By default, Cwtch only supports peer-to-peer, online, chat. In order to support multi-party conversations, and offline +delivery, an (untrusted) third-party is required. We call these entities "servers"

These servers can be set up by anyone and are intended to be always online. Most importantly, all communication with a +server is designed such that the server learns as little information as possible about the contents or metadata.

In many respects communication with a server is identical to communication with a regular Cwtch peer, +all the same steps are taken however the server always acts as the inbound peer, and the outbound +peer always uses newly generated ephemeral keypair - so that each server session is disconnected.

As such, peer-server conversations only differ in the kinds of messages that are sent between the two parties, +with the server storing all messages that it receives and thus allowing any client to query for older messages.

The risk model associated with servers is more complicated that peer-to-peer communication, as such we currently +require people who want to use servers within Cwtch to opt-in to the Group Chat experiment +in order to add, manage and create groups on untrusted servers.

How Groups Work Under the Hood

When a person wants to start a group conversation they first randomly generate a secret Group Key. All group communication will be encrypted using this key.

Along with the Group Key, the group creator also decides on a Cwtch Server to use as the host of the group. +For more information on how Servers authenticate themselves see key bundles.

A Group Identifier is generated using the group key and the group server and these three elements are packaged up +into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections).

To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts +their message using the Group Key and generates a cryptographic signature over the Group Id, Group Server +and the decrypted message (see: wire formats for more information).

To receive message from the group, a profile connected to the server hosting the group and downloads all messages (since +their previous connection). Profiles then attempt to decrypt each message using the Group Key and if successful attempt +to verify the signature (see Cwtch Servers Cwtch Groups for an overview of attacks and mitigations).

+ + + + \ No newline at end of file diff --git a/build-staging/docs/groups/leave-group/index.html b/build-staging/docs/groups/leave-group/index.html new file mode 100644 index 00000000..a5a5bf0c --- /dev/null +++ b/build-staging/docs/groups/leave-group/index.html @@ -0,0 +1,25 @@ + + + + + +How to Leave a Group | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/groups/manage-known-servers/index.html b/build-staging/docs/groups/manage-known-servers/index.html new file mode 100644 index 00000000..2b343525 --- /dev/null +++ b/build-staging/docs/groups/manage-known-servers/index.html @@ -0,0 +1,25 @@ + + + + + +Managing Servers | The Cwtch Handbook + + + + + + + + + + + + +
+

Managing Servers

Experiments Required

This feature requires Experiments Enabled and +the Group Experiment turned on.

Cwtch groups are hosted by untrusted servers. If you want to see the servers you know about, their status, and the groups hosted on them:

  1. On your contacts pane
  2. Got to the manage servers icon

Import locally hosted server

  1. To import a locally hosted server click on select local server
  2. Select the server you want
+ + + + \ No newline at end of file diff --git a/build-staging/docs/groups/send-invite/index.html b/build-staging/docs/groups/send-invite/index.html new file mode 100644 index 00000000..4935dcd9 --- /dev/null +++ b/build-staging/docs/groups/send-invite/index.html @@ -0,0 +1,25 @@ + + + + + +Sending Invites to a Group | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/intro/index.html b/build-staging/docs/intro/index.html new file mode 100644 index 00000000..6c1d021f --- /dev/null +++ b/build-staging/docs/intro/index.html @@ -0,0 +1,25 @@ + + + + + +What is Cwtch? | The Cwtch Handbook + + + + + + + + + + + + +
+

What is Cwtch?

Cwtch (/kʊtʃ/ - a Welsh word roughly translating to “a hug that creates a safe place”) is a decentralized, privacy-preserving, metadata resistant messaging app.

  • Decentralized and Open: There is no “Cwtch service” or “Cwtch network”. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch.
  • Privacy Preserving: All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services.
  • Metadata Resistant: Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.

Security, Encryption and Safety

For a more in depth look at the security, privacy, and underlying encryption technology used in Cwtch, please +consult our Security Handbook

Getting Started

You can download the latest version of Cwtch from https://cwtch.im/download/

+ + + + \ No newline at end of file diff --git a/build-staging/docs/platforms/tails/index.html b/build-staging/docs/platforms/tails/index.html new file mode 100644 index 00000000..b053de96 --- /dev/null +++ b/build-staging/docs/platforms/tails/index.html @@ -0,0 +1,26 @@ + + + + + +Running Cwtch on Tails | The Cwtch Handbook + + + + + + + + + + + + +
+

Running Cwtch on Tails

New Feature

New in Cwtch 1.12

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

The following steps require that Tails has been launched with an Administration Password.

Tails uses Onion Grater to guard access to the control port. We have packaged +an oniongrater configuration cwtch-tails.yml and setup script (install-tails.sh) with Cwtch on Linux.

The tails-specific part of the script is reproduced below:

    # Tails needs to be have been setup up with an Administration account
#
# Make Auth Cookie Readable
sudo chmod o+r /var/run/tor/control.authcookie
# Copy Onion Grater Config
sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml
# Restart Onion Grater so the Config Takes effect
sudo systemctl restart onion-grater.service

When launching, Cwtch on Tails should be passed the CWTCH_TAILS=true environment variable to automatically configure Cwtch for running in a Tails-like environment:

exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch

Install Location

The above command, and the below onion grater configuration assume that Cwtch was installed in ~/.local/lib/cwtch/cwtch - if Cwtch was installed somewhere else (or if you are running directly from the download folder) then you will need to adjust the commands.

Onion Grater Configuration

The oniongrater configuration cwtch-tails.yml is reproduced below. As noted this configuration is can likely be restricted much +further.

    ---
# TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern
- apparmor-profiles:
- '/home/amnesia/.local/lib/cwtch/cwtch'
users:
- 'amnesia'
commands:
AUTHCHALLENGE:
- 'SAFECOOKIE .*'
SETEVENTS:
- 'CIRC WARN ERR'
- 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'
GETINFO:
- '.*'
GETCONF:
- 'DisableNetwork'
SETCONF:
- 'DisableNetwork.*'
ADD_ONION:
- '.*'
DEL_ONION:
- '.+'
HSFETCH:
- '.+'
events:
CIRC:
suppress: true
ORCONN:
suppress: true
INFO:
suppress: true
NOTICE:
suppress: true
WARN:
suppress: true
ERR:
suppress: true
HS_DESC:
response:
- pattern: '650 HS_DESC CREATED (\S+) (\S+) (\S+) \S+ (.+)'
replacement: '650 HS_DESC CREATED {} {} {} redacted {}'
- pattern: '650 HS_DESC UPLOAD (\S+) (\S+) .*'
replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'
- pattern: '650 HS_DESC UPLOADED (\S+) (\S+) .+'
replacement: '650 HS_DESC UPLOADED {} {} redacted'
- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH'
- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'
- pattern: '650 HS_DESC RECEIVED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'
- pattern: '.*'
replacement: ''
HS_DESC_CONTENT:
suppress: true

Persistence

By default, Cwtch creates $HOME/.cwtch and saves all encrypted profiles and settings files there. In order to save any profiles/conversations in Cwtch on Tails you will have to backup this folder to a non-volatile home.

See the Tails documentation for setting up persistent storage

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/availability-status/index.html b/build-staging/docs/profiles/availability-status/index.html new file mode 100644 index 00000000..7a0770e2 --- /dev/null +++ b/build-staging/docs/profiles/availability-status/index.html @@ -0,0 +1,24 @@ + + + + + +Setting Availability Status | The Cwtch Handbook + + + + + + + + + + + + +
+

Setting Availability Status

New Feature

New in Cwtch 1.12

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

On the conversations pane click the Status icon next to your profile picture.

A drop-down menu will appear with various options e.g. Available, Away, and Busy

When you select Away or Busy as a status the border of your profile picture will change to reflect the status

Contacts will see this change reflected in their conversations pane.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/change-name/index.html b/build-staging/docs/profiles/change-name/index.html new file mode 100644 index 00000000..cbb8be57 --- /dev/null +++ b/build-staging/docs/profiles/change-name/index.html @@ -0,0 +1,24 @@ + + + + + +Changing Your Display Name | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/change-password/index.html b/build-staging/docs/profiles/change-password/index.html new file mode 100644 index 00000000..533b6d12 --- /dev/null +++ b/build-staging/docs/profiles/change-password/index.html @@ -0,0 +1,24 @@ + + + + + +Changing Your Password | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/change-profile-image/index.html b/build-staging/docs/profiles/change-profile-image/index.html new file mode 100644 index 00000000..ce30a1c2 --- /dev/null +++ b/build-staging/docs/profiles/change-profile-image/index.html @@ -0,0 +1,25 @@ + + + + + +Changing Your Profile Image | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/create-a-profile/index.html b/build-staging/docs/profiles/create-a-profile/index.html new file mode 100644 index 00000000..5ff48c63 --- /dev/null +++ b/build-staging/docs/profiles/create-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Creating a New Profile | The Cwtch Handbook + + + + + + + + + + + + +
+

Creating a New Profile

  1. Press the + action button in the right bottom corner and select "New Profile"
  2. Select a display name
  3. Select if you want to protect this profile locally with strong encryption:
    • Password: your account is protected from other people who may use this device
    • No Password: anyone who has access to this device may be able to access this profile
  4. Fill in your password and re-enter it
  5. Click add new profile

A note on Password Protected (Encrypted) Profiles

Profiles are stored locally on disk and encrypted using a key derived from user-known password (via pbkdf2).

Note that, once encrypted and stored on disk, the only way to recover a profile is by rederiving the key from the password - as such it isn't possible to provide a full list of profiles a user might have access to until they enter a password.

See also: Cwtch Security Handbook: Profile Encryption & Storage

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/delete-profile/index.html b/build-staging/docs/profiles/delete-profile/index.html new file mode 100644 index 00000000..44f40331 --- /dev/null +++ b/build-staging/docs/profiles/delete-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Deleting a Profile | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/exporting-profile/index.html b/build-staging/docs/profiles/exporting-profile/index.html new file mode 100644 index 00000000..d9afe1f6 --- /dev/null +++ b/build-staging/docs/profiles/exporting-profile/index.html @@ -0,0 +1,26 @@ + + + + + +Backup or Exporting a Profile | The Cwtch Handbook + + + + + + + + + + + + +
+

Backup or Exporting a Profile

On the Profile Management Screen:

  1. Select the pencil next to the profile you want to edit
  2. Scroll down to the bottom of the screen
  3. Select "Export Profile"
  4. Choose a location, and a file name
  5. Confirm

Once confirmed, Cwtch will place a copy of the profile at the given location. This file is encrypted to the same +level that the profile is. See A note on Password Protected (Encrypted) Profiles for more information on encrypted +profiles.

This file can be imported into another instance of Cwtch on any device.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/importing-a-profile/index.html b/build-staging/docs/profiles/importing-a-profile/index.html new file mode 100644 index 00000000..e96063ef --- /dev/null +++ b/build-staging/docs/profiles/importing-a-profile/index.html @@ -0,0 +1,26 @@ + + + + + +Importing a Profile | The Cwtch Handbook + + + + + + + + + + + + +
+

Importing a Profile

  1. Press the + action button in the right bottom corner and select "Import Profile"
  2. Select an exported Cwtch profile file to import
  3. Enter the password associated with the profile +and confirm.

Once confirmed, Cwtch will attempt to decrypt the provided file using a key derived from the given password. If successful +the profile will appear on the Profile Management screen and will be ready to use.

note

While a profile can be imported onto multiple devices, currently only one version of a profile can be in-use across all devices at any one time.

Attempts to use the same profile across multiple devices may result in availability issues and messaging failures.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/introduction/index.html b/build-staging/docs/profiles/introduction/index.html new file mode 100644 index 00000000..916e8c19 --- /dev/null +++ b/build-staging/docs/profiles/introduction/index.html @@ -0,0 +1,26 @@ + + + + + +An Introduction to Cwtch Profiles | The Cwtch Handbook + + + + + + + + + + + + +
+

An Introduction to Cwtch Profiles

With Cwtch you can create one of more Profiles. Each profile generates a random ed25519 key pair compatible with +the Tor Network.

This is the identifier that you can give out to people and that they can use to contact you via Cwtch.

Cwtch allows you to create and manage multiple, separate profiles. Each profile is associated with a different +key pair which launches a different onion service.

Manage Profiles

On start up Cwtch will launch the Manage Profiles screen. From this screen you can:

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/profile-info/index.html b/build-staging/docs/profiles/profile-info/index.html new file mode 100644 index 00000000..985328e6 --- /dev/null +++ b/build-staging/docs/profiles/profile-info/index.html @@ -0,0 +1,24 @@ + + + + + +Setting Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Setting Profile Attributes

New Feature

New in Cwtch 1.12

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

On the profile management pane there are three free-form text fields below your profile picture.

You can fill these fields with any information your would like potential contacts to know. This information is public - do not put any information in here that you do not want to share with everyone.

Contacts will be able to see this information in conversation settings

+ + + + \ No newline at end of file diff --git a/build-staging/docs/profiles/unlock-profile/index.html b/build-staging/docs/profiles/unlock-profile/index.html new file mode 100644 index 00000000..4c2683ce --- /dev/null +++ b/build-staging/docs/profiles/unlock-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Unlocking Encrypted Profiles | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/servers/create-server/index.html b/build-staging/docs/servers/create-server/index.html new file mode 100644 index 00000000..14743c67 --- /dev/null +++ b/build-staging/docs/servers/create-server/index.html @@ -0,0 +1,25 @@ + + + + + +How to create a server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/servers/delete-server/index.html b/build-staging/docs/servers/delete-server/index.html new file mode 100644 index 00000000..10ed4b64 --- /dev/null +++ b/build-staging/docs/servers/delete-server/index.html @@ -0,0 +1,25 @@ + + + + + +How to delete server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/servers/edit-server/index.html b/build-staging/docs/servers/edit-server/index.html new file mode 100644 index 00000000..c5c43f22 --- /dev/null +++ b/build-staging/docs/servers/edit-server/index.html @@ -0,0 +1,25 @@ + + + + + +How to edit a server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/servers/introduction/index.html b/build-staging/docs/servers/introduction/index.html new file mode 100644 index 00000000..fde428fc --- /dev/null +++ b/build-staging/docs/servers/introduction/index.html @@ -0,0 +1,25 @@ + + + + + +Servers Introduction | The Cwtch Handbook + + + + + + + + + + + + +
+

Servers Introduction

Experiments Required

This feature requires Experiments Enabled and +the Server Hosting Experiment turned on.

Cwtch contact to contact chat is fully peer to peer, which means if one peer is offline, you cannot chat, and there is no mechanism for multiple people to chat.

To support group chat (and offline delivery) we have created untrusted Cwtch servers which can host messages for a group. The messages are encrypted with the group key, and fetch via ephemeral onions, so the server has no way to know what messages for what groups it might be holding, or who is accessing it.

Currently running servers in the Cwtch app is only supported on the Desktop version as mobile devices' internet conection and environment is too unstable and unsuitable to running a server.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/servers/share-key/index.html b/build-staging/docs/servers/share-key/index.html new file mode 100644 index 00000000..5300da42 --- /dev/null +++ b/build-staging/docs/servers/share-key/index.html @@ -0,0 +1,25 @@ + + + + + +How to share your Server Key Bundle | The Cwtch Handbook + + + + + + + + + + + + +
+

How to share your Server Key Bundle

Experiments Required

This feature requires Experiments Enabled and +the Server Hosting Experiment turned on.

Your server key bundle is the package of data a Cwtch app needs in order to use a server. If you just want to make other Cwtch users aware of your server, you can share this with them. Then they will have the ability to create their own groups on the server.

  1. Go to the server Icon
  2. Select the server you want
  3. Use the copy address icon to copy the server keys
  4. Don’t share the keys with people you don’t trust
+ + + + \ No newline at end of file diff --git a/build-staging/docs/servers/unlock-server/index.html b/build-staging/docs/servers/unlock-server/index.html new file mode 100644 index 00000000..b36917bd --- /dev/null +++ b/build-staging/docs/servers/unlock-server/index.html @@ -0,0 +1,25 @@ + + + + + +How to Unlock a server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/appearance/change-language/index.html b/build-staging/docs/settings/appearance/change-language/index.html new file mode 100644 index 00000000..bef7ae11 --- /dev/null +++ b/build-staging/docs/settings/appearance/change-language/index.html @@ -0,0 +1,24 @@ + + + + + +Change Language | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/appearance/light-dark-mode/index.html b/build-staging/docs/settings/appearance/light-dark-mode/index.html new file mode 100644 index 00000000..d64f7538 --- /dev/null +++ b/build-staging/docs/settings/appearance/light-dark-mode/index.html @@ -0,0 +1,25 @@ + + + + + +Light/Dark and themes Breakdown | The Cwtch Handbook + + + + + + + + + + + + +
+

Light/Dark and themes Breakdown

  1. Press the setting icon
  2. You can choose light or dark theme by toggling the “use light themes” switch
  3. Using the “color theme” drop down menu, pick a theme you like
    1. Cwtch: purple tones
    2. Ghost: Grey tones
    3. Mermaid: Turquoise and +purple tones
    4. Midnight: Black and gray tones
    5. Neon 1: purple and pink tones
    6. Neon 2: purple and turquoise tones
    7. Pumpkin: purple and orange tones
    8. Witch: Green and pink tones
    9. Vampire: Purple and red tones
+ + + + \ No newline at end of file diff --git a/build-staging/docs/settings/appearance/streamer-mode/index.html b/build-staging/docs/settings/appearance/streamer-mode/index.html new file mode 100644 index 00000000..67cddfee --- /dev/null +++ b/build-staging/docs/settings/appearance/streamer-mode/index.html @@ -0,0 +1,25 @@ + + + + + +Streamer/Presentation Mode | The Cwtch Handbook + + + + + + + + + + + + +
+

Streamer/Presentation Mode

Streamer/Presentation mode makes the app more visually private. In this mode, Cwtch will not display +auxiliary information like Cwtch addresses and other sensitive information on the main screens.

This is useful when taking screenshots or otherwise displaying Cwtch in a more public way.

  1. Press the settings icon
  2. Toggle "Streamer Mode" to On
  3. Check it works by looking at your profile or at your contact list
+ + + + \ No newline at end of file diff --git a/build-staging/docs/settings/appearance/ui-columns/index.html b/build-staging/docs/settings/appearance/ui-columns/index.html new file mode 100644 index 00000000..1b20ed23 --- /dev/null +++ b/build-staging/docs/settings/appearance/ui-columns/index.html @@ -0,0 +1,24 @@ + + + + + +UI columns | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/behaviour/block-unknown-connections/index.html b/build-staging/docs/settings/behaviour/block-unknown-connections/index.html new file mode 100644 index 00000000..058d7760 --- /dev/null +++ b/build-staging/docs/settings/behaviour/block-unknown-connections/index.html @@ -0,0 +1,26 @@ + + + + + +Block Unknown Connections | The Cwtch Handbook + + + + + + + + + + + + +
+

Block Unknown Connections

By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. You can change this behaviour through the Block Unknown Connections +setting.

If enabled, Cwtch will auto close all connections from Cwtch addresses that you have not added to your conversation +list. This will prevent people who have your Cwtch address from contacting you unless you also add them.

To enable:

  1. Go to Settings
  2. Toggle on Block Unknown Contacts
+ + + + \ No newline at end of file diff --git a/build-staging/docs/settings/behaviour/notification-content/index.html b/build-staging/docs/settings/behaviour/notification-content/index.html new file mode 100644 index 00000000..3cfc8535 --- /dev/null +++ b/build-staging/docs/settings/behaviour/notification-content/index.html @@ -0,0 +1,24 @@ + + + + + +Notification Content | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/behaviour/notification-policy/index.html b/build-staging/docs/settings/behaviour/notification-policy/index.html new file mode 100644 index 00000000..69c15128 --- /dev/null +++ b/build-staging/docs/settings/behaviour/notification-policy/index.html @@ -0,0 +1,25 @@ + + + + + +Notification policy | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/clickable-links/index.html b/build-staging/docs/settings/experiments/clickable-links/index.html new file mode 100644 index 00000000..7fcc7cc1 --- /dev/null +++ b/build-staging/docs/settings/experiments/clickable-links/index.html @@ -0,0 +1,26 @@ + + + + + +Clickable Links Experiment | The Cwtch Handbook + + + + + + + + + + + + +
+

Clickable Links Experiment

danger

This feature, if enabled, presents a deanonymization risk.

Do not open URLs from people you do not trust. Links sent via Cwtch are opened via the default +browser on the system. Most web browsers cannot provide anonymity.

Enable the Clickable Links Experiment

Clickable links are not enabled by default. To allow Cwtch to open links in messages:

  1. Go to Settings
  2. Enable Experiments
  3. Enable the Clickable Links Experiment

Risks

Clickable links in messages are a very useful feature however there are risks you should be aware of if you +choose to enable this feature.

To prevent accidental triggering, after clicking on a link in a message, Cwtch will first open an additional prompt with two options:

  1. Copy the URL to the Clipboard
  2. Open the URL in the default web browser

You can use the back button on your device, or click away from this prompt to avoid selecting either option.

Cwtch cannot protect you if you open malicious links.

The URL is opened in the default web browser which will likely, at a minimum, expose your IP address to the server hosting the URL. Web pages may also use other browser vulnerabilities to gather additional information, or further exploit your computer.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/file-sharing/index.html b/build-staging/docs/settings/experiments/file-sharing/index.html new file mode 100644 index 00000000..83acb7e2 --- /dev/null +++ b/build-staging/docs/settings/experiments/file-sharing/index.html @@ -0,0 +1,25 @@ + + + + + +File Sharing | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/group-experiment/index.html b/build-staging/docs/settings/experiments/group-experiment/index.html new file mode 100644 index 00000000..05024ccd --- /dev/null +++ b/build-staging/docs/settings/experiments/group-experiment/index.html @@ -0,0 +1,24 @@ + + + + + +Groups Experiment | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/image-previews-and-profile-pictures/index.html b/build-staging/docs/settings/experiments/image-previews-and-profile-pictures/index.html new file mode 100644 index 00000000..da3b708b --- /dev/null +++ b/build-staging/docs/settings/experiments/image-previews-and-profile-pictures/index.html @@ -0,0 +1,24 @@ + + + + + +Image Previews and Profile Pictures | The Cwtch Handbook + + + + + + + + + + + + +
+

Image Previews and Profile Pictures

caution

This experiment requires the File Sharing experiment enabled.

When enabled, Cwtch will download image files automatically, display image previews in the conversation window, and enable the Profile Pictures feature;

On Desktop, enabling this experiment will allow access to an additional setting "Download Folder` which can be changed to tell Cwtch where to (automatically) download pictures.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/message-formatting/index.html b/build-staging/docs/settings/experiments/message-formatting/index.html new file mode 100644 index 00000000..a791758d --- /dev/null +++ b/build-staging/docs/settings/experiments/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Message Formatting | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/qrcodes/index.html b/build-staging/docs/settings/experiments/qrcodes/index.html new file mode 100644 index 00000000..0d5674b4 --- /dev/null +++ b/build-staging/docs/settings/experiments/qrcodes/index.html @@ -0,0 +1,25 @@ + + + + + +QR Codes | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/experiments/server-hosting/index.html b/build-staging/docs/settings/experiments/server-hosting/index.html new file mode 100644 index 00000000..722bac08 --- /dev/null +++ b/build-staging/docs/settings/experiments/server-hosting/index.html @@ -0,0 +1,24 @@ + + + + + +Server Hosting | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/docs/settings/introduction/index.html b/build-staging/docs/settings/introduction/index.html new file mode 100644 index 00000000..2f206ffa --- /dev/null +++ b/build-staging/docs/settings/introduction/index.html @@ -0,0 +1,29 @@ + + + + + +An Introduction to Cwtch App Settings | The Cwtch Handbook + + + + + + + + + + + + +
+

An Introduction to Cwtch App Settings

Appearance

These are settings which effect how Cwtch looks, including themes and localization.

Behaviour

These settings impact how Cwtch responds to certain events e.g. notifications for new messages, or requests +from unknown public addresses.

Experiments

There are many features in Cwtch that people would like to have but whose implementation requires additional metadata, or +risk, beyond the minimum that Cwtch requires for basic operations.

As such under Experiments you will find a number of optional settings which, when enables, provide +additional features like group chat, file sharing or message formatting.

You should think carefully when enabling these features about the new risks that might be involved, and if you +are comfortable opting-in to those risks. For many the benefits of file sharing, image previews and group chat +far outweigh the potential harms - but for other we require everyone to opt-in to these features.

You can opt-out at any time, all features are implemented locally within the Cwtch app.

+ + + + \ No newline at end of file diff --git a/build-staging/docs/tor/index.html b/build-staging/docs/tor/index.html new file mode 100644 index 00000000..90883492 --- /dev/null +++ b/build-staging/docs/tor/index.html @@ -0,0 +1,24 @@ + + + + + +Tor | The Cwtch Handbook + + + + + + + + + + + + +
+

Tor

Cwtch uses Tor to provide routing and connections. Using Tor hidden services to host profiles and on the fly generated "ephemeral" connections when making a connection provides strong anonymity guarantees to users of Cwtch.

Tor Pane

Since we are adding an additional networking layer to Cwtch, we provide a pane to view Tor network status and make changes. To access it

  1. From the profile list pane, click the Tor icon tor icon
  2. View the tor network status
Tor Status: Online
Tor Version: 0.4.6.9

Reset Tor

The Tor network itself can occasionally have stale connections that aren't detected immediatly by it or Cwtch (we're always trying to improve this). Sometimes a user may find contacts or groups appearing offline they feel should be online. If you'd like to restart all the networking connections in Cwtch, we provide a mechanism to reboot tor from within the app. The reset button will reboot Tor from within the Cwtch app.

Cache Tor Consensus

By default we start a fresh Tor process every time the app boots, and it requires downloading some Tor network state before it can start. This process is not instant. If you want to speed up Cwtch booting, you can enable Caching Tor Conensus to speed up future boots. If you run into a boot problem where the data is stale or corrupted and Cwtch is reporting it cannot boot Tor, disable this feature and reset tor again, and it should work.

Advanced Tor Configuration

We also offer the option to provide advance Tor configuration option in this section by allowing you to

  • Specify a custom SOCKS port to connect to an existing Tor over
  • Specify a custom Control port to connect to an existing Tor over
  • and specify further options by entering custom torrc options
+ + + + \ No newline at end of file diff --git a/build-staging/es/.nojekyll b/build-staging/es/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/build-staging/es/404.html b/build-staging/es/404.html new file mode 100644 index 00000000..c2520259 --- /dev/null +++ b/build-staging/es/404.html @@ -0,0 +1,24 @@ + + + + + +Página No Encontrada | The Cwtch Handbook + + + + + + + + + + + + +
+

Página No Encontrada

No pudimos encontrar lo que buscas.

Por favor, contacta al propietario del sitio al que está enlazada la URL original y hazle saber que el enlace está roto.

+ + + + \ No newline at end of file diff --git a/build-staging/es/assets/css/styles.0fcdc540.css b/build-staging/es/assets/css/styles.0fcdc540.css new file mode 100644 index 00000000..39239332 --- /dev/null +++ b/build-staging/es/assets/css/styles.0fcdc540.css @@ -0,0 +1,2 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center,figcaption,figure,figure p a img{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_tbUL,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.sidebar_re4s,.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_S0QG>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q>:last-child,.footer__items{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.sidebarItemTitle_pO2u,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#8e64a5;--ifm-font-color-base:#281831;--ifm-navbar-background-color:#fdf3fc;--ifm-code-font-size:95%;--ifm-footer-background-color:#fdf3fc;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#dfb9de;--ifm-font-color-base:#fdf3fc;--ifm-navbar-background-color:#281831;--ifm-footer-background-color:#281831;--docusaurus-highlighted-code-line-bg:#0000004d}.ui-button{background-color:#fdf3fc;height:24px;width:24px}td>img{vertical-align:sub}figcaption{font-size:10px}h1[class*=" blogPostTitle"],h1[class^=blogPostTitle],h2[class^=blogPostTitle]{font-size:2rem}[data-theme=dark] +.icon{filter:invert(1)}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_b6E3,.sidebarLogo_isFc,.themedImage_ToTc,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedImage--dark_i4oU,[data-theme=light] .themedImage--light_HNdA{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docMainContainer_gTbr,.docPage__5DB{display:flex;width:100%}.docPage__5DB{flex:1 0}.docsWrapper_BCFX{display:flex;flex:1 0 auto}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.buttons_AeoN,.features_t9lD{align-items:center;display:flex}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.heroBanner_qdFl{background:url(/es/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg) top no-repeat;color:#fdf3fc;height:670px;overflow:hidden;padding:4rem 0;position:relative;text-align:center}.heroBanner_qdFl p{color:#fdf3fc;font-weight:700;text-shadow:-1px -1px 0 #281831,1px -1px 0 #281831,-1px 1px 0 #281831,1px 1px 0 #281831}.buttons_AeoN{justify-content:center}.button_JGCe{background-color:#8e64a5;color:#fdf3fc}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.features_t9lD{padding:2rem 0;width:100%}.featureSvg_GfXr{height:200px;width:200px}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.img_ev3q{height:auto}.admonition_LlT9{margin-bottom:1em}.admonitionHeading_tbUL{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.3rem}.admonitionHeading_tbUL code{text-transform:none}.admonitionIcon_kALy{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_kALy svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.blogPostFooterDetailsFull_mRVl{flex-direction:column}.tableOfContents_bqdL{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.searchBox_ZlJk{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_BlDH,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_m80_:focus,.expandButton_m80_:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_m80_{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_BlDH{transform:rotate(180deg)}.docSidebarContainer_b6E3{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_b3ry{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_Xe31{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_gTbr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_Uz_u{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_czyv{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:996px){.heroBanner_qdFl{padding:2rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/build-staging/es/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/es/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/es/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/es/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/es/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/es/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/es/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/es/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/es/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/es/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/es/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/es/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/es/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png b/build-staging/es/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/es/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png differ diff --git a/build-staging/es/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/es/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/es/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/es/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/es/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/es/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/es/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/es/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/es/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/es/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/es/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/es/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/es/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/es/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/es/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/es/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/es/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/es/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/es/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/es/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/es/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/es/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/es/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/es/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/es/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/es/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/es/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/es/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png b/build-staging/es/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/es/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png differ diff --git a/build-staging/es/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png b/build-staging/es/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/es/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png differ diff --git a/build-staging/es/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/es/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/es/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/es/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/es/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/es/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/es/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/es/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/es/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/es/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/es/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/es/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/es/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png b/build-staging/es/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/es/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png differ diff --git a/build-staging/es/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png b/build-staging/es/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/es/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png differ diff --git a/build-staging/es/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png b/build-staging/es/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/es/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png differ diff --git a/build-staging/es/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png b/build-staging/es/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/es/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png differ diff --git a/build-staging/es/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png b/build-staging/es/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/es/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png differ diff --git a/build-staging/es/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png b/build-staging/es/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/es/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png differ diff --git a/build-staging/es/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png b/build-staging/es/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/es/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png differ diff --git a/build-staging/es/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png b/build-staging/es/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/es/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png differ diff --git a/build-staging/es/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png b/build-staging/es/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/es/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png differ diff --git a/build-staging/es/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png b/build-staging/es/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/es/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png differ diff --git a/build-staging/es/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png b/build-staging/es/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/es/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png differ diff --git a/build-staging/es/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png b/build-staging/es/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/es/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png differ diff --git a/build-staging/es/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png b/build-staging/es/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/es/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png differ diff --git a/build-staging/es/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/es/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/es/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/es/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg b/build-staging/es/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/es/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg differ diff --git a/build-staging/es/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/es/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/es/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/es/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/es/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/es/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/es/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/es/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/es/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/es/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/es/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/es/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/es/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/es/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/es/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/es/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/es/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/es/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/es/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/es/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/es/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/es/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/es/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/es/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/es/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg b/build-staging/es/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/es/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg differ diff --git a/build-staging/es/assets/js/00242891.62d32fdf.js b/build-staging/es/assets/js/00242891.62d32fdf.js new file mode 100644 index 00000000..aae1d6f3 --- /dev/null +++ b/build-staging/es/assets/js/00242891.62d32fdf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4667],{1369:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/cwtch-stable/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/es/blog/tags/cwtch-stable","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/01a85c17.fbcc85f1.js b/build-staging/es/assets/js/01a85c17.fbcc85f1.js new file mode 100644 index 00000000..ea8df306 --- /dev/null +++ b/build-staging/es/assets/js/01a85c17.fbcc85f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4013],{9058:(e,t,a)=>{a.d(t,{Z:()=>E});var l=a(7294),r=a(6010),n=a(7961),s=a(7524),i=a(9960),c=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function o(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,c.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function g(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function b(e){return l.createElement(u.Zo,{component:g,props:e})}function d(e){let{sidebar:t}=e;const a=(0,s.i)();return t?.items.length?"mobile"===a?l.createElement(b,{sidebar:t}):l.createElement(o,{sidebar:t}):null}function E(e){const{sidebar:t,toc:a,children:s,...i}=e,c=t&&t.items.length>0;return l.createElement(n.Z,i,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(d,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":c,"col--9 col--offset-1":!c}),itemScope:!0,itemType:"http://schema.org/Blog"},s),a&&l.createElement("div",{className:"col col--2"},a))))}},1223:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var l=a(7294),r=a(6010),n=a(5999);const s=()=>(0,n.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var i=a(1944),c=a(5281),m=a(9058),o=a(3008);const u={tag:"tag_Nnez"};function g(e){let{letterEntry:t}=e;return l.createElement("article",null,l.createElement("h2",null,t.letter),l.createElement("ul",{className:"padding--none"},t.tags.map((e=>l.createElement("li",{key:e.permalink,className:u.tag},l.createElement(o.Z,e))))),l.createElement("hr",null))}function b(e){let{tags:t}=e;const a=function(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[l]=t;return a.localeCompare(l)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}(t);return l.createElement("section",{className:"margin-vert--lg"},a.map((e=>l.createElement(g,{key:e.letter,letterEntry:e}))))}var d=a(197);function E(e){let{tags:t,sidebar:a}=e;const n=s();return l.createElement(i.FG,{className:(0,r.Z)(c.k.wrapper.blogPages,c.k.page.blogTagsListPage)},l.createElement(i.d,{title:n}),l.createElement(d.Z,{tag:"blog_tags_list"}),l.createElement(m.Z,{sidebar:a},l.createElement("h1",null,n),l.createElement(b,{tags:t})))}},3008:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(7294),r=a(6010),n=a(9960);const s={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function i(e){let{permalink:t,label:a,count:i}=e;return l.createElement(n.Z,{href:t,className:(0,r.Z)(s.tag,i?s.tagWithCount:s.tagRegular)},a,i&&l.createElement("span",null,i))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/02d640a3.9bc03a47.js b/build-staging/es/assets/js/02d640a3.9bc03a47.js new file mode 100644 index 00000000..ec78c159 --- /dev/null +++ b/build-staging/es/assets/js/02d640a3.9bc03a47.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3066],{3156:e=>{e.exports=JSON.parse('{"title":"Contribuye","slug":"/category/contribute","permalink":"/es/docs/category/contribute","navigation":{"previous":{"title":"Tor","permalink":"/es/docs/tor"},"next":{"title":"Developing Cwtch","permalink":"/es/docs/contribute/developing"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/03aa1116.d741ae55.js b/build-staging/es/assets/js/03aa1116.d741ae55.js new file mode 100644 index 00000000..ea5bd539 --- /dev/null +++ b/build-staging/es/assets/js/03aa1116.d741ae55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9587],{1472:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/cwtch-stable","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/es/blog/tags/cwtch-stable/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/049fd9f7.2c598970.js b/build-staging/es/assets/js/049fd9f7.2c598970.js new file mode 100644 index 00000000..d9187044 --- /dev/null +++ b/build-staging/es/assets/js/049fd9f7.2c598970.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[426],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),l=c(r),d=o,f=l["".concat(p,".").concat(d)]||l[d]||m[d]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var p in t)hasOwnProperty.call(t,p)&&(a[p]=t[p]);a.originalType=e,a[l]="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Groups Experiment",a={unversionedId:"settings/experiments/group-experiment",id:"settings/experiments/group-experiment",title:"Groups Experiment",description:"Enables Cwtch to connect to untrusted servers and use them to host private, asynchronous, groups.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/group-experiment.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/group-experiment",permalink:"/es/docs/settings/experiments/group-experiment",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/group-experiment.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Experiments",permalink:"/es/docs/category/experiments"},next:{title:"Alojamiento de servidor",permalink:"/es/docs/settings/experiments/server-hosting"}},p={},c=[{value:"To Turn On",id:"to-turn-on",level:2}],u={toc:c},l="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"groups-experiment"},"Groups Experiment"),(0,o.kt)("p",null,"Enables Cwtch to ",(0,o.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},"connect to untrusted servers")," and use them to ",(0,o.kt)("a",{parentName:"p",href:"/docs/groups/introduction"},"host private, asynchronous, groups"),"."),(0,o.kt)("h2",{id:"to-turn-on"},"To Turn On"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ir a Configuraci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Habilitar Experimentos"),(0,o.kt)("li",{parentName:"ol"},"Habilitar el Experimento de Grupos")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/05def798.8eeab94d.js b/build-staging/es/assets/js/05def798.8eeab94d.js new file mode 100644 index 00000000..b596431a --- /dev/null +++ b/build-staging/es/assets/js/05def798.8eeab94d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8798],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:3},i="Columnas de interfaz",c={unversionedId:"settings/appearance/ui-columns",id:"settings/appearance/ui-columns",title:"Columnas de interfaz",description:"1. Pulsa el icono de configuraci\xf3n",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/ui-columns.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/ui-columns",permalink:"/es/docs/settings/appearance/ui-columns",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/ui-columns.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Explicaci\xf3n de temas Claros/Oscuros",permalink:"/es/docs/settings/appearance/light-dark-mode"},next:{title:"Modo de streaming/presentaci\xf3n",permalink:"/es/docs/settings/appearance/streamer-mode"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"columnas-de-interfaz"},"Columnas de interfaz"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pulsa el icono de configuraci\xf3n"),(0,a.kt)("li",{parentName:"ol"},"Haz clic en sencilla"),(0,a.kt)("li",{parentName:"ol"},"Selecciona la configuraci\xf3n de columnas que deseas utilizar")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/062eafd9.24dd9419.js b/build-staging/es/assets/js/062eafd9.24dd9419.js new file mode 100644 index 00000000..6dcee6ad --- /dev/null +++ b/build-staging/es/assets/js/062eafd9.24dd9419.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[984],{2700:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/autobindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/06622c1f.35e752cc.js b/build-staging/es/assets/js/06622c1f.35e752cc.js new file mode 100644 index 00000000..e9f7283e --- /dev/null +++ b/build-staging/es/assets/js/06622c1f.35e752cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4811],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>d});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=n.createContext({}),s=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=s(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},f=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(t),f=a,d=u["".concat(l,".").concat(f)]||u[f]||m[f]||o;return t?n.createElement(d,i(i({ref:r},p),{},{components:t})):n.createElement(d,i({ref:r},p))}));function d(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var o=t.length,i=new Array(o);i[0]=f;var c={};for(var l in r)hasOwnProperty.call(r,l)&&(c[l]=r[l]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var s=2;s{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=t(7462),a=(t(7294),t(3905));const o={sidebar_position:2},i="Cambiar tu nombre para mostrar",c={unversionedId:"profiles/change-name",id:"profiles/change-name",title:"Cambiar tu nombre para mostrar",description:"1. En la vista Administrar Perfiles, pulsa el l\xe1piz junto al perfil que deseas editar",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/change-name.md",sourceDirName:"profiles",slug:"/profiles/change-name",permalink:"/es/docs/profiles/change-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-name.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Crear un nuevo perfil",permalink:"/es/docs/profiles/create-a-profile"},next:{title:"Cambiar tu contrase\xf1a",permalink:"/es/docs/profiles/change-password"}},l={},s=[],p={toc:s},u="wrapper";function m(e){let{components:r,...t}=e;return(0,a.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cambiar-tu-nombre-para-mostrar"},"Cambiar tu nombre para mostrar"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"En la vista Administrar Perfiles, pulsa el l\xe1piz junto al perfil que deseas editar"),(0,a.kt)("li",{parentName:"ol"},"Cambia tu nombre"),(0,a.kt)("li",{parentName:"ol"},"Haz clic en guardar perfil")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/09ee442d.c0a61b67.js b/build-staging/es/assets/js/09ee442d.c0a61b67.js new file mode 100644 index 00000000..2972ba9a --- /dev/null +++ b/build-staging/es/assets/js/09ee442d.c0a61b67.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1319],{3905:(e,t,a)=>{a.d(t,{Zo:()=>l,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),p=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(a),u=r,m=d["".concat(c,".").concat(u)]||d[u]||h[u]||o;return a?n.createElement(m,i(i({ref:t},l),{},{components:a})):n.createElement(m,i({ref:t},l))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const o={sidebar_position:1},i="Cwtch Security Handbook",s={unversionedId:"intro",id:"intro",title:"Cwtch Security Handbook",description:"Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/intro.md",sourceDirName:".",slug:"/intro",permalink:"/es/security/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Risk Model",permalink:"/es/security/risk"}},c={},p=[{value:"What is Cwtch?",id:"what-is-cwtch",level:2},{value:"A (Brief) History of Metadata Resistant Chat",id:"a-brief-history-of-metadata-resistant-chat",level:2}],l={toc:p},d="wrapper";function h(e){let{components:t,...a}=e;return(0,r.kt)(d,(0,n.Z)({},l,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"cwtch-security-handbook"},"Cwtch Security Handbook"),(0,r.kt)("p",null,"Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes."),(0,r.kt)("p",null,(0,r.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/2.png",alt:null})),(0,r.kt)("h2",{id:"what-is-cwtch"},"What is Cwtch?"),(0,r.kt)("p",null,"Cwtch (/k\u028at\u0283/ - a Welsh word roughly translating to \u201ca hug that creates a safe place\u201d) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Decentralized and Open"),": There is no \u201cCwtch service\u201d or \u201cCwtch network\u201d. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Privacy Preserving"),": All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Metadata Resistant"),": Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.")),(0,r.kt)("h2",{id:"a-brief-history-of-metadata-resistant-chat"},"A (Brief) History of Metadata Resistant Chat"),(0,r.kt)("p",null,"In recent years, public awareness of the need and benefits of end-to-end encrypted solutions has increased with applications like ",(0,r.kt)("a",{parentName:"p",href:"https://signalapp.org"},"Signal"),", ",(0,r.kt)("a",{parentName:"p",href:"https://whatsapp.com"},"Whatsapp")," and ",(0,r.kt)("a",{parentName:"p",href:"https://wire.org"},"Wire")," now providing users with secure communications."),(0,r.kt)("p",null,"However, these tools require various levels of metadata exposure to function, and much of this metadata can be used to gain details about how and why a person is using a tool to communicate. ",(0,r.kt)("a",{parentName:"p",href:"https://www.researchgate.net/profile/Peter_Kieseberg/publication/299984940_Privacy_and_data_protection_in_smartphone_messengers/links/5a1a9c29a6fdcc50adeb1335/Privacy-and-data-protection-in-smartphone-messengers.pdf"},"[rottermanner2015privacy]"),"."),(0,r.kt)("p",null,"One tool that did seek to reduce metadata is ",(0,r.kt)("a",{parentName:"p",href:"https://ricochet.im"},"Ricochet")," first released in 2014. Ricochet used Tor v2 onion services to provide secure end-to-end encrypted communication, and to protect the metadata of communications."),(0,r.kt)("p",null,"There were no centralized servers that assist in routing Ricochet conversations. No one other than the parties involved in a conversation could know that such a conversation is taking place."),(0,r.kt)("p",null,"Ricochet wasn't without limitations; there was no multi-device support, nor is there a mechanism for supporting group communication or for a user to send messages while a contact is offline."),(0,r.kt)("p",null,"This made adoption of Ricochet a difficult proposition; with even those in environments that would be served best by metadata resistance unaware that it exists ",(0,r.kt)("a",{parentName:"p",href:"https://www.academia.edu/download/53192589/ermoshina-12.pdf"},"[ermoshina2017can]")," ",(0,r.kt)("a",{parentName:"p",href:"https://eprints.gla.ac.uk/116203/1/116203.pdf"},"[renaud2014doesn]"),"."),(0,r.kt)("p",null,"Additionally, any solution to decentralized, metadata resistant communication faces ",(0,r.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"fundamental problems")," when it comes to efficiency, privacy and group security (as defined by ",(0,r.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"transcript consensus and consistency"),")."),(0,r.kt)("p",null,"Modern alternatives to Ricochet include ",(0,r.kt)("a",{parentName:"p",href:"https://briarproject.org"},"Briar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://www.zbay.app/"},"Zbay")," and ",(0,r.kt)("a",{parentName:"p",href:"https://www.ricochetrefresh.net/"},"Ricochet Refresh")," - each tool seeks to optimize for a different set of trade-offs e.g. Briar seeks to allow people to communicate ",(0,r.kt)("a",{parentName:"p",href:"https://briarproject.org/how-it-works/"},"even when underlying network infrastructure is down")," while providing resistant to metadata surveillance."),(0,r.kt)("hr",null),(0,r.kt)("p",null,"The Cwtch project began in 2017 as an extension protocol for Ricochet providing group conversations via untrusted servers, with an eye to enabling decentralized, metadata resistant applications (like shared lists and bulletin board)"),(0,r.kt)("p",null,"An alpha version of Cwtch was ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/blog/2019/02/14/cwtch-alpha/"},"was launched in February 2019"),", and since then the Cwtch team (run by the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca"},"Open Privacy Research Society"),") has conducted research and development into Cwtch and the underlying protocols and libraries and problem spaces."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/0aa99d8f.1048080d.js b/build-staging/es/assets/js/0aa99d8f.1048080d.js new file mode 100644 index 00000000..b8fcb62d --- /dev/null +++ b/build-staging/es/assets/js/0aa99d8f.1048080d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3633],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>f});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),u=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=u(e.components);return n.createElement(c.Provider,{value:r},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),l=u(t),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||a;return t?n.createElement(f,i(i({ref:r},p),{},{components:t})):n.createElement(f,i({ref:r},p))}));function f(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[l]="string"==typeof e?e:o,i[1]=s;for(var u=2;u{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>u});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:1},i="Introducci\xf3n a Servidores",s={unversionedId:"servers/introduction",id:"servers/introduction",title:"Introducci\xf3n a Servidores",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/introduction.md",sourceDirName:"servers",slug:"/servers/introduction",permalink:"/es/docs/servers/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Servers",permalink:"/es/docs/category/servers"},next:{title:"C\xf3mo crear un servidor",permalink:"/es/docs/servers/create-server"}},c={},u=[],p={toc:u},l="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(l,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introducci\xf3n-a-servidores"},"Introducci\xf3n a Servidores"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Experimento de Grupos")," activado.")),(0,o.kt)("p",null,"El chat de Cwtch entre dos usuarios es completamente par a par (peer-to-peer), lo que significa que si un usuario est\xe1 desconectado no puedes chatear con \xe9l, y no hay un mecanismo para que m\xfaltiples personas puedan chatear."),(0,o.kt)("p",null,"Para dar soporte al chat de grupo (y a la entrega sin conexi\xf3n) hemos creado servidores no confiables que pueden albergar mensajes para un grupo. Los mensajes se cifran con la clave del grupo, y se obtienen a trav\xe9s de Onions ef\xedmeros, por lo que el servidor no tiene forma de saber qu\xe9 mensajes podr\xeda tener para qu\xe9 grupos, o qui\xe9n est\xe1 accediendo a \xe9l."),(0,o.kt)("p",null,"Los servidores que se ejecutan actualmente en la aplicaci\xf3n Cwtc s\xf3lo son compatibles con la versi\xf3n de Escritorio ya que la conexi\xf3n a Internet de los dispositivos m\xf3viles y el entorno m\xf3vil es demasiado inestable e inadecuado para ejecutar un servidor."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/0c1afdee.2cd087a1.js b/build-staging/es/assets/js/0c1afdee.2cd087a1.js new file mode 100644 index 00000000..75125269 --- /dev/null +++ b/build-staging/es/assets/js/0c1afdee.2cd087a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6060],{5356:s=>{s.exports=JSON.parse('{"label":"support","permalink":"/es/blog/tags/support","allTagsPath":"/es/blog/tags","count":3}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/0c1d60b0.73c4584d.js b/build-staging/es/assets/js/0c1d60b0.73c4584d.js new file mode 100644 index 00000000..5604aa64 --- /dev/null +++ b/build-staging/es/assets/js/0c1d60b0.73c4584d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4174],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(r),m=o,f=p["".concat(l,".").concat(m)]||p[m]||h[m]||s;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,a=new Array(s);a[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,a[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const s={},a="Cwtch Server",i={unversionedId:"components/cwtch/server",id:"components/cwtch/server",title:"Cwtch Server",description:"The goal of the Cwtch protocol is to enable group communication through Untrusted Infrastructure.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/server.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/server",permalink:"/es/security/components/cwtch/server",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/es/security/components/cwtch/groups"},next:{title:"Cwtch UI",permalink:"/es/security/category/cwtch-ui"}},l={},c=[{value:"Malicious Servers",id:"malicious-servers",level:2},{value:"Detectable Faults",id:"detectable-faults",level:3},{value:"Efficiency",id:"efficiency",level:2}],u={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cwtch-server"},"Cwtch Server"),(0,o.kt)("p",null,"The goal of the Cwtch protocol is to enable group communication through ",(0,o.kt)("strong",{parentName:"p"},"Untrusted Infrastructure"),"."),(0,o.kt)("p",null,"Unlike in relay-based schemes where the groups assign a leader, set of leaders, or a trusted third party server to ensure that every member of the group can send and receive messages in a timely manner (even if members are offline) - untrusted infrastructure has a goal of realizing those properties without the assumption of trust."),(0,o.kt)("p",null,"The original Cwtch paper defined a set of properties that Cwtch Servers were expected to provide:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Cwtch Server may be used by multiple groups or just one."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server, without collaboration of a group member, should never learn the identity of participants within a group."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server should never learn the content of any communication."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server should never be able to distinguish messages as belonging to a particular group.")),(0,o.kt)("p",null,"We note here that these properties are a superset of the design aims of Private Information Retrieval structures."),(0,o.kt)("h2",{id:"malicious-servers"},"Malicious Servers"),(0,o.kt)("p",null,"We expect the presence of malicious entities within the Cwtch ecosystem."),(0,o.kt)("p",null,"We also prioritize decentralization and permissionless entry into the ecosystem and as such we do not base any security claims on the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Any non-collusion assumptions between a set of Cwtch servers"),(0,o.kt)("li",{parentName:"ul"},"Any third-party defined verification process")),(0,o.kt)("p",null,"Peers themselves are encouraged to set up and run Cwtch servers where they can guarantee more efficient properties by relaxing trust and security assumptions - however, by default, we design the protocol to be secure without these assumptions - sacrificing efficiency where necessary."),(0,o.kt)("h3",{id:"detectable-faults"},"Detectable Faults"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"If a Cwtch server fails to relay a specific message to a subset of group members then there will be a detectable gap in the message tree of certain peers that can be discovered through peer-to-peer gossip."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch server cannot modify any message without the key material known to the group (any attempt to do so for a subset of group members will result in identical behavior to failing to relay a message)."),(0,o.kt)("li",{parentName:"ul"},"While a server ",(0,o.kt)("em",{parentName:"li"},"can")," duplicate messages, these will have no impact on the group message tree (because of encryption, nonces and message identities) - the source of the duplication is not knowable to a peer.")),(0,o.kt)("h2",{id:"efficiency"},"Efficiency"),(0,o.kt)("p",null,'As of writing, only 1 protocol is known for achieving the desired properties, naive PIR or "the server sends everything, and the peers sift through it".'),(0,o.kt)("p",null,"This has an obvious impact on bandwidth efficiency, especially for peers using mobile devices, as such we are actively developing new protocols in which the privacy and efficiency guarantees can be traded-off in different ways."),(0,o.kt)("p",null,"As of writing, the servers allow both a complete download of all stored messages, and a request to download messages from a certain specified message."),(0,o.kt)("p",null,"All peers when they first join a group on a new server download all messages from the server, and from then on download only new messages."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note"),": This behaviour does permit a mild form of metadata analysis. The server can new messages for each suspected unique profile, and then use these unique message signatures to track unique sessions over time ( via requests for new messages)."),(0,o.kt)("p",null,"This is mitigated by 2 confounding factors:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Profiles can refresh their connections at any time - resulting in fresh server session."),(0,o.kt)("li",{parentName:"ol"},'Profiles can "resync" from a server at any time - resulting in a new call to download all messages. The most common usecase for this behaviour is to fetch older messages from a group.')),(0,o.kt)("p",null,"In combination, these 2 mitigations place bounds on what the server is able to infer however we still cannot provide full metadata-resistance."),(0,o.kt)("p",null,"For potential future solutions to this problem see ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/niwl"},"Niwl")),(0,o.kt)("h1",{id:"protecting-the-server-from-malicious-peers"},"Protecting the Server from Malicious Peers"),(0,o.kt)("p",null,"The main risk to servers come in the form of spam generated by peers. In the prototype of Cwtch a spamguard mechanism was put in place that required peers to conduct some arbitrary proof of work given a server-specified parameter."),(0,o.kt)("p",null,"This is not a robust solution in the presence of a determined adversary with a significant amount of resources, and thus one of the main external risks to the Cwtch system becomes censorship-via-resource exhaustion."),(0,o.kt)("p",null,"We have outlined a potential solution to this in ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/research/OPTR2019-01/"},"token based services")," but note that this also requires further development."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/0d64c1d9.427c695b.js b/build-staging/es/assets/js/0d64c1d9.427c695b.js new file mode 100644 index 00000000..721bb9c5 --- /dev/null +++ b/build-staging/es/assets/js/0d64c1d9.427c695b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8710],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>b});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):r(r({},t),e)),i},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(i),h=a,b=p["".concat(s,".").concat(h)]||p[h]||u[h]||o;return i?n.createElement(b,r(r({ref:t},d),{},{components:i})):n.createElement(b,r({ref:t},d))}));function b(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=i.length,r=new Array(o);r[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=i(7462),a=(i(7294),i(3905));const o={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/es/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"20 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/es/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"repliqate",permalink:"/es/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/es/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/es/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"How Cwtch Bindings are Built",id:"how-cwtch-bindings-are-built",level:2},{value:"Making libCwtch Reproducible",id:"making-libcwtch-reproducible",level:2},{value:"Linux Specific Considerations",id:"linux-specific-considerations",level:3},{value:"Windows Specific Considerations",id:"windows-specific-considerations",level:3},{value:"Android Specific Considerations",id:"android-specific-considerations",level:3},{value:"OSX Specific Considerations",id:"osx-specific-considerations",level:3},{value:"Introducing Repliqate!",id:"introducing-repliqate",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...o}=e;return(0,a.kt)(p,(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,a.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,a.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,a.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,a.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."),(0,a.kt)("h2",{id:"how-cwtch-bindings-are-built"},"How Cwtch Bindings are Built"),(0,a.kt)("p",null,"Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process."),(0,a.kt)("p",null,"When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms."),(0,a.kt)("p",null,"The Cwtch Bindings build pipeline results in four compiled libraries:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.so")," \u2013 For Linux Platforms, built using the ",(0,a.kt)("a",{parentName:"li",href:"https://hub.docker.com/_/golang"},"official golang:1.19.X Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.dll")," \u2013 For Windows Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/mingw-go"},"mingw-go Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.ld")," \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"cwtch.aar")," \u2013 For Android Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/android-go-mobile"},"Android/GoMobile Docker Image"))),(0,a.kt)("p",null,"These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI."),(0,a.kt)("h2",{id:"making-libcwtch-reproducible"},"Making libCwtch Reproducible"),(0,a.kt)("p",null,"Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Go Build ID"),": By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Build Paths and Go Environment Variables"),": By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimPath")," option, which we now specify for all bindings builds.")),(0,a.kt)("h3",{id:"linux-specific-considerations"},"Linux Specific Considerations"),(0,a.kt)("p",null,"After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against."),(0,a.kt)("p",null,"Our Drone/Docker build environments are based on ",(0,a.kt)("a",{parentName:"p",href:"https://www.debian.org/releases/bullseye/"},"Debian Bullseye")," which provides ",(0,a.kt)("a",{parentName:"p",href:"https://packages.debian.org/bullseye/i386/libc6-dev"},"libc6-dev version 2.31"),". Other development setups will likely link libc-dev 2.34+."),(0,a.kt)("p",null,"libc6-dev 2.34 is notable ",(0,a.kt)("a",{parentName:"p",href:"https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread"},"because it removed dependencies on libpthread and libdl")," \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file."),(0,a.kt)("p",null,"This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on ",(0,a.kt)("a",{parentName:"p",href:"#next-steps"},"Next Steps")," for more information)."),(0,a.kt)("h3",{id:"windows-specific-considerations"},"Windows Specific Considerations"),(0,a.kt)("p",null,"The headers of PE files technically contain a timestamp field. In recent years an ",(0,a.kt)("a",{parentName:"p",href:"https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705"},"effort has been made to use this field for other purposes"),", but by default ",(0,a.kt)("inlineCode",{parentName:"p"},"go build")," will still include the timestamp of the file when producing a DLL file (at least when using CGO)."),(0,a.kt)("p",null,"Fortunately this field can be zeroed out through passing ",(0,a.kt)("inlineCode",{parentName:"p"},"-Xlinker \u2013no-insert-timestamp")," into the ",(0,a.kt)("inlineCode",{parentName:"p"},"mingw32-gcc")," process."),(0,a.kt)("p",null,"With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment."),(0,a.kt)("h3",{id:"android-specific-considerations"},"Android Specific Considerations"),(0,a.kt)("p",null,"With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Cwtch makes use of ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/golang/mobile"},"GoMobile")," for compiling Android libraries. We pin to a specific version ",(0,a.kt)("inlineCode",{parentName:"li"},"43a0384520996c8376bfb8637390f12b44773e65")," in our Docker containers. Unlike ",(0,a.kt)("inlineCode",{parentName:"li"},"go build"),", the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimpPath")," parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized ",(0,a.kt)("inlineCode",{parentName:"li"},"/tmp/go-build*")," references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced."),(0,a.kt)("li",{parentName:"ul"},"We still use ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/releases/sdk-tools"},"sdk-tools")," instead of the new ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/command-line"},"commandline-tools"),". The latest version of sdk-tools is ",(0,a.kt)("inlineCode",{parentName:"li"},"4333796")," and available from: ",(0,a.kt)("a",{parentName:"li",href:"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"},"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"),". As part of our plans for Cwtch Stable we will be updating this dependency."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated ",(0,a.kt)("inlineCode",{parentName:"li"},"openjdk:8")," image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. ")),(0,a.kt)("p",null,"All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles."),(0,a.kt)("h3",{id:"osx-specific-considerations"},"OSX Specific Considerations"),(0,a.kt)("p",null,"Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds."),(0,a.kt)("p",null,"As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine."),(0,a.kt)("p",null,"In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1."),(0,a.kt)("p",null,"In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a ",(0,a.kt)("a",{parentName:"p",href:"https://www.apple.com/legal/sla/docs/xcode.pdf"},"proprietary SDK"),". There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware."),(0,a.kt)("p",null,"Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions."),(0,a.kt)("h2",{id:"introducing-repliqate"},"Introducing Repliqate!"),(0,a.kt)("p",null,"With all the above changes, ",(0,a.kt)("strong",{parentName:"p"},"Cwtch Bindings for Linux and Windows are fully reproducible!")),(0,a.kt)("p",null,"That alone is great, but we also want to make it easier for ",(0,a.kt)("strong",{parentName:"p"},"you")," to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team."),(0,a.kt)("p",null,"To make this process accessible we are releasing a new tool called ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate"),"."),(0,a.kt)("p",null,"Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution."),(0,a.kt)("p",null,"Repliqate runs ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script"},"build-scripts")," to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"builds.openprivacy.ca"),"."),(0,a.kt)("p",null,"We now provide ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"Repliqate build-scripts")," for reproducible both ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script"},"Linux libCwtch.so builds"),", ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script"},"Windows libCwtch.dll builds"),"!"),(0,a.kt)("p",null,"We also have a partially repeatable ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script"},"Android cwtch.aar build")," script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section."),(0,a.kt)("p",null,"You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings."),(0,a.kt)("p",null,"As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!"),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4515:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/0e00d73c.e93221bd.js b/build-staging/es/assets/js/0e00d73c.e93221bd.js new file mode 100644 index 00000000..8ec2dfc1 --- /dev/null +++ b/build-staging/es/assets/js/0e00d73c.e93221bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[836],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),s=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=s(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(t),d=o,m=u["".concat(l,".").concat(d)]||u[d]||f[d]||a;return t?n.createElement(m,i(i({ref:r},p),{},{components:t})):n.createElement(m,i({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=d;var c={};for(var l in r)hasOwnProperty.call(r,l)&&(c[l]=r[l]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var s=2;s{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:5},i="Desbloquear perfiles cifrados",c={unversionedId:"profiles/unlock-profile",id:"profiles/unlock-profile",title:"Desbloquear perfiles cifrados",description:"Cuando reinicies Cwtch, si usaste una contrase\xf1a para proteger tu perfil, no se cargar\xe1 por defecto y necesitar\xe1s desbloquearlo.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/unlock-profile.md",sourceDirName:"profiles",slug:"/profiles/unlock-profile",permalink:"/es/docs/profiles/unlock-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/unlock-profile.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Cambiar tu imagen de perfil",permalink:"/es/docs/profiles/change-profile-image"},next:{title:"Eliminar un perfil",permalink:"/es/docs/profiles/delete-profile"}},l={},s=[],p={toc:s},u="wrapper";function f(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"desbloquear-perfiles-cifrados"},"Desbloquear perfiles cifrados"),(0,o.kt)("p",null,"Cuando reinicies Cwtch, si usaste una ",(0,o.kt)("a",{parentName:"p",href:"/docs/profiles/change-password/"},"contrase\xf1a")," para proteger tu perfil, no se cargar\xe1 por defecto y necesitar\xe1s desbloquearlo."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Pulsa el icono de desbloqueo rosa ",(0,o.kt)("img",{src:"/img/lock_open-24px.webp",className:"ui-button",alt:"\xedcono de desbloqueo"})),(0,o.kt)("li",{parentName:"ol"},"Introduce tu contrase\xf1a"),(0,o.kt)("li",{parentName:"ol"},"Haz clic en \u201cdesbloquear tu perfil\u201d")),(0,o.kt)("p",null,"Ve tambi\xe9n: ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Manual de seguridad de Cwtch: Encriptaci\xf3n del perfil & Almacenamiento")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/0e5857d6.52a7d47f.js b/build-staging/es/assets/js/0e5857d6.52a7d47f.js new file mode 100644 index 00000000..180fb140 --- /dev/null +++ b/build-staging/es/assets/js/0e5857d6.52a7d47f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5889],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=c(r),m=i,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(f,o(o({ref:t},l),{},{components:r})):n.createElement(f,o({ref:t},l))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[d]="string"==typeof e?e:i,o[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const a={sidebar_position:4},o="Vista previa de im\xe1genes y fotos de perfil",s={unversionedId:"settings/experiments/image-previews-and-profile-pictures",id:"settings/experiments/image-previews-and-profile-pictures",title:"Vista previa de im\xe1genes y fotos de perfil",description:"This experiment requires the File Sharing experiment enabled.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/image-previews-and-profile-pictures.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/image-previews-and-profile-pictures",permalink:"/es/docs/settings/experiments/image-previews-and-profile-pictures",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/image-previews-and-profile-pictures.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Compartir Archivos",permalink:"/es/docs/settings/experiments/file-sharing"},next:{title:"Experimento de Enlaces Cliqueables",permalink:"/es/docs/settings/experiments/clickable-links"}},p={},c=[],l={toc:c},d="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"vista-previa-de-im\xe1genes-y-fotos-de-perfil"},"Vista previa de im\xe1genes y fotos de perfil"),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"This experiment requires the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"File Sharing")," experiment enabled.")),(0,i.kt)("p",null,"When enabled, Cwtch will download image files automatically, display image previews in the conversation window, and enable the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profile Pictures")," feature;"),(0,i.kt)("p",null,"On Desktop, enabling this experiment will allow access to an additional setting ",(0,i.kt)("inlineCode",{parentName:"p"},'"'),"Download Folder` which can be changed to tell Cwtch where to (automatically) download pictures."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/114c7a7e.6593dfd5.js b/build-staging/es/assets/js/114c7a7e.6593dfd5.js new file mode 100644 index 00000000..055016e7 --- /dev/null +++ b/build-staging/es/assets/js/114c7a7e.6593dfd5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2524],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),d=a,f=u["".concat(c,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:4},i="Modo de streaming/presentaci\xf3n",s={unversionedId:"settings/appearance/streamer-mode",id:"settings/appearance/streamer-mode",title:"Modo de streaming/presentaci\xf3n",description:"El modo de streaming / presentaci\xf3n hace la aplicaci\xf3n m\xe1s visualmente privada. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/streamer-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/streamer-mode",permalink:"/es/docs/settings/appearance/streamer-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/streamer-mode.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Columnas de interfaz",permalink:"/es/docs/settings/appearance/ui-columns"},next:{title:"Behaviour",permalink:"/es/docs/category/behaviour"}},c={},p=[],l={toc:p},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"modo-de-streamingpresentaci\xf3n"},"Modo de streaming/presentaci\xf3n"),(0,a.kt)("p",null,"El modo de streaming / presentaci\xf3n hace la aplicaci\xf3n m\xe1s visualmente privada. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens."),(0,a.kt)("p",null,"Esto es \xfatil cuando se toman capturas de pantalla o cuando se muestra Cwtch de una manera m\xe1s p\xfablica."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pulsa el icono de configuraci\xf3n"),(0,a.kt)("li",{parentName:"ol"},'Activar "Modo Streamer"'),(0,a.kt)("li",{parentName:"ol"},"Comprueba que funciona mirando tu perfil o tu lista de contactos")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/141cdfa9.3e834abc.js b/build-staging/es/assets/js/141cdfa9.3e834abc.js new file mode 100644 index 00000000..97f55329 --- /dev/null +++ b/build-staging/es/assets/js/141cdfa9.3e834abc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7293],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(a),m=n,h=u["".concat(c,".").concat(m)]||u[m]||f[m]||i;return a?r.createElement(h,o(o({ref:t},p),{},{components:a})):r.createElement(h,o({ref:t},p))}));function h(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=a.length,o=new Array(i);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const i={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"6 de abril de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/es/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/es/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/es/blog/cwtch-stable-roadmap-update"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},u="wrapper";function f(e){let{components:t,...a}=e;return(0,n.kt)(u,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,n.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,n.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,n.kt)("p",null,"The Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/14eb3368.5ac78d9e.js b/build-staging/es/assets/js/14eb3368.5ac78d9e.js new file mode 100644 index 00000000..b466bfa7 --- /dev/null +++ b/build-staging/es/assets/js/14eb3368.5ac78d9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9817],{1310:(e,t,a)=>{a.d(t,{Z:()=>E});var n=a(7462),r=a(7294),i=a(6010),l=a(5281),s=a(2802),c=a(8596),o=a(9960),m=a(5999),d=a(4996);function u(e){return r.createElement("svg",(0,n.Z)({viewBox:"0 0 24 24"},e),r.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const h={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,d.Z)("/");return r.createElement("li",{className:"breadcrumbs__item"},r.createElement(o.Z,{"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},r.createElement(u,{className:h.breadcrumbHomeIcon})))}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g(e){let{children:t,href:a,isLast:n}=e;const i="breadcrumbs__link";return n?r.createElement("span",{className:i,itemProp:"name"},t):a?r.createElement(o.Z,{className:i,href:a,itemProp:"item"},r.createElement("span",{itemProp:"name"},t)):r.createElement("span",{className:i},t)}function p(e){let{children:t,active:a,index:l,addMicrodata:s}=e;return r.createElement("li",(0,n.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,i.Z)("breadcrumbs__item",{"breadcrumbs__item--active":a})}),t,r.createElement("meta",{itemProp:"position",content:String(l+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?r.createElement("nav",{className:(0,i.Z)(l.k.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},r.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&r.createElement(b,null),e.map(((t,a)=>{const n=a===e.length-1;return r.createElement(p,{key:a,active:n,index:a,addMicrodata:!!t.href},r.createElement(g,{href:t.href,isLast:n},t.label))})))):null}},4228:(e,t,a)=>{a.r(t),a.d(t,{default:()=>y});var n=a(7294),r=a(1944),i=a(2802),l=a(4996),s=a(6010),c=a(9960),o=a(3919),m=a(5999);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:a}=e;return n.createElement(c.Z,{href:t,className:(0,s.Z)("card padding--lg",d.cardContainer)},a)}function h(e){let{href:t,icon:a,title:r,description:i}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,s.Z)("text--truncate",d.cardTitle),title:r},a," ",r),i&&n.createElement("p",{className:(0,s.Z)("text--truncate",d.cardDescription),title:i},i))}function b(e){let{item:t}=e;const a=(0,i.Wl)(t);return a?n.createElement(h,{href:a,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,m.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const a=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return n.createElement(h,{href:t.href,icon:a,title:t.label,description:t.description??r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(v,{item:t});case"category":return n.createElement(b,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function p(e){let{className:t}=e;const a=(0,i.jA)();return n.createElement(E,{items:a.items,className:t})}function E(e){const{items:t,className:a}=e;if(!t)return n.createElement(p,e);const r=(0,i.MN)(t);return n.createElement("section",{className:(0,s.Z)("row",a)},r.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}var f=a(49),N=a(3120),Z=a(4364),k=a(1310),_=a(2503);const L={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function T(e){let{categoryGeneratedIndex:t}=e;return n.createElement(r.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,l.Z)(t.image)})}function x(e){let{categoryGeneratedIndex:t}=e;const a=(0,i.jA)();return n.createElement("div",{className:L.generatedIndexPage},n.createElement(N.Z,null),n.createElement(k.Z,null),n.createElement(Z.Z,null),n.createElement("header",null,n.createElement(_.Z,{as:"h1",className:L.title},t.title),t.description&&n.createElement("p",null,t.description)),n.createElement("article",{className:"margin-top--lg"},n.createElement(E,{items:a.items,className:L.list})),n.createElement("footer",{className:"margin-top--lg"},n.createElement(f.Z,{previous:t.navigation.previous,next:t.navigation.next})))}function y(e){return n.createElement(n.Fragment,null,n.createElement(T,e),n.createElement(x,e))}},49:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7462),r=a(7294),i=a(5999),l=a(2244);function s(e){const{previous:t,next:a}=e;return r.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,i.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&r.createElement(l.Z,(0,n.Z)({},t,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),a&&r.createElement(l.Z,(0,n.Z)({},a,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,a)=>{a.d(t,{Z:()=>c});var n=a(7294),r=a(6010),i=a(5999),l=a(5281),s=a(4477);function c(e){let{className:t}=e;const a=(0,s.E)();return a.badge?n.createElement("span",{className:(0,r.Z)(t,l.k.docs.docVersionBadge,"badge badge--secondary")},n.createElement(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:a.label}},"Version: {versionLabel}")):null}},3120:(e,t,a)=>{a.d(t,{Z:()=>g});var n=a(7294),r=a(6010),i=a(2263),l=a(9960),s=a(5999),c=a(143),o=a(5281),m=a(373),d=a(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function h(e){const t=u[e.versionMetadata.banner];return n.createElement(t,e)}function b(e){let{versionLabel:t,to:a,onClick:r}=e;return n.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:n.createElement("b",null,n.createElement(l.Z,{to:a,onClick:r},n.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function v(e){let{className:t,versionMetadata:a}=e;const{siteConfig:{title:l}}=(0,i.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,m.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:v}=(0,c.Jo)(s),g=u??(p=v).docs.find((e=>e.id===p.mainDocId));var p;return n.createElement("div",{className:(0,r.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},n.createElement("div",null,n.createElement(h,{siteTitle:l,versionMetadata:a})),n.createElement("div",{className:"margin-top--md"},n.createElement(b,{versionLabel:v.label,to:g.path,onClick:()=>d(v.name)})))}function g(e){let{className:t}=e;const a=(0,d.E)();return a.banner?n.createElement(v,{className:t,versionMetadata:a}):null}},2503:(e,t,a)=>{a.d(t,{Z:()=>m});var n=a(7462),r=a(7294),i=a(6010),l=a(5999),s=a(6668),c=a(9960);const o={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function m(e){let{as:t,id:a,...m}=e;const{navbar:{hideOnScroll:d}}=(0,s.L)();if("h1"===t||!a)return r.createElement(t,(0,n.Z)({},m,{id:void 0}));const u=(0,l.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof m.children?m.children:a});return r.createElement(t,(0,n.Z)({},m,{className:(0,i.Z)("anchor",d?o.anchorWithHideOnScrollNavbar:o.anchorWithStickyNavbar,m.className),id:a}),m.children,r.createElement(c.Z,{className:"hash-link",to:`#${a}`,"aria-label":u,title:u},"\u200b"))}},2244:(e,t,a)=>{a.d(t,{Z:()=>l});var n=a(7294),r=a(6010),i=a(9960);function l(e){const{permalink:t,title:a,subLabel:l,isNext:s}=e;return n.createElement(i.Z,{className:(0,r.Z)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},l&&n.createElement("div",{className:"pagination-nav__sublabel"},l),n.createElement("div",{className:"pagination-nav__label"},a))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/15cce247.5aeb757f.js b/build-staging/es/assets/js/15cce247.5aeb757f.js new file mode 100644 index 00000000..cfe31446 --- /dev/null +++ b/build-staging/es/assets/js/15cce247.5aeb757f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4318],{188:e=>{e.exports=JSON.parse('{"title":"Groups","slug":"/category/groups","permalink":"/es/docs/category/groups","navigation":{"previous":{"title":"Removing a Conversation","permalink":"/es/docs/chat/delete-contact"},"next":{"title":"Una Introducci\xf3n a los Grupos de Cwtch","permalink":"/es/docs/groups/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/17896441.27340309.js b/build-staging/es/assets/js/17896441.27340309.js new file mode 100644 index 00000000..d1e2980a --- /dev/null +++ b/build-staging/es/assets/js/17896441.27340309.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7918],{1310:(e,t,n)=>{n.d(t,{Z:()=>E});var a=n(7462),l=n(7294),o=n(6010),r=n(5281),s=n(2802),c=n(8596),i=n(9960),d=n(5999),m=n(4996);function u(e){return l.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},e),l.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const v={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,m.Z)("/");return l.createElement("li",{className:"breadcrumbs__item"},l.createElement(i.Z,{"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},l.createElement(u,{className:v.breadcrumbHomeIcon})))}const p={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function h(e){let{children:t,href:n,isLast:a}=e;const o="breadcrumbs__link";return a?l.createElement("span",{className:o,itemProp:"name"},t):n?l.createElement(i.Z,{className:o,href:n,itemProp:"item"},l.createElement("span",{itemProp:"name"},t)):l.createElement("span",{className:o},t)}function f(e){let{children:t,active:n,index:r,addMicrodata:s}=e;return l.createElement("li",(0,a.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,o.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n})}),t,l.createElement("meta",{itemProp:"position",content:String(r+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?l.createElement("nav",{className:(0,o.Z)(r.k.docs.docBreadcrumbs,p.breadcrumbsContainer),"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},l.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&l.createElement(b,null),e.map(((t,n)=>{const a=n===e.length-1;return l.createElement(f,{key:n,active:a,index:n,addMicrodata:!!t.href},l.createElement(h,{href:t.href,isLast:a},t.label))})))):null}},5154:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});var a=n(7294),l=n(1944),o=n(902);const r=a.createContext(null);function s(e){let{children:t,content:n}=e;const l=function(e){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return a.createElement(r.Provider,{value:l},t)}function c(){const e=(0,a.useContext)(r);if(null===e)throw new o.i6("DocProvider");return e}function i(){const{metadata:e,frontMatter:t,assets:n}=c();return a.createElement(l.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var d=n(6010),m=n(7524),u=n(49);function v(){const{metadata:e}=c();return a.createElement(u.Z,{previous:e.previous,next:e.next})}var b=n(3120),p=n(4364),h=n(5281),f=n(5999);function E(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:a.createElement("b",null,a.createElement("time",{dateTime:new Date(1e3*t).toISOString()},n))}}," on {date}")}function g(e){let{lastUpdatedBy:t}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:a.createElement("b",null,t)}}," by {user}")}function L(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:l}=e;return a.createElement("span",{className:h.k.common.lastUpdated},a.createElement(f.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?a.createElement(E,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:l?a.createElement(g,{lastUpdatedBy:l}):""}},"Last updated{atDate}{byUser}"),!1)}var C=n(4881),N=n(1526);const Z={lastUpdated:"lastUpdated_vwxv"};function k(e){return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterTagsRow,"row margin-bottom--sm")},a.createElement("div",{className:"col"},a.createElement(N.Z,e)))}function _(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:l,formattedLastUpdatedAt:o}=e;return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterEditMetaRow,"row")},a.createElement("div",{className:"col"},t&&a.createElement(C.Z,{editUrl:t})),a.createElement("div",{className:(0,d.Z)("col",Z.lastUpdated)},(n||l)&&a.createElement(L,{lastUpdatedAt:n,formattedLastUpdatedAt:o,lastUpdatedBy:l})))}function x(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:l,lastUpdatedBy:o,tags:r}=e,s=r.length>0,i=!!(t||n||o);return s||i?a.createElement("footer",{className:(0,d.Z)(h.k.docs.docFooter,"docusaurus-mt-lg")},s&&a.createElement(k,{tags:r}),i&&a.createElement(_,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:o,formattedLastUpdatedAt:l})):null}var T=n(6043),H=n(3743),U=n(7462);const y={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function A(e){let{collapsed:t,...n}=e;return a.createElement("button",(0,U.Z)({type:"button"},n,{className:(0,d.Z)("clean-btn",y.tocCollapsibleButton,!t&&y.tocCollapsibleButtonExpanded,n.className)}),a.createElement(f.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component"},"On this page"))}const w={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function M(e){let{toc:t,className:n,minHeadingLevel:l,maxHeadingLevel:o}=e;const{collapsed:r,toggleCollapsed:s}=(0,T.u)({initialState:!0});return a.createElement("div",{className:(0,d.Z)(w.tocCollapsible,!r&&w.tocCollapsibleExpanded,n)},a.createElement(A,{collapsed:r,onClick:s}),a.createElement(T.z,{lazy:!0,className:w.tocCollapsibleContent,collapsed:r},a.createElement(H.Z,{toc:t,minHeadingLevel:l,maxHeadingLevel:o})))}const I={tocMobile:"tocMobile_ITEo"};function B(){const{toc:e,frontMatter:t}=c();return a.createElement(M,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,d.Z)(h.k.docs.docTocMobile,I.tocMobile)})}var O=n(9407);function S(){const{toc:e,frontMatter:t}=c();return a.createElement(O.Z,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:h.k.docs.docTocDesktop})}var V=n(2503),P=n(1506);function D(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return a.createElement("div",{className:(0,d.Z)(h.k.docs.docMarkdown,"markdown")},n&&a.createElement("header",null,a.createElement(V.Z,{as:"h1"},n)),a.createElement(P.Z,null,t))}var R=n(1310);const F={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function z(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),l=e.hide_table_of_contents,o=!l&&t.length>0;return{hidden:l,mobile:o?a.createElement(B,null):void 0,desktop:!o||"desktop"!==n&&"ssr"!==n?void 0:a.createElement(S,null)}}();return a.createElement("div",{className:"row"},a.createElement("div",{className:(0,d.Z)("col",!n.hidden&&F.docItemCol)},a.createElement(b.Z,null),a.createElement("div",{className:F.docItemContainer},a.createElement("article",null,a.createElement(R.Z,null),a.createElement(p.Z,null),n.mobile,a.createElement(D,null,t),a.createElement(x,null)),a.createElement(v,null))),n.desktop&&a.createElement("div",{className:"col col--3"},n.desktop))}function j(e){const t=`docs-doc-id-${e.content.metadata.unversionedId}`,n=e.content;return a.createElement(s,{content:e.content},a.createElement(l.FG,{className:t},a.createElement(i,null),a.createElement(z,null,a.createElement(n,null))))}},49:(e,t,n)=>{n.d(t,{Z:()=>s});var a=n(7462),l=n(7294),o=n(5999),r=n(2244);function s(e){const{previous:t,next:n}=e;return l.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,o.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&l.createElement(r.Z,(0,a.Z)({},t,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),n&&l.createElement(r.Z,(0,a.Z)({},n,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,n)=>{n.d(t,{Z:()=>c});var a=n(7294),l=n(6010),o=n(5999),r=n(5281),s=n(4477);function c(e){let{className:t}=e;const n=(0,s.E)();return n.badge?a.createElement("span",{className:(0,l.Z)(t,r.k.docs.docVersionBadge,"badge badge--secondary")},a.createElement(o.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label}},"Version: {versionLabel}")):null}},3120:(e,t,n)=>{n.d(t,{Z:()=>h});var a=n(7294),l=n(6010),o=n(2263),r=n(9960),s=n(5999),c=n(143),i=n(5281),d=n(373),m=n(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function v(e){const t=u[e.versionMetadata.banner];return a.createElement(t,e)}function b(e){let{versionLabel:t,to:n,onClick:l}=e;return a.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:a.createElement("b",null,a.createElement(r.Z,{to:n,onClick:l},a.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function p(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:r}}=(0,o.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:m}=(0,d.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:p}=(0,c.Jo)(s),h=u??(f=p).docs.find((e=>e.id===f.mainDocId));var f;return a.createElement("div",{className:(0,l.Z)(t,i.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},a.createElement("div",null,a.createElement(v,{siteTitle:r,versionMetadata:n})),a.createElement("div",{className:"margin-top--md"},a.createElement(b,{versionLabel:p.label,to:h.path,onClick:()=>m(p.name)})))}function h(e){let{className:t}=e;const n=(0,m.E)();return n.banner?a.createElement(p,{className:t,versionMetadata:n}):null}},9407:(e,t,n)=>{n.d(t,{Z:()=>d});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",i="table-of-contents__link--active";function d(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(s.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:i})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>b});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function s(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=s({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function m(e){const t=(0,l.useRef)(void 0),n=d();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=i(s,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===d)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const v=l.memo(u);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:d,maxHeadingLevel:u,...b}=e;const p=(0,o.L)(),h=d??p.tableOfContents.minHeadingLevel,f=u??p.tableOfContents.maxHeadingLevel,E=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>s({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:h,maxHeadingLevel:f});return m((0,l.useMemo)((()=>{if(c&&i)return{linkClassName:c,linkActiveClassName:i,minHeadingLevel:h,maxHeadingLevel:f}}),[c,i,h,f])),l.createElement(v,(0,a.Z)({toc:E,className:n,linkClassName:c},b))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1a25c548.54459e7f.js b/build-staging/es/assets/js/1a25c548.54459e7f.js new file mode 100644 index 00000000..246b37ec --- /dev/null +++ b/build-staging/es/assets/js/1a25c548.54459e7f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5732],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=r,u=h["".concat(c,".").concat(m)]||h[m]||g[m]||o;return a?n.createElement(u,i(i({ref:t},p),{},{components:a})):n.createElement(u,i({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const o={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"6 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/es/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,r.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,r.kt)("strong",{parentName:"p"},"Beta")," to ",(0,r.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,r.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}g.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1af3d897.05f2d997.js b/build-staging/es/assets/js/1af3d897.05f2d997.js new file mode 100644 index 00000000..5511a440 --- /dev/null +++ b/build-staging/es/assets/js/1af3d897.05f2d997.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1443],{400:s=>{s.exports=JSON.parse('{"label":"testing","permalink":"/es/blog/tags/testing","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1be78505.c2da882e.js b/build-staging/es/assets/js/1be78505.c2da882e.js new file mode 100644 index 00000000..fb0a6ec0 --- /dev/null +++ b/build-staging/es/assets/js/1be78505.c2da882e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9514,4972],{9963:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ge});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),c=n(3320),i=n(2802),s=n(4477),d=n(1116),m=n(7961),u=n(5999),b=n(2466),p=n(5936);const h={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};function E(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,l]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:r,cancelScroll:c}=(0,b.Ct)();return(0,b.RF)(((e,n)=>{let{scrollY:a}=e;const r=n?.scrollY;r&&(o.current?o.current=!1:a>=r?(c(),l(!1)):a{e.location.hash&&(o.current=!0,l(!1))})),{shown:n,scrollToTop:()=>r(0)}}({threshold:300});return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,l.Z)("clean-btn",r.k.common.backToTopButton,h.backToTopButton,e&&h.backToTopButtonShow),type:"button",onClick:t})}var f=n(1442),g=n(6550),k=n(7524),_=n(6668),v=n(1327),C=n(7462);function S(e){return a.createElement("svg",(0,C.Z)({width:"20",height:"20","aria-hidden":"true"},e),a.createElement("g",{fill:"#7a7a7a"},a.createElement("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),a.createElement("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})))}const I={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function N(e){let{onClick:t}=e;return a.createElement("button",{type:"button",title:(0,u.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,l.Z)("button button--secondary button--outline",I.collapseSidebarButton),onClick:t},a.createElement(S,{className:I.collapseSidebarButtonIcon}))}var T=n(9689),Z=n(902);const x=Symbol("EmptyContext"),B=a.createContext(x);function y(e){let{children:t}=e;const[n,l]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:l})),[n]);return a.createElement(B.Provider,{value:o},t)}var w=n(6043),L=n(8596),A=n(9960),M=n(2389);function F(e){let{categoryLabel:t,onClick:n}=e;return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel",message:"Toggle the collapsible sidebar category '{label}'",description:"The ARIA label to toggle the collapsible sidebar category"},{label:t}),type:"button",className:"clean-btn menu__caret",onClick:n})}function H(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{items:m,label:u,collapsible:b,className:p,href:h}=t,{docs:{sidebar:{autoCollapseCategories:E}}}=(0,_.L)(),f=function(e){const t=(0,M.Z)();return(0,a.useMemo)((()=>e.href?e.href:!t&&e.collapsible?(0,i.Wl)(e):void 0),[e,t])}(t),g=(0,i._F)(t,o),k=(0,L.Mg)(h,o),{collapsed:v,setCollapsed:S}=(0,w.u)({initialState:()=>!!b&&(!g&&t.collapsed)}),{expandedItem:I,setExpandedItem:N}=function(){const e=(0,a.useContext)(B);if(e===x)throw new Z.i6("DocSidebarItemsExpandedStateProvider");return e}(),T=function(e){void 0===e&&(e=!v),N(e?null:s),S(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:l}=e;const o=(0,Z.D9)(t);(0,a.useEffect)((()=>{t&&!o&&n&&l(!1)}),[t,o,n,l])}({isActive:g,collapsed:v,updateCollapsed:T}),(0,a.useEffect)((()=>{b&&null!=I&&I!==s&&E&&S(!0)}),[b,I,s,S,E]),a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemCategory,r.k.docs.docSidebarItemCategoryLevel(c),"menu__list-item",{"menu__list-item--collapsed":v},p)},a.createElement("div",{className:(0,l.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":k})},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!h&&b,"menu__link--active":g}),onClick:b?e=>{n?.(t),h?T(!1):(e.preventDefault(),T())}:()=>{n?.(t)},"aria-current":k?"page":void 0,"aria-expanded":b?!v:void 0,href:b?f??"#":f},d),u),h&&b&&a.createElement(F,{categoryLabel:u,onClick:e=>{e.preventDefault(),T()}})),a.createElement(w.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:v},a.createElement(j,{items:m,tabIndex:v?-1:0,onItemClick:n,activePath:o,level:c+1})))}var P=n(3919),W=n(9471);const D={menuExternalLink:"menuExternalLink_NmtK"};function R(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{href:m,label:u,className:b,autoAddBaseUrl:p}=t,h=(0,i._F)(t,o),E=(0,P.Z)(m);return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(c),"menu__list-item",b),key:u},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",!E&&D.menuExternalLink,{"menu__link--active":h}),autoAddBaseUrl:p,"aria-current":h?"page":void 0,to:m},E&&{onClick:n?()=>n(t):void 0},d),u,!E&&a.createElement(W.Z,null)))}const V={menuHtmlItem:"menuHtmlItem_M9Kj"};function z(e){let{item:t,level:n,index:o}=e;const{value:c,defaultStyle:i,className:s}=t;return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(n),i&&[V.menuHtmlItem,"menu__list-item"],s),key:o,dangerouslySetInnerHTML:{__html:c}})}function U(e){let{item:t,...n}=e;switch(t.type){case"category":return a.createElement(H,(0,C.Z)({item:t},n));case"html":return a.createElement(z,(0,C.Z)({item:t},n));default:return a.createElement(R,(0,C.Z)({item:t},n))}}function K(e){let{items:t,...n}=e;return a.createElement(y,null,t.map(((e,t)=>a.createElement(U,(0,C.Z)({key:t,item:e,index:t},n)))))}const j=(0,a.memo)(K),G={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:o}=e;const c=function(){const{isActive:e}=(0,T.nT)(),[t,n]=(0,a.useState)(e);return(0,b.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return a.createElement("nav",{"aria-label":(0,u.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,l.Z)("menu thin-scrollbar",G.menu,c&&G.menuWithAnnouncementBar,o)},a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:n,activePath:t,level:1})))}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",X="sidebarHidden_VK0M",J="sidebarLogo_isFc";function Q(e){let{path:t,sidebar:n,onCollapse:o,isHidden:r}=e;const{navbar:{hideOnScroll:c},docs:{sidebar:{hideable:i}}}=(0,_.L)();return a.createElement("div",{className:(0,l.Z)(q,c&&O,r&&X)},c&&a.createElement(v.Z,{tabIndex:-1,className:J}),a.createElement(Y,{path:t,sidebar:n}),i&&a.createElement(N,{onClick:o}))}const $=a.memo(Q);var ee=n(3102),te=n(2961);const ne=e=>{let{sidebar:t,path:n}=e;const o=(0,te.e)();return a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&o.toggle(),"link"===e.type&&o.toggle()},level:1}))};function ae(e){return a.createElement(ee.Zo,{component:ne,props:e})}const le=a.memo(ae);function oe(e){const t=(0,k.i)(),n="desktop"===t||"ssr"===t,l="mobile"===t;return a.createElement(a.Fragment,null,n&&a.createElement($,e),l&&a.createElement(le,e))}const re={expandButton:"expandButton_m80_",expandButtonIcon:"expandButtonIcon_BlDH"};function ce(e){let{toggleSidebar:t}=e;return a.createElement("div",{className:re.expandButton,title:(0,u.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t},a.createElement(S,{className:re.expandButtonIcon}))}const ie={docSidebarContainer:"docSidebarContainer_b6E3",docSidebarContainerHidden:"docSidebarContainerHidden_b3ry",sidebarViewport:"sidebarViewport_Xe31"};function se(e){let{children:t}=e;const n=(0,d.V)();return a.createElement(a.Fragment,{key:n?.name??"noSidebar"},t)}function de(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}=e;const{pathname:c}=(0,g.TH)(),[i,s]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{i&&s(!1),!i&&(0,f.n)()&&s(!0),o((e=>!e))}),[o,i]);return a.createElement("aside",{className:(0,l.Z)(r.k.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&s(!0)}},a.createElement(se,null,a.createElement("div",{className:(0,l.Z)(ie.sidebarViewport,i&&ie.sidebarViewportHidden)},a.createElement(oe,{sidebar:t,path:c,onCollapse:d,isHidden:i}),i&&a.createElement(ce,{toggleSidebar:d}))))}const me={docMainContainer:"docMainContainer_gTbr",docMainContainerEnhanced:"docMainContainerEnhanced_Uz_u",docItemWrapperEnhanced:"docItemWrapperEnhanced_czyv"};function ue(e){let{hiddenSidebarContainer:t,children:n}=e;const o=(0,d.V)();return a.createElement("main",{className:(0,l.Z)(me.docMainContainer,(t||!o)&&me.docMainContainerEnhanced)},a.createElement("div",{className:(0,l.Z)("container padding-top--md padding-bottom--lg",me.docItemWrapper,t&&me.docItemWrapperEnhanced)},n))}const be={docPage:"docPage__5DB",docsWrapper:"docsWrapper_BCFX"};function pe(e){let{children:t}=e;const n=(0,d.V)(),[l,o]=(0,a.useState)(!1);return a.createElement(m.Z,{wrapperClassName:be.docsWrapper},a.createElement(E,null),a.createElement("div",{className:be.docPage},n&&a.createElement(de,{sidebar:n.items,hiddenSidebarContainer:l,setHiddenSidebarContainer:o}),a.createElement(ue,{hiddenSidebarContainer:l},t)))}var he=n(4972),Ee=n(197);function fe(e){const{versionMetadata:t}=e;return a.createElement(a.Fragment,null,a.createElement(Ee.Z,{version:t.version,tag:(0,c.os)(t.pluginId,t.version)}),a.createElement(o.d,null,t.noIndex&&a.createElement("meta",{name:"robots",content:"noindex, nofollow"})))}function ge(e){const{versionMetadata:t}=e,n=(0,i.hI)(e);if(!n)return a.createElement(he.default,null);const{docElement:c,sidebarName:m,sidebarItems:u}=n;return a.createElement(a.Fragment,null,a.createElement(fe,e),a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.docsPages,r.k.page.docsDocPage,e.versionMetadata.className)},a.createElement(s.q,{version:t},a.createElement(d.b,{name:m,items:u},a.createElement(pe,null,c)))))}},4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});var a=n(7294),l=n(5999),o=n(1944),r=n(7961);function c(){return a.createElement(a.Fragment,null,a.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1c2b746e.ad6be4f5.js b/build-staging/es/assets/js/1c2b746e.ad6be4f5.js new file mode 100644 index 00000000..58faf6f3 --- /dev/null +++ b/build-staging/es/assets/js/1c2b746e.ad6be4f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1539],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>p});var r=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;e=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var M=r.createContext({}),u=function(t){var e=r.useContext(M),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},s=function(t){var e=u(t.components);return r.createElement(M.Provider,{value:e},t.children)},L="mdxType",w={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},l=r.forwardRef((function(t,e){var n=t.components,i=t.mdxType,o=t.originalType,M=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),L=u(n),l=i,p=L["".concat(M,".").concat(l)]||L[l]||w[l]||o;return n?r.createElement(p,a(a({ref:e},s),{},{components:n})):r.createElement(p,a({ref:e},s))}));function p(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var o=n.length,a=new Array(o);a[0]=l;var c={};for(var M in e)hasOwnProperty.call(e,M)&&(c[M]=e[M]);c.originalType=t,c[L]="string"==typeof t?t:i,a[1]=c;for(var u=2;u{n.r(e),n.d(e,{assets:()=>M,contentTitle:()=>a,default:()=>w,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:10},a="Removing a Conversation",c={unversionedId:"chat/delete-contact",id:"chat/delete-contact",title:"Removing a Conversation",description:"This feature will result in irreversible deletion. This cannot be undone.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/delete-contact.md",sourceDirName:"chat",slug:"/chat/delete-contact",permalink:"/es/docs/chat/delete-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/delete-contact.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Desbloquear un contacto",permalink:"/es/docs/chat/unblock-contact"},next:{title:"Groups",permalink:"/es/docs/category/groups"}},M={},u=[],s={toc:u},L="wrapper";function w(t){let{components:e,...o}=t;return(0,i.kt)(L,(0,r.Z)({},s,o,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"removing-a-conversation"},"Removing a Conversation"),(0,i.kt)("admonition",{type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,i.kt)("strong",{parentName:"p"},"irreversible")," deletion. This ",(0,i.kt)("strong",{parentName:"p"},"cannot be undone"),".")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"In a chat with a contact, go to the conversation settings on the top right ",(0,i.kt)("span",{class:"icon"},(0,i.kt)("img",{src:n(5905).Z,width:"24",height:"24"}))),(0,i.kt)("li",{parentName:"ul"},"Scroll to the ",(0,i.kt)("strong",{parentName:"li"},"leave this conversation")," button, and press it."),(0,i.kt)("li",{parentName:"ul"},"You will be prompted to confirm if you want to leave the conversation. This action cannot be undone.")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}w.isMDXComponent=!0},5905:(t,e,n)=>{n.d(e,{Z:()=>r});const r="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyNS4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjQgMjQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJLnN0MHtmaWxsOm5vbmU7fQ0KPC9zdHlsZT4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0wLDBoMjR2MjRIMFYweiIvPg0KPGc+DQoJPHBhdGggZD0iTTEzLjYsMTMuOGMtMS0wLjItMi0wLjMtMi44LTAuM2MtMi43LDAtOCwxLjMtOCw0djJoOS44Yy0wLjMtMC42LTAuNC0xLjMtMC40LTIuMUMxMi4yLDE1LjksMTIuNywxNC43LDEzLjYsMTMuOHoiLz4NCgk8Y2lyY2xlIGN4PSIxMC44IiBjeT0iNy40IiByPSI0Ii8+DQo8L2c+DQo8cGF0aCBkPSJNMjEuMSwxNy45YzAtMC4xLDAtMC4zLDAtMC40YzAtMC4yLDAtMC4zLDAtMC40bDEtMC43YzAuMS0wLjEsMC4xLTAuMiwwLjEtMC4zbC0wLjktMS42Yy0wLjEtMC4xLTAuMi0wLjEtMC4zLTAuMWwtMS4xLDAuNQ0KCWMtMC4yLTAuMi0wLjUtMC4zLTAuOC0wLjRsLTAuMi0xLjJjMC0wLjEtMC4xLTAuMi0wLjItMC4yaC0xLjhjLTAuMSwwLTAuMiwwLjEtMC4yLDAuMmwtMC4yLDEuMmMtMC4zLDAuMS0wLjUsMC4zLTAuOCwwLjRsLTEuMS0wLjUNCgljLTAuMSwwLTAuMiwwLTAuMywwLjFMMTMuNCwxNmMtMC4xLDAuMSwwLDAuMiwwLjEsMC4zbDEsMC43YzAsMC4xLDAsMC4zLDAsMC40YzAsMC4xLDAsMC4zLDAsMC40bC0xLDAuN2MtMC4xLDAuMS0wLjEsMC4yLTAuMSwwLjMNCglsMC45LDEuNmMwLjEsMC4xLDAuMiwwLjEsMC4zLDAuMWwxLjEtMC41YzAuMiwwLjIsMC41LDAuMywwLjgsMC40bDAuMiwxLjJjMCwwLjEsMC4xLDAuMiwwLjIsMC4yaDEuOGMwLjEsMCwwLjItMC4xLDAuMi0wLjINCglsMC4yLTEuMmMwLjMtMC4xLDAuNS0wLjMsMC44LTAuNGwxLjEsMC41YzAuMSwwLDAuMiwwLDAuMy0wLjFsMC45LTEuNmMwLjEtMC4xLDAtMC4yLTAuMS0wLjNMMjEuMSwxNy45eiBNMTcuNywxOS4yDQoJYy0wLjksMC0xLjctMC44LTEuNy0xLjdjMC0wLjksMC44LTEuNywxLjctMS43YzAuOSwwLDEuNywwLjgsMS43LDEuN0MxOS40LDE4LjQsMTguNywxOS4yLDE3LjcsMTkuMnoiLz4NCjwvc3ZnPg0K"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1c48b4d1.b4858c3a.js b/build-staging/es/assets/js/1c48b4d1.b4858c3a.js new file mode 100644 index 00000000..323afae6 --- /dev/null +++ b/build-staging/es/assets/js/1c48b4d1.b4858c3a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8664],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=c(r),d=o,m=p["".concat(l,".").concat(d)]||p[d]||h[d]||i;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Developing Cwtch",a={unversionedId:"contribute/developing",id:"contribute/developing",title:"Developing Cwtch",description:"This section documents some ways to get started with Cwtch Development.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/developing.md",sourceDirName:"contribute",slug:"/contribute/developing",permalink:"/es/docs/contribute/developing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/developing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Contribute",permalink:"/es/docs/category/contribute"},next:{title:"Pruebas de Cwtch",permalink:"/es/docs/contribute/testing"}},l={},c=[{value:"Cwtch Issues Tracking Process",id:"cwtch-issues-tracking-process",level:2},{value:"Cwtch Pull-Request Process",id:"cwtch-pull-request-process",level:2},{value:"Build Bot",id:"build-bot",level:3},{value:"Useful Resources",id:"useful-resources",level:2}],u={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"developing-cwtch"},"Developing Cwtch"),(0,o.kt)("p",null,"This section documents some ways to get started with Cwtch Development."),(0,o.kt)("h2",{id:"cwtch-issues-tracking-process"},"Cwtch Issues Tracking Process"),(0,o.kt)("p",null,"All Cwtch issues are tracked from the ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"cwtch-ui git repository"),", even if the bug/feature originates in an upstream library. This allows us to keep everything in one place."),(0,o.kt)("p",null,"Issues are generally divided into 4 distinct categories:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Unprocessed")," - These are new issues that have not been discussed by the Cwtch team."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=195&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Scheduled"))," - These issues have been planned for an upcoming release. They are usually tagged with the release they are expected to be fixed in e.g. ",(0,o.kt)("inlineCode",{parentName:"li"},"cwtch-1.11"),". A core Cwtch team member is likely working on the issue, or is expecting to work on the issue in the coming weeks."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=153&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Desired"))," - These are issues that we would like to fix but for some reason we are unable to schedule. This might be because the feature is large and requires a lot of effort, or because there is some blocker (e.g. a missing feature in Flutter or some other library) that prevents work on the feature."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=136&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Help Wanted"))," - These are generally small issues that we would like to fix but that have been designated low priority. These are ideal first issues for volunteers.")),(0,o.kt)("p",null,'If you would like to work on an open bug/feature, please comment on the issue and a member of the Cwtch team will follow up with advice on where to go from there. This helps us keep track of who is working on what problems, and reduces the amount of duplicate work. We aim to answer most queries within 24 hours, feel free to "bump" an issue if it takes longer than that.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)")),(0,o.kt)("h2",{id:"cwtch-pull-request-process"},"Cwtch Pull-Request Process"),(0,o.kt)("p",null,"All pull-requests must be reviewed and approved by a core Cwtch team member prior to merging. Sarah reviews all new and active pull requests multiple times a week."),(0,o.kt)("h3",{id:"build-bot"},"Build Bot"),(0,o.kt)("p",null,"All Cwtch projects are set up with automated builds and testing. Every pull request is expected to be able to pass through these pipelines prior to being merged. If buildbot reports a failure then Sarah will work with you to determine the issue, and any necessary fixes."),(0,o.kt)("p",null,"Buildbot can fail for reasons beyond your control e.g. many of our integration tests rely setting up Tor connections, these can be brittle on occasion and result in timeouts and failures. Always confirm the root cause of a test failure before deciding what to do next."),(0,o.kt)("h2",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/components/ecosystem-overview"},"Cwtch Ecosystem Overview")," - a summary of active Cwtch repositories from the Cwtch Secure Development Handbook."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"Contributing Documentation")," - advice on contributing Cwtch documentation."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/testing"},"Contributing Testing")," - advice on contributing by testing Cwtch."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/translate"},"Contributing Translations")," - advice on contributing translations to Cwtch.")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"All contributions are ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1cd6f7c0.24f5b1b9.js b/build-staging/es/assets/js/1cd6f7c0.24f5b1b9.js new file mode 100644 index 00000000..4d76e148 --- /dev/null +++ b/build-staging/es/assets/js/1cd6f7c0.24f5b1b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2995],{6448:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/cwtch","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/es/blog/tags/cwtch/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1e810a61.bb60f444.js b/build-staging/es/assets/js/1e810a61.bb60f444.js new file mode 100644 index 00000000..57b75f3a --- /dev/null +++ b/build-staging/es/assets/js/1e810a61.bb60f444.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4533],{1888:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/release","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1ebd8798.80be0f08.js b/build-staging/es/assets/js/1ebd8798.80be0f08.js new file mode 100644 index 00000000..d69815c6 --- /dev/null +++ b/build-staging/es/assets/js/1ebd8798.80be0f08.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4788],{3905:(e,t,n)=>{n.d(t,{Zo:()=>g,kt:()=>u});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},g=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,g=c(e,["components","mdxType","originalType","parentName"]),p=s(n),d=i,u=p["".concat(l,".").concat(d)]||p[d]||h[d]||r;return n?a.createElement(u,o(o({ref:t},g),{},{components:n})):a.createElement(u,o({ref:t},g))}));function u(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:i,o[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>s});var a=n(7462),i=(n(7294),n(3905));const r={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/es/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"24 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"autobindings",permalink:"/es/blog/tags/autobindings"},{label:"libcwtch",permalink:"/es/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/es/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/es/blog/cwtch-testing-ii"}},l={authorsImageUrls:[void 0]},s=[],g={toc:s},p="wrapper";function h(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,a.Z)({},g,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,i.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,i.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1f18ed69.10d0b90f.js b/build-staging/es/assets/js/1f18ed69.10d0b90f.js new file mode 100644 index 00000000..ca91d3aa --- /dev/null +++ b/build-staging/es/assets/js/1f18ed69.10d0b90f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8261],{420:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/libcwtch","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/1f984337.9a9de679.js b/build-staging/es/assets/js/1f984337.9a9de679.js new file mode 100644 index 00000000..66942e80 --- /dev/null +++ b/build-staging/es/assets/js/1f984337.9a9de679.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3769],{295:s=>{s.exports=JSON.parse('{"label":"bindings","permalink":"/es/blog/tags/bindings","allTagsPath":"/es/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/21b6537d.06433fac.js b/build-staging/es/assets/js/21b6537d.06433fac.js new file mode 100644 index 00000000..bf22dcd3 --- /dev/null +++ b/build-staging/es/assets/js/21b6537d.06433fac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2806],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return t?n.createElement(v,i(i({ref:r},p),{},{components:t})):n.createElement(v,i({ref:r},p))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:5},i="C\xf3mo compartir tu Paquete de Claves del Servidor",s={unversionedId:"servers/share-key",id:"servers/share-key",title:"C\xf3mo compartir tu Paquete de Claves del Servidor",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/share-key.md",sourceDirName:"servers",slug:"/servers/share-key",permalink:"/es/docs/servers/share-key",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/share-key.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"C\xf3mo eliminar un servidor",permalink:"/es/docs/servers/delete-server"},next:{title:"C\xf3mo desbloquear un servidor",permalink:"/es/docs/servers/unlock-server"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"c\xf3mo-compartir-tu-paquete-de-claves-del-servidor"},"C\xf3mo compartir tu Paquete de Claves del Servidor"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Experimento de Grupos")," activado.")),(0,o.kt)("p",null,"El Paquete de Claves del Servidor es el paquete de datos que una aplicaci\xf3n Cwtch necesita para poder usar un servidor. Si s\xf3lo quieres hacer que otros usuarios de Cwtch tengan conocimiento de tu servidor, puedes compartir \xe9sto con ellos. Entonces tendr\xe1n la habilidad de crear sus propios grupos en el servidor."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ve al icono del servidor"),(0,o.kt)("li",{parentName:"ol"},"Selecciona el servidor que quieras"),(0,o.kt)("li",{parentName:"ol"},"Usa el icono de copiar la direcci\xf3n para copiar las claves del servidor"),(0,o.kt)("li",{parentName:"ol"},"No compartas las claves con gente en la que no conf\xedas")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Keys.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/23c99aae.a5c52f6a.js b/build-staging/es/assets/js/23c99aae.a5c52f6a.js new file mode 100644 index 00000000..66b159f8 --- /dev/null +++ b/build-staging/es/assets/js/23c99aae.a5c52f6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8639],{867:a=>{a.exports=JSON.parse('{"label":"planning","permalink":"/es/blog/tags/planning","allTagsPath":"/es/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/24c23e10.2a5ce882.js b/build-staging/es/assets/js/24c23e10.2a5ce882.js new file mode 100644 index 00000000..b83ad9e0 --- /dev/null +++ b/build-staging/es/assets/js/24c23e10.2a5ce882.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3346],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),m=o,h=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(h,i(i({ref:t},u),{},{components:n})):r.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:6},i="Documentation Style Guide",s={unversionedId:"contribute/documentation",id:"contribute/documentation",title:"Documentation Style Guide",description:"This section documents the expected structure and quality of Cwtch documentation.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/documentation.md",sourceDirName:"contribute",slug:"/contribute/documentation",permalink:"/es/docs/contribute/documentation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/documentation.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Translating Cwtch",permalink:"/es/docs/contribute/translate"},next:{title:"Stickers",permalink:"/es/docs/contribute/stickers"}},c={},l=[{value:"Screenshots and Cast of Characters",id:"screenshots-and-cast-of-characters",level:2},{value:"Dialogue and Content",id:"dialogue-and-content",level:2},{value:"Experiments",id:"experiments",level:2},{value:"Risks",id:"risks",level:2}],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"documentation-style-guide"},"Documentation Style Guide"),(0,o.kt)("p",null,"This section documents the expected structure and quality of Cwtch documentation."),(0,o.kt)("h2",{id:"screenshots-and-cast-of-characters"},"Screenshots and Cast of Characters"),(0,o.kt)("p",null,"Most Cwtch documentation should feature at least one screenshot or animated image. Screenshots of the Cwtch application should be focused on the feature being described by the documentation."),(0,o.kt)("p",null,"To ensure consistency between screenshots we suggest that the profile involved should serve particular, constant, roles."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Alice")," - used to represent the primary profile."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Bob")," - the primary contact, useful when demonstrating peer-to-peer features"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Carol")," - a secondary contact, useful when demonstrating group features"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mallory")," - representing a malicious peer (to be used when demonstrating blocking functionality)")),(0,o.kt)("h2",{id:"dialogue-and-content"},"Dialogue and Content"),(0,o.kt)("p",null,"Where screenshots and demonstrations show dialogue, conversations, and/or images please keep the conversations short, on a casual topic. Examples include:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Organizing a picnic"),(0,o.kt)("li",{parentName:"ul"},"Sharing photos from a vacation"),(0,o.kt)("li",{parentName:"ul"},"Sending a document for review")),(0,o.kt)("h2",{id:"experiments"},"Experiments"),(0,o.kt)("p",null,"All features that rely on an experiment being enabled should all this out prominently at the top of the page e.g.:"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Example Experiment")," turned on.")),(0,o.kt)("h2",{id:"risks"},"Risks"),(0,o.kt)("p",null,"If a feature might result in destruction of key material or permanent deletion of state, then these should also be called out at the top of the documentation e.g.:"),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,o.kt)("strong",{parentName:"p"},"irreversible")," deletion of key material. This ",(0,o.kt)("strong",{parentName:"p"},"cannot be undone"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/25b9f0e4.5fecb48b.js b/build-staging/es/assets/js/25b9f0e4.5fecb48b.js new file mode 100644 index 00000000..5bade4af --- /dev/null +++ b/build-staging/es/assets/js/25b9f0e4.5fecb48b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6649],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>g});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),l=u(r),m=o,g=l["".concat(p,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(g,a(a({ref:t},s),{},{components:r})):n.createElement(g,a({ref:t},s))}));function g(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[l]="string"==typeof e?e:o,a[1]=c;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:5},a="Aceptar una invitaci\xf3n de grupo",c={unversionedId:"groups/accept-group-invite",id:"groups/accept-group-invite",title:"Aceptar una invitaci\xf3n de grupo",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/accept-group-invite.md",sourceDirName:"groups",slug:"/groups/accept-group-invite",permalink:"/es/docs/groups/accept-group-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/accept-group-invite.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Enviar invitaciones a un Grupo",permalink:"/es/docs/groups/send-invite"},next:{title:"C\xf3mo abandonar un grupo",permalink:"/es/docs/groups/leave-group"}},p={},u=[],s={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"aceptar-una-invitaci\xf3n-de-grupo"},"Aceptar una invitaci\xf3n de grupo"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Si un amigo te env\xeda una solicitud de grupo"),(0,o.kt)("li",{parentName:"ol"},"Elige si quieres o no unirte a este grupo"),(0,o.kt)("li",{parentName:"ol"},"Ahora el grupo est\xe1 en tu lista de contactos")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_acceptinvite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/26a00d26.52c0f2a0.js b/build-staging/es/assets/js/26a00d26.52c0f2a0.js new file mode 100644 index 00000000..3cb7d5b1 --- /dev/null +++ b/build-staging/es/assets/js/26a00d26.52c0f2a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6719],{9922:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/es/blog","blogDescription":"The latest updated on Cwtch development.","blogTitle":"Development Log"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/270b2a86.4eb699d2.js b/build-staging/es/assets/js/270b2a86.4eb699d2.js new file mode 100644 index 00000000..a5de4ebe --- /dev/null +++ b/build-staging/es/assets/js/270b2a86.4eb699d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[355],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>f});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var i=n.createContext({}),d=function(e){var r=n.useContext(i),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},p=function(e){var r=d(e.components);return n.createElement(i.Provider,{value:r},e.children)},l="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),l=d(t),h=a,f=l["".concat(i,".").concat(h)]||l[h]||u[h]||o;return t?n.createElement(f,s(s({ref:r},p),{},{components:t})):n.createElement(f,s({ref:r},p))}));function f(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var o=t.length,s=new Array(o);s[0]=h;var c={};for(var i in r)hasOwnProperty.call(r,i)&&(c[i]=r[i]);c.originalType=e,c[l]="string"==typeof e?e:a,s[1]=c;for(var d=2;d{t.r(r),t.d(r,{assets:()=>i,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var n=t(7462),a=(t(7294),t(3905));const o={sidebar_position:3},s="Sharing Cwtch Addresses",c={unversionedId:"chat/share-address-with-friends",id:"chat/share-address-with-friends",title:"Sharing Cwtch Addresses",description:"There are many ways to share a Cwtch address.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/share-address-with-friends.md",sourceDirName:"chat",slug:"/chat/share-address-with-friends",permalink:"/es/docs/chat/share-address-with-friends",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-address-with-friends.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Aceptar/denegar nuevas conversaciones",permalink:"/es/docs/chat/accept-deny-new-conversation"},next:{title:"Guardar el historial de conversaciones",permalink:"/es/docs/chat/save-conversation-history"}},i={},d=[{value:"Sharing Your Cwtch Address",id:"sharing-your-cwtch-address",level:2}],p={toc:d},l="wrapper";function u(e){let{components:r,...t}=e;return(0,a.kt)(l,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"sharing-cwtch-addresses"},"Sharing Cwtch Addresses"),(0,a.kt)("p",null,"There are many ways to share a Cwtch address."),(0,a.kt)("h2",{id:"sharing-your-cwtch-address"},"Sharing Your Cwtch Address"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Ve a tu perfil"),(0,a.kt)("li",{parentName:"ol"},"Haz clic en el icono de copiar direcci\xf3n")),(0,a.kt)("p",null,"Ahora puedes compartir esta direcci\xf3n. Las personas con esta direcci\xf3n podr\xe1n a\xf1adirte como un contacto de Cwtch."),(0,a.kt)("p",null,"Para obtener informaci\xf3n sobre c\xf3mo bloquear conexiones de personas que no conoces, por favor consulta ",(0,a.kt)("a",{parentName:"p",href:"/docs/settings/behaviour/block-unknown-connections"},"Configuraci\xf3n: Bloquear Conexiones Desconocidas")),(0,a.kt)("h1",{id:"sharing-a-friends-cwtch-address"},"Sharing A Friends Cwtch Address"),(0,a.kt)("p",null,"Inside of Cwtch there is another mechanism for exchanging Cwtch addresses."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/2928a17c.7412f6b7.js b/build-staging/es/assets/js/2928a17c.7412f6b7.js new file mode 100644 index 00000000..7eb04603 --- /dev/null +++ b/build-staging/es/assets/js/2928a17c.7412f6b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2054],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),p=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,f=u["".concat(s,".").concat(m)]||u[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Una Introducci\xf3n a la configuraci\xf3n de Cwtch",c={unversionedId:"settings/introduction",id:"settings/introduction",title:"Una Introducci\xf3n a la configuraci\xf3n de Cwtch",description:"Apariencia",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/introduction.md",sourceDirName:"settings",slug:"/settings/introduction",permalink:"/es/docs/settings/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Settings",permalink:"/es/docs/category/settings"},next:{title:"Appearance",permalink:"/es/docs/category/appearance"}},s={},p=[{value:"Apariencia",id:"apariencia",level:2},{value:"Comportamiento",id:"comportamiento",level:2},{value:"Experimentos",id:"experimentos",level:2}],l={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"una-introducci\xf3n-a-la-configuraci\xf3n-de-cwtch"},"Una Introducci\xf3n a la configuraci\xf3n de Cwtch"),(0,o.kt)("h2",{id:"apariencia"},"Apariencia"),(0,o.kt)("p",null,"These are settings which effect how Cwtch looks, including themes and localization."),(0,o.kt)("h2",{id:"comportamiento"},"Comportamiento"),(0,o.kt)("p",null,"These settings impact how Cwtch responds to certain events e.g. notifications for new messages, or requests from unknown public addresses."),(0,o.kt)("h2",{id:"experimentos"},"Experimentos"),(0,o.kt)("p",null,"Hay muchas caracter\xedsticas en Cwtch que a los usuarios les gustar\xeda tener pero cuya implementaci\xf3n requiere metadatos adicionales, o riesgo, m\xe1s all\xe1 del m\xednimo que Cwtch requiere para operaciones b\xe1sicas."),(0,o.kt)("p",null,"Como tal en ",(0,o.kt)("strong",{parentName:"p"},"Experimentos")," encontrar\xe1s un n\xfamero de ",(0,o.kt)("strong",{parentName:"p"},"ajustes opcionales")," que, cuando se activan, proporcionan caracter\xedsticas adicionales como chat de grupo, intercambio de archivos o formato de mensaje."),(0,o.kt)("p",null,"Deber\xedas pensar detenidamente al habilitar estas caracter\xedsticas sobre los nuevos riesgos que podr\xedan implicar, y si est\xe1s c\xf3modo optando por esos riesgos. Para muchos, los beneficios de compartir archivos, las previsualizaciones de im\xe1genes y el chat de grupo superan con creces los da\xf1os potenciales - pero para otros requerimos que los usuarios opten por usar estas caracter\xedsticas."),(0,o.kt)("p",null,"Puede optar por no hacerlo en cualquier momento, todas las caracter\xedsticas se implementan localmente dentro de la aplicaci\xf3n Cwtch."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/2d2c7491.761fd692.js b/build-staging/es/assets/js/2d2c7491.761fd692.js new file mode 100644 index 00000000..1ceeb50c --- /dev/null +++ b/build-staging/es/assets/js/2d2c7491.761fd692.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3455],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=s(r),f=o,m=u["".concat(p,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(m,i(i({ref:t},l),{},{components:r})):n.createElement(m,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Packet Format",c={unversionedId:"components/tapir/packet_format",id:"components/tapir/packet_format",title:"Packet Format",description:"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, len bytes of data, and the rest zero padded:",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/tapir/packet_format.md",sourceDirName:"components/tapir",slug:"/components/tapir/packet_format",permalink:"/es/security/components/tapir/packet_format",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Tapir",permalink:"/es/security/category/tapir"},next:{title:"Authentication Protocol",permalink:"/es/security/components/tapir/authentication_protocol"}},p={},s=[],l={toc:s},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"packet-format"},"Packet Format"),(0,o.kt)("p",null,"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, ",(0,o.kt)("inlineCode",{parentName:"p"},"len")," bytes of data, and the rest zero padded:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|\n")),(0,o.kt)("p",null,"Once encrypted, the entire 8192 byte data packet is encrypted using ",(0,o.kt)("a",{parentName:"p",href:"https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox"},"libsodium secretbox")," using the standard structure ( note in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)"),(0,o.kt)("p",null,"For information on how the secret key is derived see the ",(0,o.kt)("a",{parentName:"p",href:"/es/security/components/tapir/authentication_protocol"},"authentication protocol")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/302af923.36b0527a.js b/build-staging/es/assets/js/302af923.36b0527a.js new file mode 100644 index 00000000..307680e6 --- /dev/null +++ b/build-staging/es/assets/js/302af923.36b0527a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1664],{5960:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/bindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/31631b3e.beb6fb60.js b/build-staging/es/assets/js/31631b3e.beb6fb60.js new file mode 100644 index 00000000..37d85559 --- /dev/null +++ b/build-staging/es/assets/js/31631b3e.beb6fb60.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5170],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=o,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},a="Connectivity",s={unversionedId:"components/connectivity/intro",id:"components/connectivity/intro",title:"Connectivity",description:"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/connectivity/intro.md",sourceDirName:"components/connectivity",slug:"/components/connectivity/intro",permalink:"/es/security/components/connectivity/intro",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Connectivity & Tor",permalink:"/es/security/category/connectivity--tor"},next:{title:"Tapir",permalink:"/es/security/category/tapir"}},c={},p=[{value:"Known Risks",id:"known-risks",level:2},{value:"Private Key Exposure to the Tor Process",id:"private-key-exposure-to-the-tor-process",level:3},{value:"Mitigations",id:"mitigations",level:3},{value:"Tor Process Management",id:"tor-process-management",level:3},{value:"Testing Status",id:"testing-status",level:2}],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"connectivity"},"Connectivity"),(0,o.kt)("p",null,"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication."),(0,o.kt)("p",null,"We provide the ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity")," package for managing the Tor daemon and setting up and tearing down onion services through Tor."),(0,o.kt)("h2",{id:"known-risks"},"Known Risks"),(0,o.kt)("h3",{id:"private-key-exposure-to-the-tor-process"},"Private Key Exposure to the Tor Process"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (Requires Physical Access or Privilege Escalation to exploit)"),(0,o.kt)("p",null,"We must pass the private key of any onion service we wish to set up to the connectivity library, through the ",(0,o.kt)("inlineCode",{parentName:"p"},"Listen")," interface (and thus to the Tor process). This is one of the most critical areas that is outside of our control. Any binding to a rouge tor process or binary will result in compromise of the Onion private key."),(0,o.kt)("h3",{id:"mitigations"},"Mitigations"),(0,o.kt)("p",null,"Connectivity attempt to bind to the system-provided Tor process as the default, ",(0,o.kt)("em",{parentName:"p"},"only")," when it has been provided with an authentication token."),(0,o.kt)("p",null,"Otherwise connectivity always attempts to deploy its own Tor process using a known good binary packaged with the system (outside of the scope of the connectivity package)"),(0,o.kt)("p",null,"In the long term we hope an integrated library will become available and allow direct management through an in-process interface to prevent the private key from leaving the process boundary (or other alternative paths that allow us to maintain full control over the private key in-memory.)"),(0,o.kt)("h3",{id:"tor-process-management"},"Tor Process Management"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (Requires Physical Access or Privilege Escalation to exploit)"),(0,o.kt)("p",null,"Many issues can arise from the management of a separate process, including the need to restart, exit and otherwise ensure appropriate management."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity/src/branch/master/acn.go"},"ACN")," interface provides ",(0,o.kt)("inlineCode",{parentName:"p"},"Restart"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Close")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetBootstrapStatus")," interfaces to allow applications to manage the underlying Tor process. In addition the ",(0,o.kt)("inlineCode",{parentName:"p"},"SetStatusCallback")," method can be used to allow an application to be notified when the status of the Tor process changes."),(0,o.kt)("p",null,"However, if sufficiently-privileged users wish they can interfere with this mechanism, and as such the Tor process is a more brittle component interaction than others."),(0,o.kt)("h2",{id:"testing-status"},"Testing Status"),(0,o.kt)("p",null,"Current connectivity has limited unit testing capabilities and none of these are run during pull requests or merges. There is no integration testing."),(0,o.kt)("p",null,"It is worth noting that connectivity is used by both Tapir and Cwtch in their integration tests (and so despite the lack of package level testing, it is exposed to system-wide test conditions)"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/33c3c542.7cd1cc21.js b/build-staging/es/assets/js/33c3c542.7cd1cc21.js new file mode 100644 index 00000000..e140252d --- /dev/null +++ b/build-staging/es/assets/js/33c3c542.7cd1cc21.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4733],{4382:e=>{e.exports=JSON.parse('{"title":"Configuraci\xf3n","slug":"/category/settings","permalink":"/es/docs/category/settings","navigation":{"previous":{"title":"C\xf3mo desbloquear un servidor","permalink":"/es/docs/servers/unlock-server"},"next":{"title":"Una Introducci\xf3n a la configuraci\xf3n de Cwtch","permalink":"/es/docs/settings/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/34545dcf.e9bf7bdd.js b/build-staging/es/assets/js/34545dcf.e9bf7bdd.js new file mode 100644 index 00000000..aaab29ce --- /dev/null +++ b/build-staging/es/assets/js/34545dcf.e9bf7bdd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8667],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function A(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var A=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),o=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=o(e.components);return r.createElement(i.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,A=e.originalType,i=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=o(n),d=a,m=c["".concat(i,".").concat(d)]||c[d]||u[d]||A;return n?r.createElement(m,l(l({ref:t},p),{},{components:n})):r.createElement(m,l({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var A=n.length,l=new Array(A);l[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[c]="string"==typeof e?e:a,l[1]=s;for(var o=2;o{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>A,metadata:()=>s,toc:()=>o});var r=n(7462),a=(n(7294),n(3905));const A={sidebar_position:5},l="Experimento de Enlaces Cliqueables",s={unversionedId:"settings/experiments/clickable-links",id:"settings/experiments/clickable-links",title:"Experimento de Enlaces Cliqueables",description:"Esta funci\xf3n, si est\xe1 activada, presenta un riesgo de desanonimizaci\xf3n.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/clickable-links.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/clickable-links",permalink:"/es/docs/settings/experiments/clickable-links",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/clickable-links.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Vista previa de im\xe1genes y fotos de perfil",permalink:"/es/docs/settings/experiments/image-previews-and-profile-pictures"},next:{title:"Formato de mensajes",permalink:"/es/docs/settings/experiments/message-formatting"}},i={},o=[{value:"Riesgos",id:"riesgos",level:2}],p={toc:o},c="wrapper";function u(e){let{components:t,...A}=e;return(0,a.kt)(c,(0,r.Z)({},p,A,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"experimento-de-enlaces-cliqueables"},"Experimento de Enlaces Cliqueables"),(0,a.kt)("admonition",{type:"danger"},(0,a.kt)("p",{parentName:"admonition"},"Esta funci\xf3n, si est\xe1 activada, presenta un riesgo de ",(0,a.kt)("strong",{parentName:"p"},"desanonimizaci\xf3n"),"."),(0,a.kt)("p",{parentName:"admonition"},(0,a.kt)("strong",{parentName:"p"},"no abras")," las URLs de personas en las que no conf\xedas. Los enlaces enviados a trav\xe9s de Cwtch se abren a trav\xe9s del navegador ",(0,a.kt)("strong",{parentName:"p"},"predeterminado")," en el sistema. La mayor\xeda de los navegadores web no pueden proporcionar anonimato.")),(0,a.kt)("h1",{id:"activa-el-experimento-de-enlaces-cliqueables"},"Activa el Experimento de Enlaces Cliqueables"),(0,a.kt)("p",null,"Los enlaces cliqueables ",(0,a.kt)("strong",{parentName:"p"},"no")," est\xe1n habilitados por defecto. Para permitir a Cwtch abrir enlaces en mensajes:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Ir a Configuraci\xf3n"),(0,a.kt)("li",{parentName:"ol"},"Habilitar Experimentos"),(0,a.kt)("li",{parentName:"ol"},"Activa el ",(0,a.kt)("inlineCode",{parentName:"li"},"Experimento de Enlaces Cliqueables"))),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(1302).Z,width:"1243",height:"58"})),(0,a.kt)("h2",{id:"riesgos"},"Riesgos"),(0,a.kt)("p",null,"Los enlaces cliqueables en los mensajes son una caracter\xedstica muy \xfatil, sin embargo, hay riesgos que debes tener en cuenta si decides activar esta funci\xf3n."),(0,a.kt)("p",null,"Para prevenir la activaci\xf3n accidental, despu\xe9s de hacer clic en un enlace en un mensaje, Cwtch abrir\xe1 primero un aviso adicional con dos opciones:"),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(6004).Z,width:"1274",height:"192"})),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Copia la URL al portapapeles"),(0,a.kt)("li",{parentName:"ol"},"Abre la URL en el ",(0,a.kt)("strong",{parentName:"li"},"navegador web predeterminado"))),(0,a.kt)("p",null,"Puedes usar el bot\xf3n de retroceso de tu dispositivo o hacer clic lejos de este aviso para evitar seleccionar cualquiera de las dos opciones."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Cwtch No puede protegerte si abres enlaces maliciosos"),"."),(0,a.kt)("p",null,"La URL se abre en el ",(0,a.kt)("strong",{parentName:"p"},"navegador web predeterminado")," el cual es probable, como m\xednimo, que exponga tu direcci\xf3n IP al servidor que aloja la URL. Las p\xe1ginas web tambi\xe9n pueden usar otras vulnerabilidades del navegador para obtener informaci\xf3n adicional, o aprovecharse a\xfan m\xe1s de tu equipo."))}u.isMDXComponent=!0},6004:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png"},1302:(e,t,n)=>{n.d(t,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABNsAAAA6CAIAAAAGIMiyAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO3de1yM6f8/8GumdFCrViRZpbZVSbRbNklYpSSklmgplXNC+aLNSiJMRC1bDkmxkkOlROkcHWw1HTQdhlqsY6VaNoNQ8/vj/n3uzzw6TBmSz3o9/5q57muu08w1j3nPdd/XzRg2bBgRSlpaWngGAAAAAAAAABEw+7oBAAAAAAAA8JlCRAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfQMRKQAAAAAAAPQNRKQAAAAAAADQNxCRAgAAAAAAQN/47CJSFotV3UFCQoLIBXI4HBaL1emhzMzMqKiody1w+PDhoaGhmZmZHA6noqIiLy8vNDSUOnTz5k0fHx/q8YkTJ86ePSukHBcXl+rqaktLy55XLaQvglX3BIvFunnzZsd0BQWF5OTkgICA92kMAAAAAAD8O4j3dQP6AJ/P9/PzE0xpamrqq8a0Y2tru2HDBgkJifz8/Dt37rS1tamoqMjJyXXMOXjw4P79+3/8Fr4nJSWlQYMGDR48uK8bAgAAAAAAPcLn89ulMBiMD1X4R4pIlZSU6Me1tbWdpnw0fD7/5MmTH7PGnnN1dX3x4sXKlSvLysqE55wxY8bHadKHVVFRoa+v39etAAAAAACAblCB6I8//jh16lRdXd0hQ4YQQurq6jgcTkZGRkxMDPkQoWnvRqSenp7Tpk0bMmSIlJQUnWhiYkIIyc7OplNevXpVV1eXkpKyZ8+eXm3PJ27z5s1fffXVli1bug1HAQAAAAAAeg+fz//xxx/XrVunrKwsmK6srKysrGxhYbFu3bpff/01JibmPYPSXryONCIiYunSpaqqqhISEi8FUEcFUyQkJFRVVZctWxYeHt577emWi4tLSUnJgQMH8vPzq6qqrl+/7unpSR0yMzM7d+4cm83mcrklJSW///674BrvqFGj/vjjD+ol7c4HFrRp06bs7OzKyko2m33o0KGOGbS1tRsaGqKjo3vS2ri4uCtXrtBPvb29c3JyqqqqSktLO64Am5ubs9ls6m+M5cuXJyYmlpaWcrncgoICf39/wZwfqi9CsNns4OBg6jGHwwkMDMzKyqqsrCwuLqbTBSkoKFy5ciUvL8/AwIAQsmPHjry8vKqqqpKSkpSUFC0trXeqHQAAAAAAhOPz+T4+Pv7+/u3CUUHKysr+/v4+Pj4dz+l9J721Rvp///d/xsbGr1+/TkxMDAsL43K57TKMGTOGfqylpbVkyRIrKytjY+P169fv37+/l1pFYTKZ1dXVgimBgYEhISGEEFlZWXV19XPnzjU3N8+ZM2fx4sVU2PPy5cs3b94kJyffv39fQ0NjxowZPj4+q1atol4+ZMiQhISExsbGyZMnz58//+3bt9u2bWtXqYeHh4uLS3x8fElJiba2to2NzYEDB9auXSuYR1FR8e+//xahR35+fjY2Nunp6WVlZSNGjGj3L4WRkZGvr299ff3y5csJIZKSknV1ddevX29sbDQ0NLSxsbl79y4dVX6ovvScoaFhSkrKvXv3JkyYYG5uvmXLlnaRcFhYmIKCgqenJ5vNXrZsmZ2dXVpaWmFhoby8/NChQzt+tAAAAAAAoB1lMmBRm95kvpo6f6B4ZwuTfMLnE8In/FZ+G/E1kXAY25NiHRwc+Hz+9u3bRV4p7a2I1MLCghBy6dIleplRCC6Xu3Hjxra2NltbWwsLi96OSDvubFRUVEQ/Dg4OTkpKIoQ0NTXt3r174sSJKSkpubm5ubm5dB41NbWvv/6afpqZmUkVeOjQocuXL0+bNq1jFDdz5szq6mp6NIYNG6anp9cuT79+/UTr0fTp069du9ZpTCgrK+vl5fXy5cvVq1c3NjYSQg4ePEgfDQkJYbPZgi35UH3puWvXrlFVHD9+vKioSFdXV/BoVFSUqqqqr69vRkYGIURDQ4PP58fHx6ekpIhcIwAAAADAZ8WOr+vbatZpICqICkf5czUlF/coHKU4OjqWl5fHxsaKFpT2VkSqqKjY2tp6+PBhOoXL5XZsIp/Pp8+6PHz4sLW1taKiYi81SbDSnuxsFB0dvXXrVhkZGeqpvb399OnTVVRUpKSkBgwYUF9f3+mrOBzOnDlzZGRkeDyeYLqCgsKwYcOqqqqopwwGo+NyaENDg5qa2rt2Z8qUKXJyciUlJZ0edXNzk5eXd3R0vHPnDp24fv36CRMmDBo0SFpaWlZWVkJC4oP3RTR1dXXS0tL0UyMjI2Vl5X379sXFxVEpSUlJU6ZMCQwM/Ouvv0pKSg4fPnz//v0PUjUAAAAAwL+SHV93Z6u58Dz/f4GUT96SNqn1hu9ahbu7e2xsLJ/PFyEo/ezuRyoaBweHX375hRBy6tSpDRs2cDicrnK+fv26tbW1XQhHCGlpaSksLNT+Dy0tLSMjo3Z5/vrrL3l5+U2bNr1T24YOHUoIYTI7fytv3LghJSW1cuVKOoXFYjk7O9+/f//QoUOurq5C7nzzPn35IGpqal6+fGlra0v/L5CVlWVoaHjixImXL1/OmjUrPj7e2tq6N6oGAAAAAPgXUCYDfFvNepKTT/htpI0xV4upPOCda1FWtrW1fffWEdJ7EWl9fb2YmJhgIKSlpaXZgeC2NCtXrhQTE+tq7bFvGRkZvXnzZvHixWFhYbm5ue0u3hX8J0BbW/vJkycdS6itrdXW1tbQ0BBSy759+xobG+fOnTtr1qyety0nJ6e1tbWr82aTkpIyMjKmTp3q4+NDpXz77bd379718PA4e/as4OnKH7YvH8STJ0/CwsJUVFSOHTsmmL5nz54ff/zR2dm5X79+5ubd/N8DAAAAAPDZWtSm1+3JurRWwmeavfM5mxRTU1PRXthbZ+2mpKSsWLFi5syZDAbj+PHjwref0dLScnFxsbKy4vP5H+H6QAaDYW9vL5jy9OlT6trRrjQ2NsrKyh47diwvL09bW1tHR4e6JpMybdq0lpaW27dvT5gwQVdX9+jRo1T6s2fPhg4dam5unpKScurUqR07doSEhJw5c+bu3buGhoYNDQ2hoaGCtdTW1oaHh69cuXLXrl2zZ8+urq5+8eKFqqqqvLz8smXLCCHPnz/X0NAwNDTMz8+nX3X//v3S0lITExN/f//s7GwdHZ3+/fvT8SchZOXKlTExMQsWLHj8+PHRo0efPXumo6Ozc+fOO3fuGBsbDxw4ULANXfVFsOqe9IUaZxcXF/opn88XYS/lX3/9VUlJae7cuYGBgR4eHqtWrdLV1S0rK6uvrzcyMpKUlHzw4MG7lgkAAAAA8JmYzO8+wqRP2W3lt0noDhGtIl1dXWrd7l1P3O2tiDQgIEBXV3fChAk2NjbW1tYtLS30IWpRSzDylJSUpE46zc3N3bdvXy81icZgMLZv3y6YwuVyhUek3t7eX3/99ffffz9+/PjHjx8XFRWNGDGCPlpeXm5lZdW/f//Gxsbw8HB6Z6bExEQnJ6eAgABPT8/z589LS0s7ODi4u7v369fv77//vnTpUseKjhw5UlZWtm7dulGjRk2cOPHNmzdPnz69ceMGdTQtLc3c3Nzf33/KlCmCr9qyZcvWrVtNTU2tra2fP3/e8ZrS1atXR0ZGurq6PnjwIDg4ePPmzTY2Nm/evKmpqampqRHM2VVfBKvuYV8YDIaXlxf9tLW1VbS7+3h5eSkqKs6YMePx48ctLS2ampoTJ06UkJB4/vx5amrq7t27RSgTAAAAAOBzoM4f2H0mQgghbaStlbSJKX0hWkVDhogYyjKGDRsmPIfgTjPvytPT09zcXFFRUUpKik40MTEhhGRnZ9Mpr169qq+vT0lJaXdvTAAAAAAAABBZ1VuPnmyxyyfkLb/1Bf+1/G0PIibKlrmtra0jR45kMBjvukbauxEpTUlJiX5cW1vbaQoAAAAAAAB8QJdbF4/kDxKeRzAilc1bIj5MToSKHj16ZGJiIkJE2ltn7bbTMeZEFAoAAAAAANCrrjLudBuR0hiE8arskaxIEWlZWZkIryK4+wsAAAAAAMC/1Slm6VvS1pOcTMJkEsar1D9Fqyg9PV20FyIiBQAAAAAA+Hd6RP7xEUsTnodBGAxCGAwixmC+ja58/fDpu9by8OHDmJgYEU7ZJYhIAQAAAAAA/sXOMTi/iKX0ZKVUnDAlGGKNAVfftYrAwECRmkYIIlJaTExMZGTkBykqISGhh7c5YbPZW7Zs6UnOrprX87oCAwMzMzN7kpMQYmlpWV1draWl1cP8nyfBIe35G/HvYG9vf/PmzZ7kZLFYubm5vd2ej6/nk1c0Z8+ePXv2bO+VDwAAAJ+VcwyOqXhYKLPwFqOhq9CUQRhMwpRkiPNjuPXh13teeEREBLVAKlrbPtLORp+IK1eufP311+0SW1tbey/0KigoKCgocHNz66XyRRMTEyMlJWVlZdXXDRHFpzmknzN/f/9p06ZZW1vfv3//o1W6du3aFStW6OjoCCZyudxdu3adPHlSX1//zJkzVOLbt28bGhri4+MDAgIIIdShDRs2xMfHf7TWfij48AMAAIDIHpF/9jCv7SHXhGfj8/l8Pr/V99A2xjYnJ6dui42IiNi2bZuYmJhop+ySzy0iXbhwYb9+/Qghvr6+mpqaCxYs6O0aS0pKKisre7uWd1VeXi54h9j/Lb06pAcPHtTQ0LC0tOyl8j8Rly9fvnv37urVqz9IaVwuV1FR8WOGoz3k5eWVk5MzduzYRYsWLVmypKamJi4urq8b9V4+ze8TAAAA+Dehokomk7lt2zYOh7N+/fqubhf68OHD/fv3x8TEMJlMkcNR8rlFpI2NjdSDtrY2Pp//Ee5As2LFit6uQgQ+Pj593QTR9eqQMplMMTGx3iv/EyEmJsZkfrAz9sPDwz/NM5bfvHlTW1tbW1ubnJxcXFxsZGT0vx6RfprfJwAAAPAvw2AwqCAzNjb2/Pnzc+fONTMzGzt2rJKSEiGktrb2xo0baWlp0dHRYmJi77M6SsF1pP81dOjQa9euVVVV5efnb9iwgUpUUFAIDw8vLi7mcDgXLlzQ09Nr96p58+alpqaWl5cXFhaGhIS0O5qXl7dz507qsaenZ25ubmVlZU5Ojqenp2A2Dw+PsrIyV1dXfX39CxculJSUcLncvLw8d3d3Os9XX32Vn59fVVV17dq1Tn+YmpiYJCQklJWVlZSUHDlyREhPo6KioqOjCSGWlpZsNjsqKqq0tLS8vDw2Nnb48OHtMh85cqSgoGDy5MkKCgqRkZGlpaUVFRW5ubmOjo6C2ToOlIyMTGZmZlRUFJXh6NGjOTk5w4cPj4mJiYqKysrKqqysvH79+vr164UMNYvFSkxMPH/+PIfDOXnypOCQslis1NTUK1eulJeXs9lsf3//gIAAaogyMjJmzpxJFevs7JyVlVVRUZGfn+/l5UUlxsTEnDt3rt3bvXPnTlNT0xEjRlRVVZ06dUqwd6GhoYWFhVwut6ioqNvrto2MjGJjY2/cuFFWVhYXF2dsbEwISUhIoE8TXbNmDZfL9fPzo54eO3YsISGBELJ3797CwsKqqqqCgoJdu3bRBTo6Ot66dcvCwoJ66u7uXlJSIiMjIyMjc+TIETabXVlZmZGRQb8j6enpBw4coB57eHgUFxcLNu/cuXPq6uo//PBDVVWVt7c3IaSrcgQFBwez2ezy8vL09HR6bCk+Pj4FBQXUYz09vejo6NLS0hs3brQ7LVZJSSk5OTkhIUFGRkYwfcuWLXl5eVVVVX/88cfWrVupROrNTUpKKi8vLy0t/e2334SPebfa2tpev34tJENXg08IMTc3T0pK4nA4HA4nPT1dQUGBSh83bhz1koyMjDlz5hBCupq/MTExx48fT01Nrays/OWXXwgh27dvz8/Pr6ioyMjIoE/WcHJyouZFQUFBx5lIOnz4hYzP+8wONze3a9euVVZWlpSUUJevdzr3u5oUO3bsyM/Pr6yszMrKyszM3L59O5XescvCv1IAAACgD1FBJpPJFBcXv3DhwqpVq4yMjNTU1NTU1IyMjFatWnXhwgVxcfH3XB2lICL9L0lJyfDw8DVr1vz111+Ojo7U72YWi6Wuru7h4bFy5Up5efl2kaSOjo6Xl9etW7cWL14cGBhYWFjYVeFLlixZtGhRQkLCggULIiMjORwOfWjp0qXOzs6nTp0KCQnhcrl37tw5ePDg5s2bHz58KHjqdr9+/YKCgpYvX/7gwYPVq1cbGRm1q8LHx4fH49na2u7Zs2f8+PFUsNEtOTm5R48eLV26NCwsTENDo10HAwICDAwMtm/ffvXq1c2bN2tqavr5+c2cOTMiIoIOQigdB4rH4wUFBY0ePdrd3d3JyWn8+PFBQUHUuZ0jRoyIjIx0dHTkcDhLly41MzMTMtQaGhrPnj3bvXv38ePH2zV+yJAhqampS5Ysyc/Pt7W1VVNT8/X19fPzExcXp4J2Q0NDDw+P7OzsSZMmXbp0ycHBgY7rhg4deuzYMcG3+5dffklPT7979662tvaiRYsEK3r48GFkZOTatWuzsrKsrKwWLlwoZEh9fX2ZTObatWt37do1cOBAKgIpKChQU1Ojgplx48bxeLyxY8dS+TU1Ndls9vz582fNmnXmzJkffvhh//792dnZdIEnT55sbGycPn069dTQ0JDL5fJ4vH379unq6gYEBLi6ujY1Nbm7u7e7rrJTdnZ2t2/fzszM1NbW3rFjByGk23IOHDjw3XffHThwwMnJKTk5mc1md1X4rl27JCUlN23atGnTpnY7aR0+fJjJZLq6uvJ4PDrR1dXVzs4uNjbW3t4+Ly/vp59+WrJkCXVoyJAhGRkZTk5OqampFhYWLi4u3XatUwYGBocPH2YwGOfPn+8qj5DBJ4S4ubm1tbWtWbPG2dn5zJkz9KkWfD5/69atfn5+TCaT+rwJmb9U+Orj4xMXF7dmzZo5c+YEBwfPnDnz4cOHa9euJYTo6+uvX7++vLzcwcEhPDxcQkJCeL+6HR+RZ4eLi0tlZeW8efN+/vnny5cvE0I6nfudTgqqa7GxsT/99FN2djb1Tyqd3q7Lwr9SAAAAoG/RQSkVl7ZDpb9/OEo+t7N2hbt79y598uGhQ4csLCxiY2MNDAwuXrx49epVQkhOTo65ubngSxwdHV+8eEFdj1dUVCSkcCsrqxs3brBYLEJIWVkZna6kpDR37ty4uLg9e/YQQng8Hr1mWFdXFxERYW5unpKSQgi5c+cOtd5YXFx89erVOXPmXL/+3y2w5s2bN3z4cBaLVVNTU1NTY2NjM2bMmB52PDQ0lMvlstlsY2NjwZUZBwcHMzMzf3//S5cuEUL69evHZDJVVVUzMzNDQ0PbFdLpQMXHx0+YMGHRokWvX7++ePEitTBLCLl9+zZVApvNzsvLmzFjRlpaWldD/eTJk6VLl3ba8ubm5n379hFCysvLJ06cWFZWlpiYSAgZO3bsDz/8QAiZP38+j8ejgvMdO3ZYWVmZmJgkJycTQu7du0ctuhKBt7urIdq2bRv1ICUlxdjYWEjgZ2trq6KiYmdnR73LYmJi27Zt09fXj4iIsLOzc3BwCAoK0tDQiImJsbe3V1BQ0NfXl5eXj4yMnDBhAoPBUFRUVFJSonfloZWXl48ePZp6PHLkyKNHjxJCvv/++9OnT1OZuVxuUlKSra1tRUVFV23rSrflTJgwITY2lhouIeHorFmz1NXVFy5cSM0Fapwpp0+fHjhwoJubW7vLTS0sLEpKSqg9h0pLS0eOHGlmZhYWFkYIaW5u3rt3L1Xj5MmTR40a9a792rt37549exgMRkNDw/r16wXnXTuSkpJCBl9MTExKSkpFReXkyZOC3Wez2UlJSYSQUaNGUdceC5m/HA5n8+bN1CEWi1VVVUWN54kTJ0JCQqZMmTJjxoynT59SuxYVFRVNmTJFeO+6HR+RZ4e4uPiAAQO++uor+h3sdO53OinMzMxKSkr8/f0JIaWlpdOmTaPymJubd+yy8K8UAAAA6HNUtMlgMPh8frvI8/0DURoi0k6kpaW1tbVJSkoqKSnJysrOmjWL3pa2ublZMKeSktLTpz26gayCgsK9e/c6po8dO5bBYFy79t89r7y9vSdNmiQlJUW9zdLS0u1ewuPxnjx5MnDgQMFEdXV1BoNBRbyUqqqqnjRMUHNz86BBg+inkyZNamxspH5PE0L27t0rLS1tb2/v5ORUVla2f/9+OggXMlCenp7Z2dl8Pr+rW2U0NTXJycl1O9TC8Xi8ly9f0peANjU1UaM3aNAgOTk5wSiitbW13Wvpt1tI+Y6OjvPmzRs4cGBbW9uAAQPExbucON988w2Px6ODn8jISG9vb01NzaKiops3b44bN446YXLXrl02NjaOjo7Dhw+/ffs29T/CyJEjJ02aZG1tXV1dffr0afqEZ0LI5cuXWSyWvr7+d999x+fzjxw5Qo3Y7du3qQy1tbVNTU30CaU91205SkpKAwYMuHv3brdFaWtrt7S0dPxrRlJSUldXt6CgoGNM+OWXX1ZXV9NPHz9+PHTo0I4l83i8dtf3trS0iImJycjI0CuuMjIyDAbj+fPndJ6NGzfGx8fv3bvXwsJC+Cm7J0+eFDL4v/32m7Oz88aNG9esWXP9+nVqfU9QQ0MDfV1uV/OXz+fT+eXk5FRVVemP5T///NO/f39FRcVnz54JaaQQHcen3dF3mh0hISHW1ta//vprbW1tUlKSv79/p3O/00khJyf3559/dmxDp10W8pUCAAAAn5QPGH92hLN2hamtrX3x4kViYqLBf1BrCzQej/fll1/2pKhXr14NHjy4Y3pqampdXZ2Pj4+GhgYhxNnZed68eUePHjUxMZk4cWJXpcnJydXV1QmmUEtPmzdvppvq4ODQk4YJERgY+OWXX9KXqN2/f3/ZsmUGBgb79u1TV1cXvMZVyEBt2LBBWlp6wIAB1MmrFMFtdeTl5evr67sdatE0NTU1NzcbCBBhVycZGZkNGzYUFBQYGxubmJjU19cLyfzo0SMZGRnq2lFCiKWlJYPBoE5HzMnJGTlypKmp6a1btwghXC7XwMBAR0cnPz+fyrxly5ZJkyZ5eHjw+XxXV1fBYuPi4urr621sbCZOnEitXtbW1r569UpwtVZOTu7x48eEECpCEN4p+mtFSDl0htevX6urqwsvkBDS1NQkJSVlYGDQLr2lpeX48ePGxsb0qhqtublZWVmZfjpw4MCmpqZuKyKE5OfnM5lMwQ/5/PnzW1tbBRdmKdu2bXv+/HnHMLIdIYOflJRkZ2c3bdq0mJgYU1NT+nrLjno4f//555+bN28KfiwTExOfPn0qwh8K76Or2XH48GFLS8sFCxZUVFQ4Ozvr6+t3nPtdTYrm5uZO/1PotMtCvlIAAADg84GItBvFxcXTp0+nrtGaOXMmtX8J7erVqwoKCkFBQUpKSpaWltTv41evXnWMB0pLS8eOHUv95Fq4cCF9f5G2tjYvLy9xcXFqaxBFRUUJCYnBgwfr6OjQO99QvvnmG2dnZx0dnZCQECkpKWoNh67r9OnTDx8+3Lhxo5mZmYyMjKOjo6GhoeDLeTyejIzMO/3kraysPHDgwJgxY6i2OTs7r1ixQklJ6ebNmy0tLT0ZqKlTpy5cuPDs2bPnz5+3s7ObOnUqlVlXV9fLy0tHRycwMFBWVvbs2bPdDrVo4uLipKWlT548qaGhoaam1u1Wpc3NzYqKitQ2TnTiiBEjJCUlFRQUtLS03Nzc5OXlqXTBIaXfiNjY2IaGhi1btpiZmU2dOtXd3b2srKympoYQEhQUJCYmZmRklJubSwjJycnR1NQcPHjw77//TgiZMmWKp6enjo5OdXV1p2tl1EdIS0srLS2NSuFwOLNnz3Z2dh4zZkxYWNjbt29PnDhBCHn8+PHo0aNdXFyMjIz09fU7FsXj8dTV1enrWrsqh1ZdXT1jxow5c+YMHz589erVw4cPf/LkCYPBaHebnOTk5H/++cfb21tPT09fX3/VqlX0ocDAwPj4eDs7u+XLlwu+5Pr163p6et7e3hoaGt7e3iNHjuzhdrilpaVlZWUuLi4eHh5GRkaurq5Lly7Nzc0VvEiV7mxsbOy33377008/0Yn9+/fX+g8lJSXhg79hw4a5c+fW1tbW1NRQ23R31Soh81dQVlaWrq6ur6+vjIyMoaEhtaNPUlKSvLz8sWPH9PT07O3tVVRUejIO76Or2eHj4zN58uTq6mpqN/LW1taOc7+rSZGXl6enp0f9xbZx48YvvvhCSJeFf6UAAADAZwIRaTe8vLxKSkpcXV3Lyso2bdo0btw4waNnz549derU+PHj09PTd+3aRe02lJaWpqqqmpqaKpjT09MzLy/PwcGhoqJi3bp19DWBhJCioiIWi6WiohIeHv7bb79xOJzVq1dHRUVpamoK/jiur693c3M7d+6cpqZmQEAAtVAmWJevr+/z588DAgJycnIcHBwEqyCEREdHv3jxIi0tbfLkyT3vfkRERGRkpKWl5aZNm9TV1Z2cnNLT048ePfrixYt223t2OlA///zzrVu39u7du3PnzpqaGnqzooaGhjlz5pw/f/7bb7/dv39/aWlpt0MtmqysrKCgoGHDhlFbV8+aNUv43j8RERF1dXXBwcGCtzOpqKhITEycMmVKTEzM7Nmz6eUgwSGl3wgej8disRgMRlBQ0L59+5qamgS3mKqsrJSQkKAumTty5AiDwbhz5w61vq2iomJpaXnmzJn4+HhVVdWO91OJi4tTV1dvbW2lIlhCyI4dO2pqatatWxcZGamsrOzn50eFEMHBwU+ePNm4cePBgwdbW1s7RlDR0dGysrIXL16kFi27KofGYrHq6uq2b9+emJhoZ2enq6ublpZWWlrKYrHoayMJIffv3w8KCvriiy9OnToVHh4+Y8YMwUI8PT0LCwtdXfZp1doAAAHqSURBVF0F0/38/JKSkqytrS9evGhubh4aGirkat52fv7556qqqoULF4aHhy9evJjNZne1yBYQEHDv3j3BfYa2b9+e8B9+fn7CB3/06NFeXl6VlZXe3t7FxcWC58a3I2T+tmvPmTNnpk2bdv369aCgIFNTU0JIcnLy0aNHR40aFRUV5ebm9uDBgx6Og8g6nR1qamrjx48/ePBgYWHh7Nmzz58/X1pa2nHudzUpdu/efeXKlVmzZsXHx5uamra0tFAfv067LPwrBQAAAD4TjK5ueErreB0jwPuIiYl59eqV8O1qoVPZ2dlcLnfZsmV93RCAHikuLg4LCwsODu7rhgAAAMCnC2ukAP8b9PT0Bg0aRG80BfCJmzx5cv/+/cvLy/u6IQAAAPBJw167AP8b7O3t//77byE31QT4FPj7+ycnJz979szd3f3mzZvU/ZwAAAAAuoKIFOB/g4GBgQh39AH4yEaPHm1lZdXW1vbnn38KXkQNAAAA0ClcRwoAAAAAAAB9A9eRAgAAAAAAQN9ARAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfeP/AQclJUZgqx9hAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/359fb69f.b8e0e841.js b/build-staging/es/assets/js/359fb69f.b8e0e841.js new file mode 100644 index 00000000..ef7f97ba --- /dev/null +++ b/build-staging/es/assets/js/359fb69f.b8e0e841.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4685],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>f});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=a.createContext({}),u=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d=function(e){var t=u(e.components);return a.createElement(s.Provider,{value:t},e.children)},l="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),l=u(r),m=n,f=l["".concat(s,".").concat(m)]||l[m]||p[m]||o;return r?a.createElement(f,i(i({ref:t},d),{},{components:r})):a.createElement(f,i({ref:t},d))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[l]="string"==typeof e?e:n,i[1]=c;for(var u=2;u{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var a=r(7462),n=(r(7294),r(3905));const o={sidebar_position:1},i="\xbfQu\xe9 es Cwtch?",c={unversionedId:"intro",id:"intro",title:"\xbfQu\xe9 es Cwtch?",description:"Cwtch (/k\u028at\u0283/ - Una palabra galesa m\xe1s o menos traducida a \u201cun abrazo que crea un lugar seguro\u201d) es una aplicaci\xf3n de mensajer\xeda descentralizada, que preserva la privacidad.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/intro.md",sourceDirName:".",slug:"/intro",permalink:"/es/docs/intro",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/es/docs/category/getting-started"}},s={},u=[],d={toc:u},l="wrapper";function p(e){let{components:t,...r}=e;return(0,n.kt)(l,(0,a.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"qu\xe9-es-cwtch"},"\xbfQu\xe9 es Cwtch?"),(0,n.kt)("p",null,"Cwtch (/k\u028at\u0283/ - Una palabra galesa m\xe1s o menos traducida a \u201cun abrazo que crea un lugar seguro\u201d) es una aplicaci\xf3n de mensajer\xeda descentralizada, que preserva la privacidad."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Descentralizado y Abierto"),': No hay "Servicio de Cwtch" o "Red de Cwtch". Los participantes en Cwtch pueden albergar sus propios espacios seguros o prestar su infraestructura a otros que buscan un espacio seguro. El protocolo Cwtch es abierto, y cualquiera es libre de construir bots, servicios e interfaces de usuario e integrar e interactuar con Cwtch.'),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Preservaci\xf3n de la privacidad"),": Toda la comunicaci\xf3n en Cwtch est\xe1 cifrada de extremo a extremo y tiene lugar en los servicios de Onion Tor v3."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Resistente a los metadatos"),": Cwtch ha sido dise\xf1ada de tal manera que no hay informaci\xf3n intercambiada o disponible para nadie sin su consentimiento expl\xedcito, incluyendo mensajes on-the-wire y metadatos de protocolo.")),(0,n.kt)("h1",{id:"seguridad-y-cifrado"},"Seguridad y cifrado"),(0,n.kt)("p",null,"Para ver en profundidad la tecnolog\xeda de seguridad, privacidad y cifrado subyacente utilizada en Cwtch, por favor consulte nuestro ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Manual de seguridad")),(0,n.kt)("h1",{id:"primeros-pasos"},"Primeros pasos"),(0,n.kt)("p",null,"Puedes descargar la \xfaltima versi\xf3n de Cwtch desde ",(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download/"},"https://cwtch.im/download/")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3a042459.0e82c2da.js b/build-staging/es/assets/js/3a042459.0e82c2da.js new file mode 100644 index 00000000..5eca0808 --- /dev/null +++ b/build-staging/es/assets/js/3a042459.0e82c2da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2516],{7132:s=>{s.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable","allTagsPath":"/es/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3a109bd3.f064b182.js b/build-staging/es/assets/js/3a109bd3.f064b182.js new file mode 100644 index 00000000..93f69a60 --- /dev/null +++ b/build-staging/es/assets/js/3a109bd3.f064b182.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7782],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>g});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),s=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),p=s(n),h=r,g=p["".concat(l,".").concat(h)]||p[h]||u[h]||a;return n?o.createElement(g,i(i({ref:t},m),{},{components:n})):o.createElement(g,i({ref:t},m))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:r,i[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/es/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"10 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/es/blog/tags/documentation"},{label:"security-handbook",permalink:"/es/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/es/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/es/blog/autobindings-ii"}},l={authorsImageUrls:[void 0]},s=[],m={toc:s},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,o.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3ace3922.74740c09.js b/build-staging/es/assets/js/3ace3922.74740c09.js new file mode 100644 index 00000000..4ddb4db3 --- /dev/null +++ b/build-staging/es/assets/js/3ace3922.74740c09.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8974],{5670:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/reproducible-builds","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3ca9f026.619ce63a.js b/build-staging/es/assets/js/3ca9f026.619ce63a.js new file mode 100644 index 00000000..a0d8bb16 --- /dev/null +++ b/build-staging/es/assets/js/3ca9f026.619ce63a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8177],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||o;return a?n.createElement(m,s(s({ref:t},d),{},{components:a})):n.createElement(m,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const o={},s="Message Overlays",i={unversionedId:"components/ui/overlays",id:"components/ui/overlays",title:"Message Overlays",description:"Adapted from Notes on the Cwtch Chat API",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/overlays.md",sourceDirName:"components/ui",slug:"/components/ui/overlays",permalink:"/es/security/components/ui/overlays",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Input",permalink:"/es/security/components/ui/input"},next:{title:"Deployment",permalink:"/es/security/deployment"}},l={},c=[{value:"Chat overlays, lists, and bulletins",id:"chat-overlays-lists-and-bulletins",level:2},{value:"Data structure",id:"data-structure",level:2},{value:"Chat Messages (Overlay 1)",id:"chat-messages-overlay-1",level:2},{value:"Invitations (Overlays 100 and 101)",id:"invitations-overlays-100-and-101",level:2},{value:"Lists / Bulletin Boards",id:"lists--bulletin-boards",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"message-overlays"},"Message Overlays"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/08-chatapi/"},"Adapted from: Discreet Log #8: Notes on the Cwtch Chat API")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note: This section covers overlay protocols on-top of the Cwtch protcol. For information on the Cwtch Protocol messages themselves please see ",(0,r.kt)("a",{parentName:"strong",href:"/es/security/components/cwtch/message_formats"},"Message Formats"))),(0,r.kt)("p",null,"We envision Cwtch as a platform for providing an authenticated transport layer to higher-level applications. Developers are free to make their own choices about what application layer protocols to use, whether they want bespoke binary message formats or just want to throw an HTTP library on top and call it a day. Cwtch can generate new keypairs for you (which become onion addresses; no need for any DNS registrations!) and you can REST assured that any data your application receives from the (anonymous communication) network has been authenticated already."),(0,r.kt)("p",null,"For our current stack, messages are wrapped in a minimal JSON frame that adds some contextual information about the message type. And because serialised JSON objects are just dictionaries, we can easily add more metadata later on as needed."),(0,r.kt)("h2",{id:"chat-overlays-lists-and-bulletins"},"Chat overlays, lists, and bulletins"),(0,r.kt)("p",null,'The original Cwtch alpha demoed "overlays": different ways of interpreting the same data channel, depending on the structure of the atomic data itself. We included simple checklists and BBS/classified ads as overlays that could be viewed and shared with any Cwtch contact, be it a single peer or a group. The wire format looked like this:'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:1,d:"hey there!"}\n{o:2,d:"bread",l:"groceries"}\n{o:3,d:"garage sale",p:"[parent message signature]"}\n')),(0,r.kt)("p",null,"Overlay field ",(0,r.kt)("inlineCode",{parentName:"p"},"o")," determined if it was a chat (1), list (2), or bulletin (3) message. The data field ",(0,r.kt)("inlineCode",{parentName:"p"},"d")," is overloaded, and lists/bulletins need additional information about what group/post they belong to. (We use message signatures in place of IDs to avoid things like message ordering problems and maliciously crafted IDs. This is also how the Cwtch protocol communicates to the front end which message is being acked.)"),(0,r.kt)("h2",{id:"data-structure"},"Data structure"),(0,r.kt)("p",null,"Implementing tree-structured data on top of a sequential message store comes with obvious performance disadvantages. For example, consider the message view, which loads most-recent-messages first and only goes back far enough to fetch enough messages to fill the current viewport, in comparison with a (somewhat pathological) forum where almost every message is a child of the very first message in the history, which could have been gigs and gigs of data-ago. If the UI only displays top-level posts until the user expands them, we have to parse the entire history before we get enough info to display anything at all."),(0,r.kt)("p",null,'Another problem is that multiplexing all these overlays into one data store creates "holes" in the data that confuse ',(0,r.kt)("a",{parentName:"p",href:"https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html"},"lazy-loaded listviews")," and scrollbars. The message count may indicate there is a ton more information to display if the user simply scrolls, but when it actually gets fetched and parsed we might realize that none of it is relevant to the current overlay."),(0,r.kt)("p",null,"None of these problems are insurmountable, but they demonstrate a flaw in our initial assumptions about the nature of collaborative message flows and how we should be handling that data."),(0,r.kt)("h1",{id:"overlay-types"},"Overlay Types"),(0,r.kt)("p",null,"As stated above, overlays are specified in a very simple JSON format with the following structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'type ChatMessage struct {\n O int `json:"o"`\n D string `json:"d"`\n}\n')),(0,r.kt)("p",null,"Where O stands for ",(0,r.kt)("inlineCode",{parentName:"p"},"Overlay")," with the current supported overlays documented below:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"1: data is a chat string\n2: data is a list state/delta\n3: data is a bulletin state/delta\n100: contact suggestion; data is a peer onion address\n101: contact suggestion; data is a group invite string\n")),(0,r.kt)("h2",{id:"chat-messages-overlay-1"},"Chat Messages (Overlay 1)"),(0,r.kt)("p",null,"The most simple over is a chat message which simply contains raw, unprocessed chat message information."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:1,d:"got milk?"}\n')),(0,r.kt)("h2",{id:"invitations-overlays-100-and-101"},"Invitations (Overlays 100 and 101)"),(0,r.kt)("p",null,"Instead of receiving the invite as an incoming contact request at the profile level, new inline invites are shared with a particular contact/group, where they can be viewed and/or accepted later, even if they were initially rejected (potentially by accident)."),(0,r.kt)("p",null,"The wire format for these are equally simple:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}\n{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}\n')),(0,r.kt)("p",null,'This represents a departure from our original "overlays" thinking to a more action-oriented representation. The chat "overlay" can communicate that someone ',(0,r.kt)("em",{parentName:"p"},"did"),' something, even if it\'s paraphrased down to "added an item to a list," and the lists and bulletins and other beautifully chaotic data can have their state precomputed and stored separately.'),(0,r.kt)("h2",{id:"lists--bulletin-boards"},"Lists / Bulletin Boards"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note: Expected to be Defined in Cwtch Beta 1.5")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3cd9b44e.16ca6c39.js b/build-staging/es/assets/js/3cd9b44e.16ca6c39.js new file mode 100644 index 00000000..1565145d --- /dev/null +++ b/build-staging/es/assets/js/3cd9b44e.16ca6c39.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8186],{2332:e=>{e.exports=JSON.parse('{"title":"Connectivity & Tor","slug":"/category/connectivity--tor","permalink":"/es/security/category/connectivity--tor","navigation":{"previous":{"title":"Component Ecosystem Overview","permalink":"/es/security/components/ecosystem-overview"},"next":{"title":"Connectivity","permalink":"/es/security/components/connectivity/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3db42865.27ab3fca.js b/build-staging/es/assets/js/3db42865.27ab3fca.js new file mode 100644 index 00000000..c1f2d599 --- /dev/null +++ b/build-staging/es/assets/js/3db42865.27ab3fca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7139],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/3ec42fa4.61f4a24d.js b/build-staging/es/assets/js/3ec42fa4.61f4a24d.js new file mode 100644 index 00000000..d09b1751 --- /dev/null +++ b/build-staging/es/assets/js/3ec42fa4.61f4a24d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5583],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>b});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,b=p["".concat(c,".").concat(m)]||p[m]||d[m]||o;return n?r.createElement(b,i(i({ref:t},l),{},{components:n})):r.createElement(b,i({ref:t},l))}));function b(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>u});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1},i="Pruebas de Cwtch",s={unversionedId:"contribute/testing",id:"contribute/testing",title:"Pruebas de Cwtch",description:"Esta secci\xf3n documenta algunas formas de comenzar con la prueba de Cwtch.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/testing.md",sourceDirName:"contribute",slug:"/contribute/testing",permalink:"/es/docs/contribute/testing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/testing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Developing Cwtch",permalink:"/es/docs/contribute/developing"},next:{title:"Translating Cwtch",permalink:"/es/docs/contribute/translate"}},c={},u=[{value:"Ejecutar Fuzzbot",id:"ejecutar-fuzzbot",level:3},{value:"\xdanete al Grupo de Pruebas de Candidatos de Lanzamientos de Cwtch",id:"\xfanete-al-grupo-de-pruebas-de-candidatos-de-lanzamientos-de-cwtch",level:3},{value:"Cwtch Nightlies",id:"cwtch-nightlies",level:3},{value:"Submitting Feedback",id:"submitting-feedback",level:3}],l={toc:u},p="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"pruebas-de-cwtch"},"Pruebas de Cwtch"),(0,a.kt)("p",null,"Esta secci\xf3n documenta algunas formas de comenzar con la prueba de Cwtch."),(0,a.kt)("h3",{id:"ejecutar-fuzzbot"},"Ejecutar Fuzzbot"),(0,a.kt)("p",null,"FuzzBot es nuestro bot de pruebas de desarrollo. Puede a\xf1adir FuzzBot como contacto: ",(0,a.kt)("inlineCode",{parentName:"p"},"cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad"),"."),(0,a.kt)("admonition",{title:"Ayuda de FuzzBot",type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Enviar a FuzzBot un mensaje de ",(0,a.kt)("inlineCode",{parentName:"p"},"help")," lo activar\xe1 para enviar una respuesta con todos los comandos de prueba disponibles actualmente.")),(0,a.kt)("p",null,"Para m\xe1s informaci\xf3n sobre FuzzBot consulta nuestro ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Blog de desarrollo"),"."),(0,a.kt)("h3",{id:"\xfanete-al-grupo-de-pruebas-de-candidatos-de-lanzamientos-de-cwtch"},"\xdanete al Grupo de Pruebas de Candidatos de Lanzamientos de Cwtch"),(0,a.kt)("p",null,"Enviar a Fuzzbot el comando de ",(0,a.kt)("inlineCode",{parentName:"p"},"testgroup-invite")," har\xe1 que FuzzBot te invite al ",(0,a.kt)("strong",{parentName:"p"},"Grupo de Testeadores de Cwtch"),"! Ah\xed puedes hacer preguntas, publicar informes de errores y ofrecer comentarios."),(0,a.kt)("h3",{id:"cwtch-nightlies"},"Cwtch Nightlies"),(0,a.kt)("p",null,"Las construcciones de Cwtch Nightly son construcciones de desarrollo que contienen nuevas caracter\xedsticas que est\xe1n listas para probar."),(0,a.kt)("p",null,"Las versiones m\xe1s recientes de desarrollo de Cwtch est\xe1n disponibles en nuestro ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"servidor de compilaci\xf3n"),"."),(0,a.kt)("p",null,"Nosotros ",(0,a.kt)("strong",{parentName:"p"},"no")," recomendamos que los testers se actualicen siempre a los \xfaltimos Nightlies. En su lugar publicaremos un mensaje en el Grupo de Pruebas de Candidatos de Lanzamientos de Cwtch cuando un Nightlie significativo se encuentre disponible. Un Nightly se considera significativo si contiene una nueva caracter\xedstica o una correcci\xf3n importante de errores."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"All contributions are ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))),(0,a.kt)("h3",{id:"submitting-feedback"},"Submitting Feedback"),(0,a.kt)("p",null,"There are three main ways of submitting testing feedback to the team:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Via Cwtch: Either via the Release Candidate Testers Group or directly to a Cwtch team member."),(0,a.kt)("li",{parentName:"ul"},"Via Gitea: Please open an issue in ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues")," - please do not worry about duplicate issues, we will de-duplicate as part of our triage process."),(0,a.kt)("li",{parentName:"ul"},"Via Email: Email ",(0,a.kt)("inlineCode",{parentName:"li"},"team@cwtch.im")," with the bug report and one of our team will look into it.")),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/404e0e09.606db230.js b/build-staging/es/assets/js/404e0e09.606db230.js new file mode 100644 index 00000000..4911045c --- /dev/null +++ b/build-staging/es/assets/js/404e0e09.606db230.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5703],{3905:(e,r,n)=>{n.d(r,{Zo:()=>u,kt:()=>f});var a=n(7294);function t(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function o(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);r&&(a=a.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var r=1;r=0||(t[n]=e[n]);return t}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(t[n]=e[n])}return t}var c=a.createContext({}),p=function(e){var r=a.useContext(c),n=r;return e&&(n="function"==typeof e?e(r):s(s({},r),e)),n},u=function(e){var r=p(e.components);return a.createElement(c.Provider,{value:r},e.children)},d="mdxType",l={inlineCode:"code",wrapper:function(e){var r=e.children;return a.createElement(a.Fragment,{},r)}},m=a.forwardRef((function(e,r){var n=e.components,t=e.mdxType,o=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=t,f=d["".concat(c,".").concat(m)]||d[m]||l[m]||o;return n?a.createElement(f,s(s({ref:r},u),{},{components:n})):a.createElement(f,s({ref:r},u))}));function f(e,r){var n=arguments,t=r&&r.mdxType;if("string"==typeof e||t){var o=n.length,s=new Array(o);s[0]=m;var i={};for(var c in r)hasOwnProperty.call(r,c)&&(i[c]=r[c]);i.originalType=e,i[d]="string"==typeof e?e:t,s[1]=i;for(var p=2;p{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var a=n(7462),t=(n(7294),n(3905));const o={sidebar_position:1},s="Una Introducci\xf3n a los Grupos de Cwtch",i={unversionedId:"groups/introduction",id:"groups/introduction",title:"Una Introducci\xf3n a los Grupos de Cwtch",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/introduction.md",sourceDirName:"groups",slug:"/groups/introduction",permalink:"/es/docs/groups/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/es/docs/category/groups"},next:{title:"Crea un grupo nuevo",permalink:"/es/docs/groups/create-group"}},c={},p=[{value:"C\xf3mo funcionan los Grupos en profundidad",id:"c\xf3mo-funcionan-los-grupos-en-profundidad",level:2}],u={toc:p},d="wrapper";function l(e){let{components:r,...n}=e;return(0,t.kt)(d,(0,a.Z)({},u,n,{components:r,mdxType:"MDXLayout"}),(0,t.kt)("h1",{id:"una-introducci\xf3n-a-los-grupos-de-cwtch"},"Una Introducci\xf3n a los Grupos de Cwtch"),(0,t.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,t.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,t.kt)("a",{parentName:"p",href:"/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,t.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,t.kt)("p",null,(0,t.kt)("strong",{parentName:"p"},"Nota: la Comunicaci\xf3n de Grupos Resistentes a los Metadatos sigue siendo un \xe1rea de investigaci\xf3n activa y lo que se documenta aqu\xed probablemente cambie en el futuro.")),(0,t.kt)("p",null,"De forma predeterminada, Cwtch s\xf3lo soporta chat de persona a persona. Para soportar conversaciones de varias personas y entrega offline, se requiere un tercero (no confiable). Llamamos a estas entidades ",(0,t.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},'"servidores"')),(0,t.kt)("p",null,"Estos servidores pueden ser configurados por cualquiera y est\xe1n pensados para estar siempre en l\xednea. Lo m\xe1s importante es que toda la comunicaci\xf3n con un servidor est\xe1 dise\xf1ada de tal manera que el servidor aprenda la menor informaci\xf3n posible sobre los contenidos o metadatos."),(0,t.kt)("p",null,"En muchos sentidos, la comunicaci\xf3n con un servidor es id\xe9ntica a la comunicaci\xf3n con un contacto regular de Cwtch. Se toman todos los mismos pasos, sin embargo el servidor siempre act\xfaa como el par entrante, y el par saliente siempre utiliza ",(0,t.kt)("strong",{parentName:"p"},"par de claves ef\xedmeras")," - para que cada sesi\xf3n del servidor est\xe9 desconectada."),(0,t.kt)("p",null,"Como tal, las conversaciones entre pares y servidores solo difieren en los ",(0,t.kt)("em",{parentName:"p"},"tipos")," de mensajes que se env\xedan entre las dos partes, con el servidor guardando todos los mensajes que recibe y permitiendo as\xed que cualquier cliente busque mensajes antiguos."),(0,t.kt)("p",null,"The risk model associated with servers is more complicated that peer-to-peer communication, as such we currently require people who want to use servers within Cwtch to ",(0,t.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"opt-in to the Group Chat experiment")," in order to add, manage and create groups on untrusted servers."),(0,t.kt)("h2",{id:"c\xf3mo-funcionan-los-grupos-en-profundidad"},"C\xf3mo funcionan los Grupos en profundidad"),(0,t.kt)("p",null,"Cuando una persona quiere iniciar una conversaci\xf3n grupal, primero genera aleatoriamente una ",(0,t.kt)("inlineCode",{parentName:"p"},"clave grupal")," secreta. Todas las comunicaciones del grupo ser\xe1n cifradas usando esta clave."),(0,t.kt)("p",null,"Junto con la ",(0,t.kt)("inlineCode",{parentName:"p"},"clave de grupo"),", el creador del grupo tambi\xe9n decide el",(0,t.kt)("strong",{parentName:"p"},"Servidor de Cwtch")," para usar como anfitri\xf3n del grupo. Para m\xe1s informaci\xf3n sobre c\xf3mo los servidores se autentican ver ",(0,t.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/key_bundles.html"},"paquetes de claves"),"."),(0,t.kt)("p",null,"Un ",(0,t.kt)("inlineCode",{parentName:"p"},"Identificador de grupo")," se genera usando la clave de grupo y el servidor de grupo. Estos tres elementos se empaquetan en una invitaci\xf3n que puede ser enviada a los miembros potenciales del grupo (i.e a travez de las conexiones peer-to-peer existentes)."),(0,t.kt)("p",null,"Para enviar un mensaje al grupo, un perfil se conecta al servidor que aloja al grupo (ver abajo), y encripta su mensaje usando la ",(0,t.kt)("inlineCode",{parentName:"p"},"Clave de Grupo")," y genera una firma criptogr\xe1fica a trav\xe9s de la ",(0,t.kt)("inlineCode",{parentName:"p"},"Identificaci\xf3n de grupo"),", ",(0,t.kt)("inlineCode",{parentName:"p"},"Servidor de Grupo")," y el mensaje descifrado (Ve: ",(0,t.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/message_formats.html"},"Formatos wire")," para m\xe1s informaci\xf3n)."),(0,t.kt)("p",null,"Para recibir mensajes del grupo, un perfil debe estar conectado al servidor que aloja el grupo y descarga ",(0,t.kt)("em",{parentName:"p"},"todos")," los mensajes (desde su conexi\xf3n anterior). Los perfiles intentan descifrar cada mensaje usando la ",(0,t.kt)("inlineCode",{parentName:"p"},"Clave de Grupo")," si logran verificar la firma (ve ",(0,t.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/server.html"},"servidores de Cwtch"),", ",(0,t.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/groups.html"},"Grupos de Cwtch")," para una visi\xf3n general de los ataques y mitigaciones)."))}l.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/43449e47.7c30d776.js b/build-staging/es/assets/js/43449e47.7c30d776.js new file mode 100644 index 00000000..b9b9fc48 --- /dev/null +++ b/build-staging/es/assets/js/43449e47.7c30d776.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[153],{4936:e=>{e.exports=JSON.parse('{"title":"Building a Cwtch App","slug":"/category/building-a-cwtch-app","permalink":"/es/developing/category/building-a-cwtch-app","navigation":{"previous":{"title":"Release and Packaging Process","permalink":"/es/developing/release"},"next":{"title":"Getting Started","permalink":"/es/developing/building-a-cwtch-app/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/43b107c1.2a677536.js b/build-staging/es/assets/js/43b107c1.2a677536.js new file mode 100644 index 00000000..c93fb5dc --- /dev/null +++ b/build-staging/es/assets/js/43b107c1.2a677536.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9200],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),d=i,g=c["".concat(l,".").concat(d)]||c[d]||h[d]||r;return n?a.createElement(g,o(o({ref:t},u),{},{components:n})):a.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/es/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"3 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"support",permalink:"/es/blog/tags/support"},{label:"testing",permalink:"/es/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/es/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/es/blog/cwtch-platform-support"}},l={authorsImageUrls:[void 0]},p=[{value:"Current Limitations of Flutter Gherkin",id:"current-limitations-of-flutter-gherkin",level:2},{value:"Integrating Tests into the Pipeline",id:"integrating-tests-into-the-pipeline",level:2},{value:"Catching Bugs!",id:"catching-bugs",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},c="wrapper";function h(e){let{components:t,...r}=e;return(0,i.kt)(c,(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"We first ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,i.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})),(0,i.kt)("h2",{id:"current-limitations-of-flutter-gherkin"},"Current Limitations of Flutter Gherkin"),(0,i.kt)("p",null,"The original ",(0,i.kt)("a",{parentName:"p",href:"https://pub.dev/packages/flutter_gherkin"},"flutter_gherkin")," is under semi-active development; however, the latest published versions don't support using it with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Test")," was originally intended to run single widget/unit tests for a Flutter project."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Drive")," was originally intended to run integration tests ",(0,i.kt)("em",{parentName:"li"},"on a device or an emulator"),".")),(0,i.kt)("p",null,"However, in recent releases these lines have become blurred. The new ",(0,i.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/testing/integration-tests"},"integration_test")," package that comes built into newer Flutter releases has support for both ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),". This was a great change because it decreases the required overhead to run larger integration tests (",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," sets up a host-controller model that requires a dedicated control channel to be setup, whereas ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible)."),(0,i.kt)("p",null,"There is thankfully code in the ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter_gherkin")," repository that supports running tests with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", however this code currently has a few issues:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The test code generation produces code that doesn't compile without minor changes."),(0,i.kt)("li",{parentName:"ul"},'Certain functionality like "take a screenshot" does not work on desktop.')),(0,i.kt)("p",null,"Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test."),(0,i.kt)("li",{parentName:"ul"},"Certain Flutter widgets like ",(0,i.kt)("inlineCode",{parentName:"li"},"DropdownButton")," are not compatible with built-in steps like ",(0,i.kt)("inlineCode",{parentName:"li"},"tap")," because they internally contain multiple copies of the same widget.")),(0,i.kt)("p",null,"Because of the above issues we have chosen to ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/flutter_gherkin"},"fork flutter_gherkin")," to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing."),(0,i.kt)("h2",{id:"integrating-tests-into-the-pipeline"},"Integrating Tests into the Pipeline"),(0,i.kt)("p",null,"One of the major limitations of ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display."),(0,i.kt)("p",null,"Thankfully it is possible to use ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Xvfb"},"Xfvb")," to create a virtual framebuffer, and set ",(0,i.kt)("inlineCode",{parentName:"p"},"DISPLAY")," to render to that buffer:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"export DISPLAY=:99\nXvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\n")),(0,i.kt)("p",null,"This allows us to neutralize our main issue with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", and efficiently run tests in our pipeline."),(0,i.kt)("h2",{id:"catching-bugs"},"Catching Bugs!"),(0,i.kt)("p",null,"This small amount of integration work has already caught its first bug."),(0,i.kt)("p",null,"Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature"},"02_save_load.feature")," simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment."),(0,i.kt)("p",null,"The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory ",(0,i.kt)("inlineCode",{parentName:"p"},"$USER_HOME/Downloads")," didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available."),(0,i.kt)("p",null,"As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!"),(0,i.kt)("h2",{id:"next-steps"},"Next Steps"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More automated tests:")," We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More platforms:")," Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/getting-started/supported_platforms"},"our target platforms"),". We expect to start this work soon; expect more news in a future Cwtch Testing update!")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More steps:")," One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the ",(0,i.kt)("inlineCode",{parentName:"p"},"expect to see the message")," step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"send a file")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"set profile picture"),"."))),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/474a1a11.6f6502bc.js b/build-staging/es/assets/js/474a1a11.6f6502bc.js new file mode 100644 index 00000000..9c712852 --- /dev/null +++ b/build-staging/es/assets/js/474a1a11.6f6502bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1825],{7240:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/api","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4972.486cf118.js b/build-staging/es/assets/js/4972.486cf118.js new file mode 100644 index 00000000..4e318acc --- /dev/null +++ b/build-staging/es/assets/js/4972.486cf118.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4972],{4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});var a=n(7294),o=n(5999),l=n(1944),r=n(7961);function i(){return a.createElement(a.Fragment,null,a.createElement(l.d,{title:(0,o.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4a6801a7.83c15240.js b/build-staging/es/assets/js/4a6801a7.83c15240.js new file mode 100644 index 00000000..123413a5 --- /dev/null +++ b/build-staging/es/assets/js/4a6801a7.83c15240.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4697],{5367:e=>{e.exports=JSON.parse('{"title":"Tapir","slug":"/category/tapir","permalink":"/es/security/category/tapir","navigation":{"previous":{"title":"Connectivity","permalink":"/es/security/components/connectivity/intro"},"next":{"title":"Packet Format","permalink":"/es/security/components/tapir/packet_format"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4aa555c3.da7eeb80.js b/build-staging/es/assets/js/4aa555c3.da7eeb80.js new file mode 100644 index 00000000..68a2f8d6 --- /dev/null +++ b/build-staging/es/assets/js/4aa555c3.da7eeb80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7797],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),u=n,f=h["".concat(c,".").concat(u)]||h[u]||m[u]||o;return a?r.createElement(f,i(i({ref:t},p),{},{components:a})):r.createElement(f,i({ref:t},p))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"16 de junio de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"release",permalink:"/es/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/es/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/es/blog/cwtch-nightly-v.11-74"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function m(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(159).Z,width:"1004",height:"480"})))}m.isMDXComponent=!0},159:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4d27f429.93b89f91.js b/build-staging/es/assets/js/4d27f429.93b89f91.js new file mode 100644 index 00000000..eb84640a --- /dev/null +++ b/build-staging/es/assets/js/4d27f429.93b89f91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[788],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=i.createContext({}),s=function(e){var t=i.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},p="mdxType",b={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(r),d=n,h=p["".concat(c,".").concat(d)]||p[d]||b[d]||a;return r?i.createElement(h,o(o({ref:t},u),{},{components:r})):i.createElement(h,o({ref:t},u))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>b,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"20 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/es/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"repliqate",permalink:"/es/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/es/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/es/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],u={toc:s},p="wrapper";function b(e){let{components:t,...r}=e;return(0,n.kt)(p,(0,i.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,n.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,n.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,n.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,n.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4d4c5a31.68003e61.js b/build-staging/es/assets/js/4d4c5a31.68003e61.js new file mode 100644 index 00000000..4bf65b8a --- /dev/null +++ b/build-staging/es/assets/js/4d4c5a31.68003e61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6588],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>b});var r=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;e=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var l=r.createContext({}),c=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},p=function(t){var e=c(t.components);return r.createElement(l.Provider,{value:e},t.children)},f="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var n=t.components,i=t.mdxType,o=t.originalType,l=t.parentName,p=s(t,["components","mdxType","originalType","parentName"]),f=c(n),d=i,b=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return n?r.createElement(b,a(a({ref:e},p),{},{components:n})):r.createElement(b,a({ref:e},p))}));function b(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in e)hasOwnProperty.call(e,l)&&(s[l]=e[l]);s.originalType=t,s[f]="string"==typeof t?t:i,a[1]=s;for(var c=2;c{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:15},a="Setting Profile Attributes",s={unversionedId:"profiles/profile-info",id:"profiles/profile-info",title:"Setting Profile Attributes",description:"This functionality is currently only available in the Nightly Release builds of Cwtch.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/profile-info.md",sourceDirName:"profiles",slug:"/profiles/profile-info",permalink:"/es/docs/profiles/profile-info",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/profile-info.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_position:15},sidebar:"tutorialSidebar",previous:{title:"Setting Availability Status",permalink:"/es/docs/profiles/availability-status"},next:{title:"Conversations",permalink:"/es/docs/category/conversations"}},l={},c=[],p={toc:c},f="wrapper";function u(t){let{components:e,...o}=t;return(0,i.kt)(f,(0,r.Z)({},p,o,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-profile-attributes"},"Setting Profile Attributes"),(0,i.kt)("admonition",{title:"Nightly Feature",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This functionality is currently ",(0,i.kt)("strong",{parentName:"p"},"only")," available in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly Release")," builds of Cwtch."),(0,i.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,i.kt)("p",null,"On the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/introduction#manage-profiles"},"profile management pane")," there are three free-form text fields below your profile picture."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(92).Z},(0,i.kt)("img",{src:n(6852).Z,width:"783",height:"354"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"You can fill these fields with any information your would like potential contacts to know. ",(0,i.kt)("strong",{parentName:"p"},"This information is public")," - do not put any information in here that you do not want to share with everyone."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(4076).Z},(0,i.kt)("img",{src:n(3506).Z,width:"730",height:"342"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Contacts will be able to see this information in ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/conversation-settings"},"conversation settings")),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(5637).Z},(0,i.kt)("img",{src:n(136).Z,width:"294",height:"195"}))),(0,i.kt)("figcaption",null)))}u.isMDXComponent=!0},5637:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},92:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png"},4076:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},136:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},6852:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png"},3506:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4df29f52.94cada4a.js b/build-staging/es/assets/js/4df29f52.94cada4a.js new file mode 100644 index 00000000..66ba5a8e --- /dev/null +++ b/build-staging/es/assets/js/4df29f52.94cada4a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4273],{6693:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/security-handbook","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/4f68bcc6.d9b156bf.js b/build-staging/es/assets/js/4f68bcc6.d9b156bf.js new file mode 100644 index 00000000..e5eed984 --- /dev/null +++ b/build-staging/es/assets/js/4f68bcc6.d9b156bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3516],{4289:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-security"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/511b7c07.1dc648e2.js b/build-staging/es/assets/js/511b7c07.1dc648e2.js new file mode 100644 index 00000000..0d71130c --- /dev/null +++ b/build-staging/es/assets/js/511b7c07.1dc648e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[724],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,d=u["".concat(c,".").concat(m)]||u[m]||h[m]||a;return r?n.createElement(d,i(i({ref:t},l),{},{components:r})):n.createElement(d,i({ref:t},l))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Cwtch Technical Basics",s={unversionedId:"components/intro",id:"components/intro",title:"Cwtch Technical Basics",description:"This page presents a brief technical overview of the Cwtch protocol.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/intro.md",sourceDirName:"components",slug:"/components/intro",permalink:"/es/security/components/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Cwtch Components",permalink:"/es/security/category/cwtch-components"},next:{title:"Component Ecosystem Overview",permalink:"/es/security/components/ecosystem-overview"}},c={},p=[{value:"A Cwtch Profile",id:"a-cwtch-profile",level:2},{value:"2-party conversions: Peer to Peer",id:"2-party-conversions-peer-to-peer",level:2},{value:"Multi-party conversations: Groups and Peer to Server Communication",id:"multi-party-conversations-groups-and-peer-to-server-communication",level:2},{value:"Servers are Peers",id:"servers-are-peers",level:3}],l={toc:p},u="wrapper";function h(e){let{components:t,...a}=e;return(0,o.kt)(u,(0,n.Z)({},l,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cwtch-technical-basics"},"Cwtch Technical Basics"),(0,o.kt)("p",null,"This page presents a brief technical overview of the Cwtch protocol."),(0,o.kt)("h2",{id:"a-cwtch-profile"},"A Cwtch Profile"),(0,o.kt)("p",null,"Users can create one of more Cwtch Profiles. Each profile generates a random ed25519 keypair compatible with Tor."),(0,o.kt)("p",null,"In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys + associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages)."),(0,o.kt)("h2",{id:"2-party-conversions-peer-to-peer"},"2-party conversions: Peer to Peer"),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(7868).Z,width:"960",height:"540"})),(0,o.kt)("p",null,'For 2 parties to engage in a peer-to-peer conversation both must be online, but only one needs to be reachable via their onion service. For the sake of clarity we often label one party the "inbound peer" (the one who hosts the onion service) and the other party the "outbound peer" (the one that connects to the onion service).'),(0,o.kt)("p",null,"After connection both parties engage in an authentication protocol which:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Asserts that each party has access to the private key associated with their public identity."),(0,o.kt)("li",{parentName:"ul"},"Generates an ephemeral session key used to encrypt all further communication during the session.")),(0,o.kt)("p",null,"This exchange (documented in further detail in ",(0,o.kt)("a",{parentName:"p",href:"/es/security/components/tapir/authentication_protocol"},"authentication protocol"),") is ",(0,o.kt)("em",{parentName:"p"},"offline deniable")," i.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the fact - it is impossible to definitely prove that the exchange happened at all."),(0,o.kt)("p",null,"After, the authentication protocol the two parties may exchange messages with each other freely."),(0,o.kt)("h2",{id:"multi-party-conversations-groups-and-peer-to-server-communication"},"Multi-party conversations: Groups and Peer to Server Communication"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Note: Metadata Resistant Group Communication is still an active research area and what is documented here will likely change in the future.")),(0,o.kt)("p",null,"When a person wants to start a group conversation they first randomly generate a secret ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),". All group communication will be encrypted using this key."),(0,o.kt)("p",null,"Along with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),", the group creator also decides on a ",(0,o.kt)("strong",{parentName:"p"},"Cwtch Server")," to use as the host of the group. For more information on how Servers authenticate themselves see ",(0,o.kt)("a",{parentName:"p",href:"/es/security/components/cwtch/key_bundles"},"key bundles"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Identifier")," is generated using the group key and the group server and these three elements are packaged up into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections)."),(0,o.kt)("p",null,"To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts their message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and generates a cryptographic signature over the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Id"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Server")," and the decrypted message (see: ",(0,o.kt)("a",{parentName:"p",href:"/es/security/components/cwtch/message_formats"},"wire formats")," for more information)."),(0,o.kt)("p",null,"To receive message from the group, a profile connected to the server hosting the group and downloads ",(0,o.kt)("em",{parentName:"p"},"all")," messages (since their previous connection). Profiles then attempt to decrypt each message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and if successful attempt to verify the signature (see ",(0,o.kt)("a",{parentName:"p",href:"/es/security/components/cwtch/server"},"Cwtch Servers")," ",(0,o.kt)("a",{parentName:"p",href:"/es/security/components/cwtch/groups"},"Cwtch Groups")," for an overview of attacks and mitigations)."),(0,o.kt)("h3",{id:"servers-are-peers"},"Servers are Peers"),(0,o.kt)("p",null,"In many respects communication with a server is identical to communication with a regular Cwtch peer, all the same steps above are taken however the server always acts as the inbound peer, and the outbound peer always uses newly generated ",(0,o.kt)("strong",{parentName:"p"},"ephemeral keypair"),' as their "longterm identity".'),(0,o.kt)("p",null,"As such peer-server conversations only differ in the ",(0,o.kt)("em",{parentName:"p"},"kinds")," of messages that are sent between the two parties, with the server relaying all messages that it receives and also allowing any client to query for older messages."))}h.isMDXComponent=!0},7868:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5181f1e2.0dbff0ec.js b/build-staging/es/assets/js/5181f1e2.0dbff0ec.js new file mode 100644 index 00000000..a5fa96f7 --- /dev/null +++ b/build-staging/es/assets/js/5181f1e2.0dbff0ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[26],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},y=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=l(n),y=o,h=p["".concat(c,".").concat(y)]||p[y]||d[y]||s;return n?r.createElement(h,i(i({ref:t},u),{},{components:n})):r.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=y;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[p]="string"==typeof e?e:o,i[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const s={sidebar_position:3},i="Key Bundles",a={unversionedId:"components/cwtch/key_bundles",id:"components/cwtch/key_bundles",title:"Key Bundles",description:"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/key_bundles.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/key_bundles",permalink:"/es/security/components/cwtch/key_bundles",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Message Formats",permalink:"/es/security/components/cwtch/message_formats"},next:{title:"Groups",permalink:"/es/security/components/cwtch/groups"}},c={},l=[{value:"Verifying Key Bundles",id:"verifying-key-bundles",level:2}],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"key-bundles"},"Key Bundles"),(0,o.kt)("p",null,"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant."),(0,o.kt)("p",null,"At the time of writing, key bundles are expected to contain 3 keys:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"A Tor v3 Onion Service Public Key for the Token Board (ed25519)- used to connect to the service over Tor to post and receive messages."),(0,o.kt)("li",{parentName:"ol"},"A Tor v3 Onion Service Public Key for the Token Service (ed25519) - used to acquire tokens to post on the service via a small proof-of-work exercise."),(0,o.kt)("li",{parentName:"ol"},"A Privacy Pass Public Key - used in the token acquisition process (a ristretto curve point) . See: ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"OPTR2019-01"))),(0,o.kt)("p",null,"The key bundle is signed and can be verified via the first v3 onion service key, thus binding it to that particular oninon address."),(0,o.kt)("h2",{id:"verifying-key-bundles"},"Verifying Key Bundles"),(0,o.kt)("p",null,"Profiles who import server key bundles verify them using the following trust-on-first-use (TOFU) algorithm:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Verify the attached signature using the v3 onion address of the server. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"Check that every key type exists. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"If the profile has imported the server key bundle previously, assert that all the keys are the same. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"Save the keys to the servers contact entry.")),(0,o.kt)("p",null,"In the future this algorithm will likely be altered to allow the addition of new public keys (e.g. to allow tokens to be acquired via a Zcash address.)"),(0,o.kt)("p",null,'Technically, at steps (2) and (3() the server can be assumed to be malicious, having signed a valid key bundle that does not conform to the specifications. When groups are moved from "experimental" to "stable" such an action will result in a warning being communicated to the profile.'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/52564945.903c212a.js b/build-staging/es/assets/js/52564945.903c212a.js new file mode 100644 index 00000000..6c5bba87 --- /dev/null +++ b/build-staging/es/assets/js/52564945.903c212a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3787],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),s=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},c=function(e){var r=s(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},f=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),u=s(t),f=o,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||i;return t?n.createElement(m,a(a({ref:r},c),{},{components:t})):n.createElement(m,a({ref:r},c))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=f;var p={};for(var l in r)hasOwnProperty.call(r,l)&&(p[l]=r[l]);p.originalType=e,p[u]="string"==typeof e?e:o,a[1]=p;for(var s=2;s{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>s});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:11},a="Importar un perfil",p={unversionedId:"profiles/importing-a-profile",id:"profiles/importing-a-profile",title:"Importar un perfil",description:'1. Pulsa el bot\xf3n + en la esquina inferior derecha y selecciona "Importar perfil"',source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/importing-a-profile.md",sourceDirName:"profiles",slug:"/profiles/importing-a-profile",permalink:"/es/docs/profiles/importing-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/importing-a-profile.md",tags:[],version:"current",sidebarPosition:11,frontMatter:{sidebar_position:11},sidebar:"tutorialSidebar",previous:{title:"Copia de seguridad o Exportaci\xf3n de un perfil",permalink:"/es/docs/profiles/exporting-profile"},next:{title:"Setting Availability Status",permalink:"/es/docs/profiles/availability-status"}},l={},s=[],c={toc:s},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"importar-un-perfil"},"Importar un perfil"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Pulsa el bot\xf3n ",(0,o.kt)("inlineCode",{parentName:"li"},"+"),' en la esquina inferior derecha y selecciona "Importar perfil"'),(0,o.kt)("li",{parentName:"ol"},"Selecciona un ",(0,o.kt)("a",{parentName:"li",href:"/docs/profiles/exporting-profile"},"archivo de perfil exportado de Cwtch")," para importar"),(0,o.kt)("li",{parentName:"ol"},"Introduce la ",(0,o.kt)("a",{parentName:"li",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"contrase\xf1a")," asociada con el perfil y confirma.")),(0,o.kt)("p",null,"Una vez confirmado, Cwtch intentar\xe1 descifrar el archivo proporcionado usando una clave derivada de la contrase\xf1a dada. Si es exitoso el perfil aparecer\xe1 en la pantalla de Administraci\xf3n de Perfiles y estar\xe1 listo para usar."),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Aunque un perfil puede ser importado en varios dispositivos, actualmente s\xf3lo una versi\xf3n de un perfil puede estar en uso en todos los dispositivos a la vez."),(0,o.kt)("p",{parentName:"admonition"},"Los intentos de usar el mismo perfil en varios dispositivos puede resultar en problemas de disponibilidad y fallos de mensajer\xeda.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/53cc4802.3b1e644b.js b/build-staging/es/assets/js/53cc4802.3b1e644b.js new file mode 100644 index 00000000..d59ae9ba --- /dev/null +++ b/build-staging/es/assets/js/53cc4802.3b1e644b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7594],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,d=u["".concat(c,".").concat(m)]||u[m]||g[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/es/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"3 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"support",permalink:"/es/blog/tags/support"},{label:"testing",permalink:"/es/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/es/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/es/blog/cwtch-platform-support"}},c={authorsImageUrls:[void 0]},l=[],p={toc:l},u="wrapper";function g(e){let{components:t,...i}=e;return(0,a.kt)(u,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"We first ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,a.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/54611c16.3b0a29e1.js b/build-staging/es/assets/js/54611c16.3b0a29e1.js new file mode 100644 index 00000000..d44f8faf --- /dev/null +++ b/build-staging/es/assets/js/54611c16.3b0a29e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8031],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),d=o,m=u["".concat(s,".").concat(d)]||u[d]||f[d]||i;return n?r.createElement(m,a(a({ref:t},p),{},{components:n})):r.createElement(m,a({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},a="Contenido de notificaciones",c={unversionedId:"settings/behaviour/notification-content",id:"settings/behaviour/notification-content",title:"Contenido de notificaciones",description:"1. Ir a la configuraci\xf3n",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/behaviour/notification-content.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-content",permalink:"/es/docs/settings/behaviour/notification-content",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-content.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Pol\xedtica de notificaciones",permalink:"/es/docs/settings/behaviour/notification-policy"},next:{title:"Experiments",permalink:"/es/docs/category/experiments"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"contenido-de-notificaciones"},"Contenido de notificaciones"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ir a la configuraci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Desplazar a comportamiento"),(0,o.kt)("li",{parentName:"ol"},"El contenido de las notificaciones controla el contenido de las notificaciones",(0,o.kt)("ol",{parentName:"li"},(0,o.kt)("li",{parentName:"ol"},'Evento simple: "Nuevo mensaje" solamente'),(0,o.kt)("li",{parentName:"ol"},'Informaci\xf3n de la conversaci\xf3n: "Nuevo mensaje de XXXXX"')))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/559441ca.28bb5a71.js b/build-staging/es/assets/js/559441ca.28bb5a71.js new file mode 100644 index 00000000..65f4233a --- /dev/null +++ b/build-staging/es/assets/js/559441ca.28bb5a71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2682],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},l=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),p=u(n),m=a,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return n?r.createElement(f,c(c({ref:t},l),{},{components:n})):r.createElement(f,c({ref:t},l))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,c=new Array(o);c[0]=m;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:a,c[1]=i;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>u});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1},c="Una Introducci\xf3n al Chat P2P de Cwtch",i={unversionedId:"chat/introduction",id:"chat/introduction",title:"Una Introducci\xf3n al Chat P2P de Cwtch",description:"Cwtch usa los servicios Onion de Tor v3 para establecer conexiones an\xf3nimas, peer-to-peer entre Perfiles.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/introduction.md",sourceDirName:"chat",slug:"/chat/introduction",permalink:"/es/docs/chat/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Conversations",permalink:"/es/docs/category/conversations"},next:{title:"Starting a New Conversation",permalink:"/es/docs/chat/add-contact"}},s={},u=[{value:"C\xf3mo funciona el chat P2P",id:"c\xf3mo-funciona-el-chat-p2p",level:2}],l={toc:u},p="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(p,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"una-introducci\xf3n-al-chat-p2p-de-cwtch"},"Una Introducci\xf3n al Chat P2P de Cwtch"),(0,a.kt)("p",null,"Cwtch usa los servicios Onion de Tor v3 para establecer conexiones an\xf3nimas, peer-to-peer entre Perfiles."),(0,a.kt)("h2",{id:"c\xf3mo-funciona-el-chat-p2p"},"C\xf3mo funciona el chat P2P"),(0,a.kt)("p",null,"Para poder chatear con tus amigos en una conversaci\xf3n peer-to-peer, ambos deben estar en l\xednea."),(0,a.kt)("p",null,"Despu\xe9s de una conexi\xf3n exitosa, ambas partes participan en un ",(0,a.kt)("strong",{parentName:"p"},"protocolo de autenticaci\xf3n")," que:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Verifica que cada parte tenga acceso a la clave privada asociada a su identidad p\xfablica."),(0,a.kt)("li",{parentName:"ul"},"Genera una clave de sesi\xf3n ef\xedmera usada para cifrar toda comunicaci\xf3n durante la sesi\xf3n.")),(0,a.kt)("p",null,"Este intercambio (documentado con m\xe1s detalle en ",(0,a.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/authentication_protocol.html"},"protocolo de autenticaci\xf3n"),") es ",(0,a.kt)("em",{parentName:"p"},"negable fuera de l\xednea")," i.e. es posible que cualquier parte forje transcripciones de este intercambio de protocolo despu\xe9s del hecho, y como tal - despu\xe9s del hecho - es imposible demostrar definitivamente que el intercambio ha ocurrido en absoluto."),(0,a.kt)("p",null,"Una vez que el proceso de autenticaci\xf3n haya tenido \xe9xito, tanto tu como tu contacto pueden comunicarse con la certeza de que nadie m\xe1s puede aprender nada sobre el contenido o los metadatos de su conversaci\xf3n."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5beee875.33a0527e.js b/build-staging/es/assets/js/5beee875.33a0527e.js new file mode 100644 index 00000000..bb3a5e39 --- /dev/null +++ b/build-staging/es/assets/js/5beee875.33a0527e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9444],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),s=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(n),m=r,g=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return n?a.createElement(g,i(i({ref:t},p),{},{components:n})):a.createElement(g,i({ref:t},p))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var a=n(7462),r=(n(7294),n(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"7 de junio de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/es/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/es/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/es/blog/cwtch-developer-documentation"}},c={authorsImageUrls:[void 0]},s=[{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,a.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,r.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(9964).Z,width:"1005",height:"481"})),(0,r.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,r.kt)("p",null,"There is a ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,r.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/"},"2023-06-05-17-36-v1.11.0-74-g0406"),"."),(0,r.kt)("p",null,"This version has a large number of improvements and bug fixes including:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A new Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor."),(0,r.kt)("li",{parentName:"ul"},"Updated UI font styles"),(0,r.kt)("li",{parentName:"ul"},"Dependency updates, including a new base of Flutter 3.10."),(0,r.kt)("li",{parentName:"ul"},"A fix for stuck file downloading notifications on Android"),(0,r.kt)("li",{parentName:"ul"},"A fix for missing profile images in certain edge cases on Android"),(0,r.kt)("li",{parentName:"ul"},"Japanese, Swedish, and Swahili translation options"),(0,r.kt)("li",{parentName:"ul"},"A new retry peer connection button for prompting Cwtch to prioritize specific connections"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails support"))),(0,r.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9964:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5ca95110.39e04a7f.js b/build-staging/es/assets/js/5ca95110.39e04a7f.js new file mode 100644 index 00000000..89b5b2f9 --- /dev/null +++ b/build-staging/es/assets/js/5ca95110.39e04a7f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1121],{4680:e=>{e.exports=JSON.parse('{"label":"developer-documentation","permalink":"/es/blog/tags/developer-documentation","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5cb298ca.39a0ae85.js b/build-staging/es/assets/js/5cb298ca.39a0ae85.js new file mode 100644 index 00000000..8f5c1dbc --- /dev/null +++ b/build-staging/es/assets/js/5cb298ca.39a0ae85.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2909],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),s=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),h=s(r),m=n,d=h["".concat(l,".").concat(m)]||h[m]||u[m]||o;return r?a.createElement(d,i(i({ref:t},p),{},{components:r})):a.createElement(d,i({ref:t},p))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var a=r(7462),n=(r(7294),r(3905));const o={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/es/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"28 de abril de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/es/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/es/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/es/blog/availability-status-profile-attributes"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5dc151e9.56486496.js b/build-staging/es/assets/js/5dc151e9.56486496.js new file mode 100644 index 00000000..12ac1661 --- /dev/null +++ b/build-staging/es/assets/js/5dc151e9.56486496.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[923],{3905:(t,e,a)=>{a.d(e,{Zo:()=>s,kt:()=>g});var r=a(7294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,r)}return a}function i(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var d=r.createContext({}),p=function(t){var e=r.useContext(d),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},s=function(t){var e=p(t.components);return r.createElement(d.Provider,{value:e},t.children)},u="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},m=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,l=t.originalType,d=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(a),m=n,g=u["".concat(d,".").concat(m)]||u[m]||c[m]||l;return a?r.createElement(g,i(i({ref:e},s),{},{components:a})):r.createElement(g,i({ref:e},s))}));function g(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var d in e)hasOwnProperty.call(e,d)&&(o[d]=e[d]);o.originalType=t,o[u]="string"==typeof t?t:n,i[1]=o;for(var p=2;p{a.r(e),a.d(e,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const l={sidebar_position:1},i="Release and Packaging Process",o={unversionedId:"release",id:"release",title:"Release and Packaging Process",description:"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.",source:"@site/developing/release.md",sourceDirName:".",slug:"/release",permalink:"/es/developing/release",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Introduction to Cwtch Development",permalink:"/es/developing/intro"},next:{title:"Building a Cwtch App",permalink:"/es/developing/category/building-a-cwtch-app"}},d={},p=[{value:"Automated Testing",id:"automated-testing",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"UI Nightly Builds",id:"ui-nightly-builds",level:2},{value:"Official Releases",id:"official-releases",level:2},{value:"Reproducible Builds",id:"reproducible-builds",level:3}],s={toc:p},u="wrapper";function c(t){let{components:e,...a}=t;return(0,n.kt)(u,(0,r.Z)({},s,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member."),(0,n.kt)("h2",{id:"automated-testing"},"Automated Testing"),(0,n.kt)("p",null,"Drone carries out a suite of automated tests at various stages of the release pipeline."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Test Suite"),(0,n.kt)("th",{parentName:"tr",align:null},"Repository"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"A full exercise of peer-to-peer and group messaging")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"File Sharing Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that file sharing and image downloading work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Automated Download Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that automated image downloading (e.g. profile pictures) work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"UI Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch-ui"),(0,n.kt)("td",{parentName:"tr",align:null},"A suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings")))),(0,n.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,n.kt)("p",null,"Drone produces the following build artifacts for all Cwtch autobindings builds."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch-sources.jar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"gomobile derived source code for the Android Cwtch library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch.aar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android Cwtch library. Supports arm, arm64, and amd64.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.so"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.dll"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 bit shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.arm64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"Arm64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.x64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")))),(0,n.kt)("h2",{id:"ui-nightly-builds"},"UI Nightly Builds"),(0,n.kt)("p",null,"We make unreleased versions of Cwtch available for testing as ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"Cwtch Nightlies"),"."),(0,n.kt)("p",null,"Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.apk"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Supports arm, arm64, and amd64. Can be sideloaded.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.aab"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android App Bundle for publishing to appstores")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Cwtch-VERSION.dmg"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.tar.gz"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"Contains the code, libs, and assets in addition to install scripts for various devices")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.zip"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-installer-VERSION.exe"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"NSIS powered installation wizard")))),(0,n.kt)("p",null,"Nightly builds are regularly purged from the system"),(0,n.kt)("h2",{id:"official-releases"},"Official Releases"),(0,n.kt)("p",null,"The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps."),(0,n.kt)("p",null,"When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. ",(0,n.kt)("inlineCode",{parentName:"p"},"v.1.12.0"),". The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder."),(0,n.kt)("h3",{id:"reproducible-builds"},"Reproducible Builds"),(0,n.kt)("p",null,"We use ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate")," to provide ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"reproducible build scripts for Cwtch"),"."),(0,n.kt)("p",null,"We update the ",(0,n.kt)("inlineCode",{parentName:"p"},"repliqate-scripts")," repository with scripts for all official releases. Currently only Cwtch bindings are reproducible"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5e5faacc.34927fd8.js b/build-staging/es/assets/js/5e5faacc.34927fd8.js new file mode 100644 index 00000000..f14f6eb3 --- /dev/null +++ b/build-staging/es/assets/js/5e5faacc.34927fd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8192],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>h});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function o(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function l(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=n.createContext({}),p=function(t){var e=n.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},u=function(t){var e=p(t.components);return n.createElement(s.Provider,{value:e},t.children)},d="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,o=t.originalType,s=t.parentName,u=i(t,["components","mdxType","originalType","parentName"]),d=p(a),m=r,h=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return a?n.createElement(h,l(l({ref:e},u),{},{components:a})):n.createElement(h,l({ref:e},u))}));function h(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var o=a.length,l=new Array(o);l[0]=m;var i={};for(var s in e)hasOwnProperty.call(e,s)&&(i[s]=e[s]);i.originalType=t,i[d]="string"==typeof t?t:r,l[1]=i;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const o={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/es/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"27 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"support",permalink:"/es/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/es/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/es/blog/cwtch-bindings-reproducible"}},s={authorsImageUrls:[void 0]},p=[{value:"Constraints on support",id:"constraints-on-support",level:2},{value:"Limitations on general-purpose computing",id:"limitations-on-general-purpose-computing",level:3},{value:"Constraints introduced by the Flutter SDK",id:"constraints-introduced-by-the-flutter-sdk",level:3},{value:"Constraints introduced by Appstore Policy",id:"constraints-introduced-by-appstore-policy",level:3},{value:"CPU Architecture and Cwtch Bindings",id:"cpu-architecture-and-cwtch-bindings",level:3},{value:"Testing and official support",id:"testing-and-official-support",level:3},{value:"End-of-life platforms",id:"end-of-life-platforms",level:3},{value:"How we decide to officially support a platform",id:"how-we-decide-to-officially-support-a-platform",level:2},{value:"Summary of official support",id:"summary-of-official-support",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},d="wrapper";function c(t){let{components:e,...o}=t;return(0,r.kt)(d,(0,n.Z)({},u,o,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"One of the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,r.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,r.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,r.kt)("p",null,"The questions we aim to answer in this post are: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,r.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,r.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,r.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,r.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6149).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraints-on-support"},"Constraints on support"),(0,r.kt)("p",null,"From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. "),(0,r.kt)("p",null,"In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms."),(0,r.kt)("h3",{id:"limitations-on-general-purpose-computing"},"Limitations on general-purpose computing"),(0,r.kt)("p",null,"In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to ",(0,r.kt)("em",{parentName:"p"},"other")," onion services). "),(0,r.kt)("p",null,"On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, ",(0,r.kt)("strong",{parentName:"p"},"blocked entirely"),". "),(0,r.kt)("p",null,"This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind."),(0,r.kt)("p",null,"While we expect that ",(0,r.kt)("a",{parentName:"p",href:"https://gitlab.torproject.org/tpo/core/arti"},"Arti")," will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. "),(0,r.kt)("p",null,"As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable."),(0,r.kt)("p",null,"We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device."),(0,r.kt)("h3",{id:"constraints-introduced-by-the-flutter-sdk"},"Constraints introduced by the Flutter SDK"),(0,r.kt)("p",null,"The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms"},"platforms that are supported by the Flutter SDK"),"."),(0,r.kt)("p",null,"To summarize, as of writing this document those platforms are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Android API 16 and above (arm, arm64, and amd64)"),(0,r.kt)("li",{parentName:"ul"},"Debian-based Linux Distributions (64-bit only)"),(0,r.kt)("li",{parentName:"ul"},"macOS El Capitan (10.11) and above"),(0,r.kt)("li",{parentName:"ul"},"Windows 7 & above (64-bit only)")),(0,r.kt)("p",null,"To put it plainly, without porting Cwtch UI to a different UI platform ",(0,r.kt)("strong",{parentName:"p"},"we cannot support a 32-bit desktop version"),"."),(0,r.kt)("h3",{id:"constraints-introduced-by-appstore-policy"},"Constraints introduced by Appstore Policy"),(0,r.kt)("p",null,"As of writing, ",(0,r.kt)("a",{parentName:"p",href:"https://developer.android.com/google/play/requirements/target-sdk"},"Google is pushing applications to target API 31 or above"),". This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality."),(0,r.kt)("h3",{id:"cpu-architecture-and-cwtch-bindings"},"CPU Architecture and Cwtch Bindings"),(0,r.kt)("p",null,"We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for."),(0,r.kt)("p",null,"It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Architecture / Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Windows"),(0,r.kt)("th",{parentName:"tr",align:null},"Linux"),(0,r.kt)("th",{parentName:"tr",align:null},"macOS"),(0,r.kt)("th",{parentName:"tr",align:null},"Android"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"x86-64 / amd64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")))),(0,r.kt)("p",null,'"\ud83d\udfe1" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).'),(0,r.kt)("h3",{id:"testing-and-official-support"},"Testing and official support"),(0,r.kt)("p",null,"As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers")," to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues."),(0,r.kt)("p",null,"We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances."),(0,r.kt)("h3",{id:"end-of-life-platforms"},"End-of-life platforms"),(0,r.kt)("p",null,"Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. ",(0,r.kt)("a",{parentName:"p",href:"https://www.microsoft.com/en-us/windows/end-of-support"},"Windows 7 fell out of support on January 14, 2020"),", Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025."),(0,r.kt)("p",null,"Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also."),(0,r.kt)("p",null,"The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations"},"Cwtch currently requires libc 2.31+"),"."),(0,r.kt)("p",null,"Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers groups")," to help us understand the limitations of Android support across different API versions."),(0,r.kt)("h2",{id:"how-we-decide-to-officially-support-a-platform"},"How we decide to officially support a platform"),(0,r.kt)("p",null,"To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform needs to be officially supported by our development tools")," - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target operating system needs to be supported by the Vendor")," - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform must be backwards compatible with the most recent version in general use")," - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch ",(0,r.kt)("em",{parentName:"li"},"may")," run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"People want to use Cwtch on that platform")," - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!")),(0,r.kt)("h2",{id:"summary-of-official-support"},"Summary of official support"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). "),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. A version of this table will be ",(0,r.kt)("a",{parentName:"p",href:"/docs/getting-started/supported_platforms"},"maintained as part of the Cwtch Handbook"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607"},"Known Issues. Specific changes to Cwtch are required for support."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}c.isMDXComponent=!0},6149:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5ec66a01.debca232.js b/build-staging/es/assets/js/5ec66a01.debca232.js new file mode 100644 index 00000000..888f4b13 --- /dev/null +++ b/build-staging/es/assets/js/5ec66a01.debca232.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3441],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>b});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},l=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},f=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,s=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),p=u(n),f=r,b=p["".concat(s,".").concat(f)]||p[f]||d[f]||a;return n?o.createElement(b,c(c({ref:t},l),{},{components:n})):o.createElement(b,c({ref:t},l))}));function b(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,c=new Array(a);c[0]=f;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[p]="string"==typeof e?e:r,c[1]=i;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var o=n(7462),r=(n(7294),n(3905));const a={sidebar_position:1},c="Bloquear Conexiones Desconocidas",i={unversionedId:"settings/behaviour/block-unknown-connections",id:"settings/behaviour/block-unknown-connections",title:"Bloquear Conexiones Desconocidas",description:"By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. Puede cambiar este comportamiento a trav\xe9s de la configuraci\xf3n de Bloquear Conexiones Desconocidas.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/behaviour/block-unknown-connections.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/block-unknown-connections",permalink:"/es/docs/settings/behaviour/block-unknown-connections",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/block-unknown-connections.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Behaviour",permalink:"/es/docs/category/behaviour"},next:{title:"Pol\xedtica de notificaciones",permalink:"/es/docs/settings/behaviour/notification-policy"}},s={},u=[],l={toc:u},p="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"bloquear-conexiones-desconocidas"},"Bloquear Conexiones Desconocidas"),(0,r.kt)("p",null,"By default, Cwtch interprets connections from unknown Cwtch addresses as ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/chat/accept-deny-new-conversation"},"Contact Requests"),". Puede cambiar este comportamiento a trav\xe9s de la configuraci\xf3n de Bloquear Conexiones Desconocidas."),(0,r.kt)("p",null,"Si est\xe1 activado, Cwtch cerrar\xe1 autom\xe1ticamente todas las conexiones de las direcciones de Cwtch que no has a\xf1adido a tu lista de contactos. This will prevent people who have your Cwtch address from contacting you unless you also add them."),(0,r.kt)("p",null,"Para habilitar:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Ve a la Configuraci\xf3n"),(0,r.kt)("li",{parentName:"ol"},"Habilita Bloquear Contactos Desconocidos")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/5f8a68fd.555ac856.js b/build-staging/es/assets/js/5f8a68fd.555ac856.js new file mode 100644 index 00000000..3e3a1951 --- /dev/null +++ b/build-staging/es/assets/js/5f8a68fd.555ac856.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4138],{2595:e=>{e.exports=JSON.parse('{"title":"Conversations","slug":"/category/conversations","permalink":"/es/docs/category/conversations","navigation":{"previous":{"title":"Setting Profile Attributes","permalink":"/es/docs/profiles/profile-info"},"next":{"title":"Una Introducci\xf3n al Chat P2P de Cwtch","permalink":"/es/docs/chat/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6048.e7c7c18a.js b/build-staging/es/assets/js/6048.e7c7c18a.js new file mode 100644 index 00000000..bac03d84 --- /dev/null +++ b/build-staging/es/assets/js/6048.e7c7c18a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6048],{9058:(e,t,a)=>{a.d(t,{Z:()=>p});var l=a(7294),r=a(6010),n=a(7961),o=a(7524),s=a(9960),i=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function c(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,i.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function d(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function g(e){return l.createElement(u.Zo,{component:d,props:e})}function h(e){let{sidebar:t}=e;const a=(0,o.i)();return t?.items.length?"mobile"===a?l.createElement(g,{sidebar:t}):l.createElement(c,{sidebar:t}):null}function p(e){const{sidebar:t,toc:a,children:o,...s}=e,i=t&&t.items.length>0;return l.createElement(n.Z,s,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(h,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":i,"col--9 col--offset-1":!i}),itemScope:!0,itemType:"http://schema.org/Blog"},o),a&&l.createElement("div",{className:"col col--2"},a))))}},390:(e,t,a)=>{a.d(t,{Z:()=>A});var l=a(7294),r=a(6010),n=a(9460),o=a(4996);function s(e){let{children:t,className:a}=e;const{frontMatter:r,assets:s}=(0,n.C)(),{withBaseUrl:i}=(0,o.C)(),m=s.image??r.image;return l.createElement("article",{className:a,itemProp:"blogPost",itemScope:!0,itemType:"http://schema.org/BlogPosting"},m&&l.createElement("meta",{itemProp:"image",content:i(m,{absolute:!0})}),t)}var i=a(9960);const m={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,n.C)(),{permalink:s,title:c}=a,u=o?"h1":"h2";return l.createElement(u,{className:(0,r.Z)(m.title,t),itemProp:"headline"},o?c:l.createElement(i.Z,{itemProp:"url",to:s},c))}var u=a(5999),d=a(8824);const g={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,d.c)();return t=>{const a=Math.ceil(t);return e(a,(0,u.I)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return l.createElement(l.Fragment,null,a(t))}function p(e){let{date:t,formattedDate:a}=e;return l.createElement("time",{dateTime:t,itemProp:"datePublished"},a)}function b(){return l.createElement(l.Fragment,null," \xb7 ")}function E(e){let{className:t}=e;const{metadata:a}=(0,n.C)(),{date:o,formattedDate:s,readingTime:i}=a;return l.createElement("div",{className:(0,r.Z)(g.container,"margin-vert--md",t)},l.createElement(p,{date:o,formattedDate:s}),void 0!==i&&l.createElement(l.Fragment,null,l.createElement(b,null),l.createElement(h,{readingTime:i})))}function f(e){return e.href?l.createElement(i.Z,e):l.createElement(l.Fragment,null,e.children)}function v(e){let{author:t,className:a}=e;const{name:n,title:o,url:s,imageURL:i,email:m}=t,c=s||m&&`mailto:${m}`||void 0;return l.createElement("div",{className:(0,r.Z)("avatar margin-bottom--sm",a)},i&&l.createElement(f,{href:c,className:"avatar__photo-link"},l.createElement("img",{className:"avatar__photo",src:i,alt:n})),n&&l.createElement("div",{className:"avatar__intro",itemProp:"author",itemScope:!0,itemType:"https://schema.org/Person"},l.createElement("div",{className:"avatar__name"},l.createElement(f,{href:c,itemProp:"url"},l.createElement("span",{itemProp:"name"},n))),o&&l.createElement("small",{className:"avatar__subtitle",itemProp:"description"},o)))}const P={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function N(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,n.C)();if(0===a.length)return null;const s=a.every((e=>{let{name:t}=e;return!t}));return l.createElement("div",{className:(0,r.Z)("margin-top--md margin-bottom--sm",s?P.imageOnlyAuthorRow:"row",t)},a.map(((e,t)=>l.createElement("div",{className:(0,r.Z)(!s&&"col col--6",s?P.imageOnlyAuthorCol:P.authorCol),key:t},l.createElement(v,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})))))}function _(){return l.createElement("header",null,l.createElement(c,null),l.createElement(E,null),l.createElement(N,null))}var k=a(8780),Z=a(1506);function I(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,n.C)();return l.createElement("div",{id:o?k.blogPostContainerID:void 0,className:(0,r.Z)("markdown",a),itemProp:"articleBody"},l.createElement(Z.Z,null,t))}var C=a(4881),w=a(1526),T=a(7462);function y(){return l.createElement("b",null,l.createElement(u.Z,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts"},"Read More"))}function F(e){const{blogPostTitle:t,...a}=e;return l.createElement(i.Z,(0,T.Z)({"aria-label":(0,u.I)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t})},a),l.createElement(y,null))}const L={blogPostFooterDetailsFull:"blogPostFooterDetailsFull_mRVl"};function B(){const{metadata:e,isBlogPostPage:t}=(0,n.C)(),{tags:a,title:o,editUrl:s,hasTruncateMarker:i}=e,m=!t&&i,c=a.length>0;return c||m||s?l.createElement("footer",{className:(0,r.Z)("row docusaurus-mt-lg",t&&L.blogPostFooterDetailsFull)},c&&l.createElement("div",{className:(0,r.Z)("col",{"col--9":m})},l.createElement(w.Z,{tags:a})),t&&s&&l.createElement("div",{className:"col margin-top--sm"},l.createElement(C.Z,{editUrl:s})),m&&l.createElement("div",{className:(0,r.Z)("col text--right",{"col--3":c})},l.createElement(F,{blogPostTitle:o,to:e.permalink}))):null}function A(e){let{children:t,className:a}=e;const o=function(){const{isBlogPostPage:e}=(0,n.C)();return e?void 0:"margin-bottom--xl"}();return l.createElement(s,{className:(0,r.Z)(o,a)},l.createElement(_,null),l.createElement(I,null,t),l.createElement(B,null))}},9460:(e,t,a)=>{a.d(t,{C:()=>s,n:()=>o});var l=a(7294),r=a(902);const n=l.createContext(null);function o(e){let{children:t,content:a,isBlogPostPage:r=!1}=e;const o=function(e){let{content:t,isBlogPostPage:a}=e;return(0,l.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:r});return l.createElement(n.Provider,{value:o},t)}function s(){const e=(0,l.useContext)(n);if(null===e)throw new r.i6("BlogPostProvider");return e}},8824:(e,t,a)=>{a.d(t,{c:()=>m});var l=a(7294),r=a(2263);const n=["zero","one","two","few","many","other"];function o(e){return n.filter((t=>e.includes(t)))}const s={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function i(){const{i18n:{currentLocale:e}}=(0,r.Z)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:o(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),s}}),[e])}function m(){const e=i();return{selectMessage:(t,a)=>function(e,t,a){const l=e.split("|");if(1===l.length)return l[0];l.length>a.pluralForms.length&&console.error(`For locale=${a.locale}, a maximum of ${a.pluralForms.length} plural forms are expected (${a.pluralForms.join(",")}), but the message contains ${l.length}: ${e}`);const r=a.select(t),n=a.pluralForms.indexOf(r);return l[Math.min(n,l.length-1)]}(a,t,e)}}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/60846aee.1180f6f5.js b/build-staging/es/assets/js/60846aee.1180f6f5.js new file mode 100644 index 00000000..49a014cc --- /dev/null +++ b/build-staging/es/assets/js/60846aee.1180f6f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3337],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||a;return n?i.createElement(h,o(o({ref:t},u),{},{components:n})):i.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,o=new Array(a);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var i=n(7462),r=(n(7294),n(3905));const a={},o="Image Previews",s={unversionedId:"components/ui/image_previews",id:"components/ui/image_previews",title:"Image Previews",description:"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/image_previews.md",sourceDirName:"components/ui",slug:"/components/ui/image_previews",permalink:"/es/security/components/ui/image_previews",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Android Service",permalink:"/es/security/components/ui/android"},next:{title:"Input",permalink:"/es/security/components/ui/input"}},l={},c=[{value:"KnownRisks",id:"knownrisks",level:2},{value:"Other Applications and/or the OS Inferring Information from Images",id:"other-applications-andor-the-os-inferring-information-from-images",level:2},{value:"Malicious Images Crashing or otherwise Compromising Cwtch",id:"malicious-images--crashing-or-otherwise-compromising-cwtch",level:2},{value:"Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata",id:"malicious-images-rendering-differently-on-different-platforms-potentially-exposing-metadata",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"image-previews"},"Image Previews"),(0,r.kt)("p",null,"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes."),(0,r.kt)("p",null,"For now, we only support single-image messages, and any image editing/cropping will have to be done in a separate application. As we mention in the filesharing FAQ, image files also frequently contain significant hidden metadata, and you should only share them with people you trust."),(0,r.kt)("h2",{id:"knownrisks"},"KnownRisks"),(0,r.kt)("h2",{id:"other-applications-andor-the-os-inferring-information-from-images"},"Other Applications and/or the OS Inferring Information from Images"),(0,r.kt)("p",null,"Images must be stored somewhere, and for now we have chosen to store them unencrypted on the file system. We have done this for 2 reasons:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"In order to support more powerful file sharing schemes like rehosting we require the ability to efficiently scan files and deliver chunks - doing this through an encrypted database layer would harm performance."),(0,r.kt)("li",{parentName:"ol"},"This information always has to transit the application boundary (either via display drivers, or storing and viewing the file in an external application) - there is nothing that Cwtch can do after that point in any case.")),(0,r.kt)("h2",{id:"malicious-images--crashing-or-otherwise-compromising-cwtch"},"Malicious Images Crashing or otherwise Compromising Cwtch"),(0,r.kt)("p",null,"Flutter uses Skia to render Images. While the underlying code is memory unsafe, it is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/google/skia/tree/main/fuzz"},"extensively fuzzed")," as part of regular development."),(0,r.kt)("p",null,"We also conduct our own fuzz testing of Cwtch components. In that analysis we found a single crash bug related to a malformed GIF file that caused the renderer to allocate a ridiculous amount of memory (and eventually be refused by the kernel). To prevent this from impacting Cwtch we have adopted the policy of always enabling a maximum ",(0,r.kt)("inlineCode",{parentName:"p"},"cacheWidth")," and/or ",(0,r.kt)("inlineCode",{parentName:"p"},"cacheHeight")," for Image widgets."),(0,r.kt)("h2",{id:"malicious-images-rendering-differently-on-different-platforms-potentially-exposing-metadata"},"Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata"),(0,r.kt)("p",null,"Recently ",(0,r.kt)("a",{parentName:"p",href:"https://www.da.vidbuchanan.co.uk/widgets/pngdiff/"},"a bug was found in Apple's png parser")," which would cause an image to render differently on Apple devices as it would on non-Apple devices."),(0,r.kt)("p",null,"We conducted a few tests on our Mac builds and could not replicate this issue for Flutter (because all Flutter builds use Skia for rendering), however we will continue to include such cases in our testing corpus."),(0,r.kt)("p",null,"For now image previews will remain experimental and opt-in."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/61794344.a3bb40cb.js b/build-staging/es/assets/js/61794344.a3bb40cb.js new file mode 100644 index 00000000..9445226e --- /dev/null +++ b/build-staging/es/assets/js/61794344.a3bb40cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6232],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(a),u=o,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||r;return a?n.createElement(m,i(i({ref:t},p),{},{components:a})):n.createElement(m,i({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"30 de junio de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/es/blog/cwtch-nightly-1-12"}},s={authorsImageUrls:[void 0]},c=[{value:"Update on the Cwtch Stable Roadmap",id:"update-on-the-cwtch-stable-roadmap",level:2},{value:"Next Steps, Refinements, Additional Work",id:"next-steps-refinements-additional-work",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(h,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,o.kt)("p",null,"This post ",(0,o.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h2",{id:"update-on-the-cwtch-stable-roadmap"},"Update on the Cwtch Stable Roadmap"),(0,o.kt)("p",null,"Back in March we extended and updated several goals from ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"our January roadmap")," that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing."),(0,o.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/#official-releases"},"Release Process")),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/"},"Packaging Documentation")),(0,o.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new ",(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"documentation style guide"),", and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/category/building-a-cwtch-app"},"Building a Cwtch App")),(0,o.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. "))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"An implementation of ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")," \ud83d\udfe1 - currently in ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518"},"active development")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information \u2705 - released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")),(0,o.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")," \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12"),". We now believe these changes will be complete in Cwtch Beta 1.13."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks."),(0,o.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below)."),(0,o.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,o.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")," \ud83d\udfe1 - we have already launched an environment for testing ",(0,o.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails"),". Other platforms are underway."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable."),(0,o.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,o.kt)("h2",{id:"next-steps-refinements-additional-work"},"Next Steps, Refinements, Additional Work"),(0,o.kt)("p",null,"As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. "),(0,o.kt)("p",null,"Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like."),(0,o.kt)("p",null,"However, ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")," featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing."),(0,o.kt)("p",null,"The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup."),(0,o.kt)("p",null,"We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards."),(0,o.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,o.kt)("h2",{id:"get-involved"},"Get Involved"),(0,o.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,o.kt)("p",null,"We also also updated our guides on ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,o.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,o.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,o.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/618f3057.e0c71e08.js b/build-staging/es/assets/js/618f3057.e0c71e08.js new file mode 100644 index 00000000..1a04c5f2 --- /dev/null +++ b/build-staging/es/assets/js/618f3057.e0c71e08.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[433],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},m=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},l="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),l=p(n),d=o,f=l["".concat(c,".").concat(d)]||l[d]||u[d]||s;return n?r.createElement(f,a(a({ref:t},m),{},{components:n})):r.createElement(f,a({ref:t},m))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,a=new Array(s);a[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[l]="string"==typeof e?e:o,a[1]=i;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const s={sidebar_position:6},a="Formato de mensajes",i={unversionedId:"settings/experiments/message-formatting",id:"settings/experiments/message-formatting",title:"Formato de mensajes",description:"When enabled, this experiment changes the conversation compose box to add message formatting UX.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/message-formatting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/message-formatting",permalink:"/es/docs/settings/experiments/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/message-formatting.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Experimento de Enlaces Cliqueables",permalink:"/es/docs/settings/experiments/clickable-links"},next:{title:"QR Codes",permalink:"/es/docs/settings/experiments/qrcodes"}},c={},p=[],m={toc:p},l="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"formato-de-mensajes"},"Formato de mensajes"),(0,o.kt)("p",null,"When enabled, this experiment changes the conversation compose box to add ",(0,o.kt)("a",{parentName:"p",href:"/docs/chat/message-formatting"},"message formatting")," UX."),(0,o.kt)("p",null,"This experiment is now enabled by default."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6275ceb4.12fa173d.js b/build-staging/es/assets/js/6275ceb4.12fa173d.js new file mode 100644 index 00000000..12486efc --- /dev/null +++ b/build-staging/es/assets/js/6275ceb4.12fa173d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6555],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),u=a,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||r;return n?o.createElement(m,i(i({ref:t},p),{},{components:n})):o.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,i[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const r={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"10 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/es/blog/tags/documentation"},{label:"security-handbook",permalink:"/es/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/es/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/es/blog/autobindings-ii"}},s={authorsImageUrls:[void 0]},c=[{value:"Cwtch Secure Development Handbook",id:"cwtch-secure-development-handbook",level:2},{value:"Volunteer Development",id:"volunteer-development",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(h,(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"cwtch-secure-development-handbook"},"Cwtch Secure Development Handbook"),(0,a.kt)("p",null,"One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions."),(0,a.kt)("p",null,"We have ",(0,a.kt)("a",{parentName:"p",href:"/security/intro"},"now ported the the handbook to this documentation site"),", along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. "),(0,a.kt)("h2",{id:"volunteer-development"},"Volunteer Development"),(0,a.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,a.kt)("p",null,"We also also updated our guides on ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,a.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,a.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"We still have more work to do on the documentation front:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Ensuring all pages ",(0,a.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"implement the new documentation style guide"),", and include appropriate screenshots and descriptions."),(0,a.kt)("li",{parentName:"ul"},"Expanding the security handbook to provide information on ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"reproducible builds"),", ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"the new Cwtch Stable API")," and upcoming improvements around fuzz testing."),(0,a.kt)("li",{parentName:"ul"},"Creating new documentation sections on the ",(0,a.kt)("a",{parentName:"li",href:"/blog/autobindings"},"libCwtch autobindings API")," and building applications on top of Cwtch.")),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/64fc8eaf.809fa82d.js b/build-staging/es/assets/js/64fc8eaf.809fa82d.js new file mode 100644 index 00000000..952b9ed2 --- /dev/null +++ b/build-staging/es/assets/js/64fc8eaf.809fa82d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2858],{3367:s=>{s.exports=JSON.parse('{"label":"nightly","permalink":"/es/blog/tags/nightly","allTagsPath":"/es/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/652ba846.266e344c.js b/build-staging/es/assets/js/652ba846.266e344c.js new file mode 100644 index 00000000..52830f03 --- /dev/null +++ b/build-staging/es/assets/js/652ba846.266e344c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4679],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),g=o,d=u["".concat(c,".").concat(g)]||u[g]||f[g]||a;return n?r.createElement(d,i(i({ref:t},p),{},{components:n})):r.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>f,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:5},i="Accessing Conversation Settings",s={unversionedId:"chat/conversation-settings",id:"chat/conversation-settings",title:"Accessing Conversation Settings",description:"In a conversation window, click on the Settings icon in the top bar.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/conversation-settings.md",sourceDirName:"chat",slug:"/chat/conversation-settings",permalink:"/es/docs/chat/conversation-settings",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/conversation-settings.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Formato de mensajes",permalink:"/es/docs/chat/message-formatting"},next:{title:"Contestar a un mensaje",permalink:"/es/docs/chat/reply-to-message"}},c={},l=[],p={toc:l},u="wrapper";function f(e){let{components:t,...a}=e;return(0,o.kt)(u,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accessing-conversation-settings"},"Accessing Conversation Settings"),(0,o.kt)("p",null,"In a conversation window, click on the Settings icon in the top bar."),(0,o.kt)("figure",null,(0,o.kt)("p",null,(0,o.kt)("a",{target:"_blank",href:n(671).Z},(0,o.kt)("img",{src:n(6305).Z,width:"624",height:"257"}))),(0,o.kt)("figcaption",null)),(0,o.kt)("p",null,"This action will open up a new screen where you can view and manage the contact."),(0,o.kt)("figure",null,(0,o.kt)("p",null,(0,o.kt)("a",{target:"_blank",href:n(4306).Z},(0,o.kt)("img",{src:n(2289).Z,width:"937",height:"689"}))),(0,o.kt)("figcaption",null)))}f.isMDXComponent=!0},4306:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png"},671:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png"},2289:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png"},6305:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/66cb26f4.04618bc5.js b/build-staging/es/assets/js/66cb26f4.04618bc5.js new file mode 100644 index 00000000..ad3995d6 --- /dev/null +++ b/build-staging/es/assets/js/66cb26f4.04618bc5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9453],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,h=u["".concat(c,".").concat(d)]||u[d]||m[d]||i;return n?r.createElement(h,a(a({ref:t},l),{},{components:n})):r.createElement(h,a({ref:t},l))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={},a="Input",s={unversionedId:"components/ui/input",id:"components/ui/input",title:"Input",description:"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/input.md",sourceDirName:"components/ui",slug:"/components/ui/input",permalink:"/es/security/components/ui/input",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Image Previews",permalink:"/es/security/components/ui/image_previews"},next:{title:"Message Overlays",permalink:"/es/security/components/ui/overlays"}},c={},p=[{value:"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices",id:"risk-interception-of-cwtch-content-or-metadata-through-an-ime-on-mobile-devices",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"input"},"Input"),(0,o.kt)("h2",{id:"risk-interception-of-cwtch-content-or-metadata-through-an-ime-on-mobile-devices"},"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")),(0,o.kt)("p",null,"Any component that has the potential to intercept data between a person, and the Cwtch app is a potential security risk."),(0,o.kt)("p",null,"One of the most likely interceptors is a 3rd party IME (Input Method Editor) commonly used by people to generate characters not natively supported by their device."),(0,o.kt)("p",null,"Even benign and stock IME apps may unintentionally leak information about the contents of a persons message e.g. through cloud synchronization, cloud translation or personal dictionaries."),(0,o.kt)("p",null,"Ultimately, this problem cannot be solved by Cwtch alone, and is a wider risk impacting the entire mobile ecosystem."),(0,o.kt)("p",null,"A similar risk exists on desktop through the use of similar input applications (in addition to software keyloggers), however we consider that fully outside the scope of Cwtch risk assessment (in line with other attacks on the security of the underlying operating system itself)."),(0,o.kt)("p",null,"This is partially mitigated in Cwtch 1.2 through the use of ",(0,o.kt)("inlineCode",{parentName:"p"},"enableIMEPersonalizedLearning: false"),". See ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/142"},"this PR")," for more information."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6875c492.a3d95c11.js b/build-staging/es/assets/js/6875c492.a3d95c11.js new file mode 100644 index 00000000..3a83b038 --- /dev/null +++ b/build-staging/es/assets/js/6875c492.a3d95c11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8610],{9703:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(5999),r=a(2244);function s(e){const{metadata:t}=e,{previousPage:a,nextPage:s}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,l.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(r.Z,{permalink:a,title:n.createElement(l.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),s&&n.createElement(r.Z,{permalink:s,title:n.createElement(l.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(9460),r=a(390);function s(e){let{items:t,component:a=r.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(l.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}},1714:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var n=a(7294),l=a(6010),r=a(5999),s=a(8824),o=a(1944),i=a(5281),g=a(9960),c=a(9058),m=a(9703),u=a(197),p=a(9985);function d(e){const t=function(){const{selectMessage:e}=(0,s.c)();return t=>e(t,(0,r.I)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,r.I)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function h(e){let{tag:t}=e;const a=d(t);return n.createElement(n.Fragment,null,n.createElement(o.d,{title:a}),n.createElement(u.Z,{tag:"blog_tags_posts"}))}function b(e){let{tag:t,items:a,sidebar:l,listMetadata:s}=e;const o=d(t);return n.createElement(c.Z,{sidebar:l},n.createElement("header",{className:"margin-bottom--xl"},n.createElement("h1",null,o),n.createElement(g.Z,{href:t.allTagsPath},n.createElement(r.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page"},"View All Tags"))),n.createElement(p.Z,{items:a}),n.createElement(m.Z,{metadata:s}))}function E(e){return n.createElement(o.FG,{className:(0,l.Z)(i.k.wrapper.blogPages,i.k.page.blogTagPostListPage)},n.createElement(h,e),n.createElement(b,e))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6a78f460.15b9b73b.js b/build-staging/es/assets/js/6a78f460.15b9b73b.js new file mode 100644 index 00000000..08f369ae --- /dev/null +++ b/build-staging/es/assets/js/6a78f460.15b9b73b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[439],{3905:(t,e,a)=>{a.d(e,{Zo:()=>c,kt:()=>d});var i=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function o(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=i.createContext({}),p=function(t){var e=i.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},c=function(t){var e=p(t.components);return i.createElement(s.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},h=i.forwardRef((function(t,e){var a=t.components,r=t.mdxType,n=t.originalType,s=t.parentName,c=l(t,["components","mdxType","originalType","parentName"]),u=p(a),h=r,d=u["".concat(s,".").concat(h)]||u[h]||f[h]||n;return a?i.createElement(d,o(o({ref:e},c),{},{components:a})):i.createElement(d,o({ref:e},c))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var n=a.length,o=new Array(n);o[0]=h;var l={};for(var s in e)hasOwnProperty.call(e,s)&&(l[s]=e[s]);l.originalType=t,l[u]="string"==typeof t?t:r,o[1]=l;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>o,default:()=>f,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var i=a(7462),r=(a(7294),a(3905));const n={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"6 de abril de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/es/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/es/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/es/blog/cwtch-stable-roadmap-update"}},s={authorsImageUrls:[void 0]},p=[{value:"Availability Status",id:"availability-status",level:2},{value:"Profile Attributes",id:"profile-attributes",level:2},{value:"Downloading the Nightly",id:"downloading-the-nightly",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},u="wrapper";function f(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,i.Z)({},c,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,r.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,r.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,r.kt)("p",null,"The Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("h2",{id:"availability-status"},"Availability Status"),(0,r.kt)("p",null,'New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".'),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(4940).Z},(0,r.kt)("img",{src:a(1859).Z,width:"442",height:"233"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")),(0,r.kt)("h2",{id:"profile-attributes"},"Profile Attributes"),(0,r.kt)("p",null,"Also new is the ability to augment your profile with a few small pieces of ",(0,r.kt)("strong",{parentName:"p"},"public")," information."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(4076).Z},(0,r.kt)("img",{src:a(3506).Z,width:"730",height:"342"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information")),(0,r.kt)("h2",{id:"downloading-the-nightly"},"Downloading the Nightly"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly builds")," are available from our build server. Download links for ",(0,r.kt)("strong",{parentName:"p"},"2023-04-05-18-28-v1.11.0-7-g0290")," are available below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Windows: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Linux: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Mac: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Android: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"))),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}f.isMDXComponent=!0},4076:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},4940:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3506:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},1859:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6ae2b8f9.be84c69e.js b/build-staging/es/assets/js/6ae2b8f9.be84c69e.js new file mode 100644 index 00000000..1afaf908 --- /dev/null +++ b/build-staging/es/assets/js/6ae2b8f9.be84c69e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3957],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=o,v=d["".concat(c,".").concat(m)]||d[m]||u[m]||a;return t?n.createElement(v,i(i({ref:r},p),{},{components:t})):n.createElement(v,i({ref:r},p))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:7},i="Administrar servidores",s={unversionedId:"groups/manage-known-servers",id:"groups/manage-known-servers",title:"Administrar servidores",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/manage-known-servers.md",sourceDirName:"groups",slug:"/groups/manage-known-servers",permalink:"/es/docs/groups/manage-known-servers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/manage-known-servers.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Editar Nombre de un Grupo",permalink:"/es/docs/groups/edit-group-name"},next:{title:"Servers",permalink:"/es/docs/category/servers"}},c={},l=[{value:"Importar servidor alojado localmente",id:"importar-servidor-alojado-localmente",level:2}],p={toc:l},d="wrapper";function u(e){let{components:r,...t}=e;return(0,o.kt)(d,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"administrar-servidores"},"Administrar servidores"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,o.kt)("p",null,"Los grupos de Cwtch est\xe1n alojados en servidores no confiables. Si quieres ver los servidores que conoces, su estado y los grupos alojados en ellos:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"En el panel de contactos"),(0,o.kt)("li",{parentName:"ol"},"Ve al icono de administrar servidores")),(0,o.kt)("h2",{id:"importar-servidor-alojado-localmente"},"Importar servidor alojado localmente"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Para importar un servidor alojado localmente haz clic en seleccionar el servidor local"),(0,o.kt)("li",{parentName:"ol"},"Selecciona el servidor que quieras")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Manage.mp4"}))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6bdc8c14.87cae20b.js b/build-staging/es/assets/js/6bdc8c14.87cae20b.js new file mode 100644 index 00000000..392559c1 --- /dev/null +++ b/build-staging/es/assets/js/6bdc8c14.87cae20b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3775],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>m});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function o(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var l=r.createContext({}),u=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):o(o({},e),t)),n},s=function(t){var e=u(t.components);return r.createElement(l.Provider,{value:e},t.children)},p="mdxType",d={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},h=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,i=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),p=u(n),h=a,m=p["".concat(l,".").concat(h)]||p[h]||d[h]||i;return n?r.createElement(m,o(o({ref:e},s),{},{components:n})):r.createElement(m,o({ref:e},s))}));function m(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var i=n.length,o=new Array(i);o[0]=h;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[p]="string"==typeof t?t:a,o[1]=c;for(var u=2;u{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(7462),a=(n(7294),n(3905));const i={sidebar_position:2},o="Translating Cwtch",c={unversionedId:"contribute/translate",id:"contribute/translate",title:"Translating Cwtch",description:"Si quieres contribuir a la traducci\xf3n de Cwtch o de este manual puedes aprender c\xf3mo aqu\xed",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/translate.md",sourceDirName:"contribute",slug:"/contribute/translate",permalink:"/es/docs/contribute/translate",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/translate.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Pruebas de Cwtch",permalink:"/es/docs/contribute/testing"},next:{title:"Documentation Style Guide",permalink:"/es/docs/contribute/documentation"}},l={},u=[{value:"Contributing Translations to the Cwtch Application",id:"contributing-translations-to-the-cwtch-application",level:2},{value:"Join our Lokalise Team",id:"join-our-lokalise-team",level:3},{value:"Directly via Git",id:"directly-via-git",level:3},{value:"Manual del usuario de Cwtch",id:"manual-del-usuario-de-cwtch",level:2}],s={toc:u},p="wrapper";function d(t){let{components:e,...n}=t;return(0,a.kt)(p,(0,r.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"translating-cwtch"},"Translating Cwtch"),(0,a.kt)("p",null,"Si quieres contribuir a la traducci\xf3n de Cwtch o de este manual puedes aprender c\xf3mo aqu\xed"),(0,a.kt)("h2",{id:"contributing-translations-to-the-cwtch-application"},"Contributing Translations to the Cwtch Application"),(0,a.kt)("p",null,"There are two ways to contribute to Cwtch applications."),(0,a.kt)("h3",{id:"join-our-lokalise-team"},"Join our Lokalise Team"),(0,a.kt)("p",null,"We use ",(0,a.kt)("a",{parentName:"p",href:"https://lokalise.com"},"Lokalise")," for managing translations for the Cwtch application."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Sign up for a Lokalise account"),(0,a.kt)("li",{parentName:"ol"},"Email ",(0,a.kt)("a",{parentName:"li",href:"mailto:team@cwtch.im"},"team@cwtch.im")," with the language you are interested in translating and an email we can use to invite you to our Lokalise team.")),(0,a.kt)("h3",{id:"directly-via-git"},"Directly via Git"),(0,a.kt)("p",null,"For new translations, you can make a copy of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb")," and begin translating - you can then either ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing#cwtch-pull-request-process"},"submit pull requests or directly")," send updates to us (",(0,a.kt)("a",{parentName:"p",href:"mailto:team@cwtch.im"},"team@cwtch.im"),") and we will merge them in."),(0,a.kt)("p",null,"For adding to existing translations you can make pull requests directly on any file in ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/")," and we will review and merge them in."),(0,a.kt)("h2",{id:"manual-del-usuario-de-cwtch"},"Manual del usuario de Cwtch"),(0,a.kt)("p",null,"This handbook is translated through ",(0,a.kt)("a",{parentName:"p",href:"https://crowdin.com"},"Crowdin"),"."),(0,a.kt)("p",null,"To join our Crowdin project:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Sign up for an account on ",(0,a.kt)("a",{parentName:"li",href:"https://crowdin.com"},"Crowdin"),"."),(0,a.kt)("li",{parentName:"ol"},"Join the ",(0,a.kt)("a",{parentName:"li",href:"https://crowdin.com/project/cwtch-users-handbook"},"cwtch-users-handbook project"),".")),(0,a.kt)("p",null,"We bundle up changes to the documentation in batches and sync them with the Crowdin project on a regular basis."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"All contributions are ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/6d68d408.3d4fb168.js b/build-staging/es/assets/js/6d68d408.3d4fb168.js new file mode 100644 index 00000000..9f6337de --- /dev/null +++ b/build-staging/es/assets/js/6d68d408.3d4fb168.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8330],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,f=u["".concat(i,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,s(s({ref:t},p),{},{components:r})):n.createElement(f,s({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[u]="string"==typeof e?e:a,s[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:5},s="Contestar a un mensaje",c={unversionedId:"chat/reply-to-message",id:"chat/reply-to-message",title:"Contestar a un mensaje",description:"1. Selecciona un mensaje al que deseas responder",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/reply-to-message.md",sourceDirName:"chat",slug:"/chat/reply-to-message",permalink:"/es/docs/chat/reply-to-message",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/reply-to-message.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Accessing Conversation Settings",permalink:"/es/docs/chat/conversation-settings"},next:{title:"Compartir un archivo",permalink:"/es/docs/chat/share-file"}},i={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"contestar-a-un-mensaje"},"Contestar a un mensaje"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Selecciona un mensaje al que deseas responder"),(0,a.kt)("li",{parentName:"ol"},"Desliza un mensaje hacia la derecha"),(0,a.kt)("li",{parentName:"ol"},"Escribe una respuesta al mensaje citado"),(0,a.kt)("li",{parentName:"ol"},"Pulsar enviar")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/70a92a1e.51ada7b2.js b/build-staging/es/assets/js/70a92a1e.51ada7b2.js new file mode 100644 index 00000000..6cef76f5 --- /dev/null +++ b/build-staging/es/assets/js/70a92a1e.51ada7b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7519],{8904:e=>{e.exports=JSON.parse('{"label":"repliqate","permalink":"/es/blog/tags/repliqate","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/72315c3e.c9658a71.js b/build-staging/es/assets/js/72315c3e.c9658a71.js new file mode 100644 index 00000000..1cb23c46 --- /dev/null +++ b/build-staging/es/assets/js/72315c3e.c9658a71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5566],{7813:e=>{e.exports=JSON.parse('{"label":"documentation","permalink":"/es/blog/tags/documentation","allTagsPath":"/es/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/72ed38d2.1e0a8f75.js b/build-staging/es/assets/js/72ed38d2.1e0a8f75.js new file mode 100644 index 00000000..77446a8e --- /dev/null +++ b/build-staging/es/assets/js/72ed38d2.1e0a8f75.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9858],{2747:e=>{e.exports=JSON.parse('{"title":"Cwtch UI","slug":"/category/cwtch-ui","permalink":"/es/security/category/cwtch-ui","navigation":{"previous":{"title":"Cwtch Server","permalink":"/es/security/components/cwtch/server"},"next":{"title":"Android Service","permalink":"/es/security/components/ui/android"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/7a3564c1.e36fa6db.js b/build-staging/es/assets/js/7a3564c1.e36fa6db.js new file mode 100644 index 00000000..04feffe7 --- /dev/null +++ b/build-staging/es/assets/js/7a3564c1.e36fa6db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9930],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),d=r,m=u["".concat(s,".").concat(d)]||u[d]||f[d]||i;return n?o.createElement(m,a(a({ref:t},p),{},{components:n})):o.createElement(m,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:r,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:2},a="Pol\xedtica de notificaciones",c={unversionedId:"settings/behaviour/notification-policy",id:"settings/behaviour/notification-policy",title:"Pol\xedtica de notificaciones",description:"1. Ir a la configuraci\xf3n",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/behaviour/notification-policy.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-policy",permalink:"/es/docs/settings/behaviour/notification-policy",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-policy.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Bloquear Conexiones Desconocidas",permalink:"/es/docs/settings/behaviour/block-unknown-connections"},next:{title:"Contenido de notificaciones",permalink:"/es/docs/settings/behaviour/notification-content"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"pol\xedtica-de-notificaciones"},"Pol\xedtica de notificaciones"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Ir a la configuraci\xf3n"),(0,r.kt)("li",{parentName:"ol"},"Desplazar al comportamiento"),(0,r.kt)("li",{parentName:"ol"},"La pol\xedtica de notificaci\xf3n controla el comportamiento de las notificaciones"),(0,r.kt)("li",{parentName:"ol"},"Haz clic en Predeterminado para cambiar el comportamiento para optar o silenciar todas las notificaciones"),(0,r.kt)("li",{parentName:"ol"},"Elige tu pol\xedtica de notificaci\xf3n preferida")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/7a4d337c.39d56149.js b/build-staging/es/assets/js/7a4d337c.39d56149.js new file mode 100644 index 00000000..f3619542 --- /dev/null +++ b/build-staging/es/assets/js/7a4d337c.39d56149.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4170],{7500:s=>{s.exports=JSON.parse('{"label":"autobindings","permalink":"/es/blog/tags/autobindings","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/7ae36327.92375b54.js b/build-staging/es/assets/js/7ae36327.92375b54.js new file mode 100644 index 00000000..26d52169 --- /dev/null +++ b/build-staging/es/assets/js/7ae36327.92375b54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1949],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,g=u["".concat(c,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(g,s(s({ref:t},p),{},{components:r})):n.createElement(g,s({ref:t},p))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:a,s[1]=i;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:2},s="Explicaci\xf3n de temas Claros/Oscuros",i={unversionedId:"settings/appearance/light-dark-mode",id:"settings/appearance/light-dark-mode",title:"Explicaci\xf3n de temas Claros/Oscuros",description:"1. Pulsa el icono de configuraci\xf3n",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/light-dark-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/light-dark-mode",permalink:"/es/docs/settings/appearance/light-dark-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/light-dark-mode.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cambiar idioma",permalink:"/es/docs/settings/appearance/change-language"},next:{title:"Columnas de interfaz",permalink:"/es/docs/settings/appearance/ui-columns"}},c={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"explicaci\xf3n-de-temas-clarososcuros"},"Explicaci\xf3n de temas Claros/Oscuros"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pulsa el icono de configuraci\xf3n"),(0,a.kt)("li",{parentName:"ol"},'Puedes elegir tema claro u oscuro activando el interruptor de "usar temas claros"'),(0,a.kt)("li",{parentName:"ol"},'Usando el men\xfa desplegable "temas de color", elige un tema que te guste'),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("ol",{parentName:"li"},(0,a.kt)("li",{parentName:"ol"},"Cwtch: tonos morados"),(0,a.kt)("li",{parentName:"ol"},"Fantasma: Tonos grises"),(0,a.kt)("li",{parentName:"ol"},"Sirena: Tonos turquesa y morados"),(0,a.kt)("li",{parentName:"ol"},"Medianoche: Tonos negros y grises"),(0,a.kt)("li",{parentName:"ol"},"Ne\xf3n 1: Tonos morados y rosados"),(0,a.kt)("li",{parentName:"ol"},"Ne\xf3n 2: Tonos morados y turquesa"),(0,a.kt)("li",{parentName:"ol"},"Calabaza: Tonos morados y naranjas"),(0,a.kt)("li",{parentName:"ol"},"Bruja: Tonos verdes y rosas"),(0,a.kt)("li",{parentName:"ol"},"Vampiro: Tonos morados y rojos")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/7d7ca3f1.49e68129.js b/build-staging/es/assets/js/7d7ca3f1.49e68129.js new file mode 100644 index 00000000..50b8fa44 --- /dev/null +++ b/build-staging/es/assets/js/7d7ca3f1.49e68129.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4398],{3905:(e,r,t)=>{t.d(r,{Zo:()=>u,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},u=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(t),m=o,v=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return t?n.createElement(v,i(i({ref:r},u),{},{components:t})):n.createElement(v,i({ref:r},u))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:6},i="C\xf3mo desbloquear un servidor",s={unversionedId:"servers/unlock-server",id:"servers/unlock-server",title:"C\xf3mo desbloquear un servidor",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/unlock-server.md",sourceDirName:"servers",slug:"/servers/unlock-server",permalink:"/es/docs/servers/unlock-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/unlock-server.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"C\xf3mo compartir tu Paquete de Claves del Servidor",permalink:"/es/docs/servers/share-key"},next:{title:"Settings",permalink:"/es/docs/category/settings"}},c={},l=[],u={toc:l},p="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(p,(0,n.Z)({},u,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"c\xf3mo-desbloquear-un-servidor"},"C\xf3mo desbloquear un servidor"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Experimento de Grupos")," activado.")),(0,o.kt)("p",null,"Si protegiste tu servidor con una contrase\xf1a, tendr\xe1 que ser desbloqueado cada vez que reinicies la aplicaci\xf3n."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ve al icono del servidor"),(0,o.kt)("li",{parentName:"ol"},"Pulsa el icono de desbloqueo rosa"),(0,o.kt)("li",{parentName:"ol"},"Introduce la contrase\xf1a de tu servidor"),(0,o.kt)("li",{parentName:"ol"},"Pulsa Desbloquear")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/814f3328.dab4f975.js b/build-staging/es/assets/js/814f3328.dab4f975.js new file mode 100644 index 00000000..de5b745c --- /dev/null +++ b/build-staging/es/assets/js/814f3328.dab4f975.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2535],{5641:t=>{t.exports=JSON.parse('{"title":"Recent Logs","items":[{"title":"Cwtch Stable Roadmap Update","permalink":"/es/blog/cwtch-stable-roadmap-update-june"},{"title":"Cwtch Beta 1.12","permalink":"/es/blog/cwtch-nightly-1-12"},{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/es/blog/cwtch-nightly-v.11-74"},{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/es/blog/cwtch-developer-documentation"},{"title":"Availability Status and Profile Attributes","permalink":"/es/blog/availability-status-profile-attributes"},{"title":"Cwtch Stable Roadmap Update","permalink":"/es/blog/cwtch-stable-roadmap-update"},{"title":"Cwtch Beta 1.11","permalink":"/es/blog/cwtch-nightly-1-11"},{"title":"Updates to Cwtch Documentation","permalink":"/es/blog/cwtch-documentation"},{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/es/blog/autobindings-ii"},{"title":"Autogenerating Cwtch Bindings","permalink":"/es/blog/autobindings"},{"title":"Notes on Cwtch UI Testing (II)","permalink":"/es/blog/cwtch-testing-ii"},{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/es/blog/cwtch-android-reproducibility"},{"title":"Notes on Cwtch UI Testing","permalink":"/es/blog/cwtch-testing-i"},{"title":"Cwtch UI Platform Support","permalink":"/es/blog/cwtch-platform-support"},{"title":"Making Cwtch Bindings Reproducible","permalink":"/es/blog/cwtch-bindings-reproducible"},{"title":"Cwtch Stable API Design","permalink":"/es/blog/cwtch-stable-api-design"},{"title":"Path to Cwtch Stable","permalink":"/es/blog/path-to-cwtch-stable"}]}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/81d88b95.aab45f5c.js b/build-staging/es/assets/js/81d88b95.aab45f5c.js new file mode 100644 index 00000000..6b13dc38 --- /dev/null +++ b/build-staging/es/assets/js/81d88b95.aab45f5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[490],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var r=1;r=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var s=n.createContext({}),c=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):o(o({},r),e)),t},p=function(e){var r=c(e.components);return n.createElement(s.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},f=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(t),f=a,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||i;return t?n.createElement(m,o(o({ref:r},p),{},{components:t})):n.createElement(m,o({ref:r},p))}));function m(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var i=t.length,o=new Array(i);o[0]=f;var l={};for(var s in r)hasOwnProperty.call(r,s)&&(l[s]=r[s]);l.originalType=e,l[u]="string"==typeof e?e:a,o[1]=l;for(var c=2;c{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=t(7462),a=(t(7294),t(3905));const i={sidebar_position:1},o="Una Introducci\xf3n a los Perfiles de Cwtch",l={unversionedId:"profiles/introduction",id:"profiles/introduction",title:"Una Introducci\xf3n a los Perfiles de Cwtch",description:"Con Cwtch puedes crear uno o m\xe1s Perfiles. Cada perfil genera un par de claves aleatorias ed25519 compatibles con la Red Tor.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/introduction.md",sourceDirName:"profiles",slug:"/profiles/introduction",permalink:"/es/docs/profiles/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Profiles",permalink:"/es/docs/category/profiles"},next:{title:"Crear un nuevo perfil",permalink:"/es/docs/profiles/create-a-profile"}},s={},c=[{value:"Administrar Perfiles",id:"administrar-perfiles",level:2}],p={toc:c},u="wrapper";function d(e){let{components:r,...t}=e;return(0,a.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"una-introducci\xf3n-a-los-perfiles-de-cwtch"},"Una Introducci\xf3n a los Perfiles de Cwtch"),(0,a.kt)("p",null,"Con Cwtch puedes crear uno o m\xe1s ",(0,a.kt)("strong",{parentName:"p"},"Perfiles"),". Cada perfil genera un par de claves aleatorias ed25519 compatibles con la Red Tor."),(0,a.kt)("p",null,"Este es el identificador que puedes dar a tus contactos y que pueden usar para contactarte a trav\xe9s de Cwtch."),(0,a.kt)("p",null,"Cwtch te permite crear y administrar perfiles m\xfaltiples y separados. Cada perfil est\xe1 asociado con un par de claves diferente que lanza un servicio de Onion diferente."),(0,a.kt)("h2",{id:"administrar-perfiles"},"Administrar Perfiles"),(0,a.kt)("p",null,"Al iniciarse Cwtch lanzar\xe1 la pantalla Administrar Perfiles. Desde esta pantalla puedes:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/create-a-profile"},"Crear un nuevo perfil")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/unlock-profile"},"Desbloquear perfiles cifrados existentes")),(0,a.kt)("li",{parentName:"ul"},"Administrar Perfiles Cargados",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-name/"},"Cambiar el Nombre Para Mostrar de un Perfil")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-password/"},"Cambiar la Contrase\xf1a de un Perfil")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/delete-profile"},"Eliminar un perfil")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-profile-image/"},"Cambiar tu imagen de perfil"))))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/824a28c6.bbeb6a19.js b/build-staging/es/assets/js/824a28c6.bbeb6a19.js new file mode 100644 index 00000000..93a7148c --- /dev/null +++ b/build-staging/es/assets/js/824a28c6.bbeb6a19.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5905],{3905:(t,e,i)=>{i.d(e,{Zo:()=>s,kt:()=>b});var r=i(7294);function n(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function o(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,r)}return i}function a(t){for(var e=1;e=0||(n[i]=t[i]);return n}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,i)&&(n[i]=t[i])}return n}var l=r.createContext({}),p=function(t){var e=r.useContext(l),i=e;return t&&(i="function"==typeof t?t(e):a(a({},e),t)),i},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},h="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var i=t.components,n=t.mdxType,o=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),h=p(i),d=n,b=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return i?r.createElement(b,a(a({ref:e},s),{},{components:i})):r.createElement(b,a({ref:e},s))}));function b(t,e){var i=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var o=i.length,a=new Array(o);a[0]=d;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[h]="string"==typeof t?t:n,a[1]=c;for(var p=2;p{i.r(e),i.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=i(7462),n=(i(7294),i(3905));const o={sidebar_position:1},a="Getting Started",c={unversionedId:"building-a-cwtch-app/intro",id:"building-a-cwtch-app/intro",title:"Getting Started",description:"Choosing A Cwtch Library",source:"@site/developing/building-a-cwtch-app/intro.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/intro",permalink:"/es/developing/building-a-cwtch-app/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Building a Cwtch App",permalink:"/es/developing/category/building-a-cwtch-app"},next:{title:"Core Concepts",permalink:"/es/developing/building-a-cwtch-app/core-concepts"}},l={},p=[{value:"Choosing A Cwtch Library",id:"choosing-a-cwtch-library",level:2},{value:"Cwtch Go Lib",id:"cwtch-go-lib",level:3},{value:"CwtchBot",id:"cwtchbot",level:3},{value:"Autobindings (C-bindings)",id:"autobindings-c-bindings",level:3},{value:"libCwtch-rs (Rust)",id:"libcwtch-rs-rust",level:3}],s={toc:p},h="wrapper";function u(t){let{components:e,...i}=t;return(0,n.kt)(h,(0,r.Z)({},s,i,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"getting-started"},"Getting Started"),(0,n.kt)("h2",{id:"choosing-a-cwtch-library"},"Choosing A Cwtch Library"),(0,n.kt)("h3",{id:"cwtch-go-lib"},"Cwtch Go Lib"),(0,n.kt)("p",null,"The official Cwtch library is written in Go and can be found at ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"https://git.openprivacy.ca/cwtch.im/cwtch"),". This library allows access to all Cwtch functionality."),(0,n.kt)("h3",{id:"cwtchbot"},"CwtchBot"),(0,n.kt)("p",null,"We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot#using-cwtchbot-go"},"building an echobot tutorial"),"."),(0,n.kt)("h3",{id:"autobindings-c-bindings"},"Autobindings (C-bindings)"),(0,n.kt)("p",null,"The ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"official c-bindings for Cwtch")," are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI."),(0,n.kt)("h3",{id:"libcwtch-rs-rust"},"libCwtch-rs (Rust)"),(0,n.kt)("p",null,"An experimental rust-fied version of Cwtch Autobindings is available in ",(0,n.kt)("a",{parentName:"p",href:"https://crates.io/crates/libcwtch"},"libCwtch-rs"),". While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/86813741.2158c6b4.js b/build-staging/es/assets/js/86813741.2158c6b4.js new file mode 100644 index 00000000..d54b9ec8 --- /dev/null +++ b/build-staging/es/assets/js/86813741.2158c6b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6679],{2750:s=>{s.exports=JSON.parse('{"label":"cwtch","permalink":"/es/blog/tags/cwtch","allTagsPath":"/es/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/86aebd6f.8292d4fa.js b/build-staging/es/assets/js/86aebd6f.8292d4fa.js new file mode 100644 index 00000000..8bf0cebc --- /dev/null +++ b/build-staging/es/assets/js/86aebd6f.8292d4fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9599],{1754:s=>{s.exports=JSON.parse('{"label":"security-handbook","permalink":"/es/blog/tags/security-handbook","allTagsPath":"/es/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/89f86a37.4b34c50d.js b/build-staging/es/assets/js/89f86a37.4b34c50d.js new file mode 100644 index 00000000..351e5219 --- /dev/null +++ b/build-staging/es/assets/js/89f86a37.4b34c50d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9759],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>g});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function c(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),s=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=s(a),u=n,g=m["".concat(l,".").concat(u)]||m[u]||h[u]||o;return a?r.createElement(g,c(c({ref:t},p),{},{components:a})):r.createElement(g,c({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,c=new Array(o);c[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:n,c[1]=i;for(var s=2;s{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},c=void 0,i={permalink:"/es/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"29 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"release",permalink:"/es/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/es/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/es/blog/cwtch-documentation"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},m="wrapper";function h(e){let{components:t,...o}=e;return(0,n.kt)(m,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},6094:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/8a73259a.d83ce251.js b/build-staging/es/assets/js/8a73259a.d83ce251.js new file mode 100644 index 00000000..fbaf1ac9 --- /dev/null +++ b/build-staging/es/assets/js/8a73259a.d83ce251.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6162],{5046:e=>{e.exports=JSON.parse('{"title":"Comportamiento","slug":"/category/behaviour","permalink":"/es/docs/category/behaviour","navigation":{"previous":{"title":"Modo de streaming/presentaci\xf3n","permalink":"/es/docs/settings/appearance/streamer-mode"},"next":{"title":"Bloquear Conexiones Desconocidas","permalink":"/es/docs/settings/behaviour/block-unknown-connections"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/8df6de9b.b9435ee3.js b/build-staging/es/assets/js/8df6de9b.b9435ee3.js new file mode 100644 index 00000000..c2aade6a --- /dev/null +++ b/build-staging/es/assets/js/8df6de9b.b9435ee3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9954],{3222:e=>{e.exports=JSON.parse('[{"label":"cwtch","permalink":"/es/blog/tags/cwtch","count":17},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable","count":17},{"label":"planning","permalink":"/es/blog/tags/planning","count":4},{"label":"release","permalink":"/es/blog/tags/release","count":2},{"label":"developer-documentation","permalink":"/es/blog/tags/developer-documentation","count":2},{"label":"nightly","permalink":"/es/blog/tags/nightly","count":1},{"label":"documentation","permalink":"/es/blog/tags/documentation","count":1},{"label":"security-handbook","permalink":"/es/blog/tags/security-handbook","count":1},{"label":"bindings","permalink":"/es/blog/tags/bindings","count":4},{"label":"autobindings","permalink":"/es/blog/tags/autobindings","count":2},{"label":"libcwtch","permalink":"/es/blog/tags/libcwtch","count":2},{"label":"support","permalink":"/es/blog/tags/support","count":3},{"label":"testing","permalink":"/es/blog/tags/testing","count":2},{"label":"reproducible-builds","permalink":"/es/blog/tags/reproducible-builds","count":2},{"label":"repliqate","permalink":"/es/blog/tags/repliqate","count":2},{"label":"api","permalink":"/es/blog/tags/api","count":1}]')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/8eaa4178.fb5d204a.js b/build-staging/es/assets/js/8eaa4178.fb5d204a.js new file mode 100644 index 00000000..66b88c67 --- /dev/null +++ b/build-staging/es/assets/js/8eaa4178.fb5d204a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6179],{1915:e=>{e.exports=JSON.parse('{"title":"Perfiles","slug":"/category/profiles","permalink":"/es/docs/category/profiles","navigation":{"previous":{"title":"Supported Platforms","permalink":"/es/docs/getting-started/supported_platforms"},"next":{"title":"Una Introducci\xf3n a los Perfiles de Cwtch","permalink":"/es/docs/profiles/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/8fd5e00a.030bf1c3.js b/build-staging/es/assets/js/8fd5e00a.030bf1c3.js new file mode 100644 index 00000000..d423d54b --- /dev/null +++ b/build-staging/es/assets/js/8fd5e00a.030bf1c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[568],{4510:e=>{e.exports=JSON.parse('{"permalink":"/es/blog","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/es/blog/page/2","blogDescription":"The latest updated on Cwtch development.","blogTitle":"Development Log"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/8fe7a387.2fa91d2e.js b/build-staging/es/assets/js/8fe7a387.2fa91d2e.js new file mode 100644 index 00000000..af1ee8f1 --- /dev/null +++ b/build-staging/es/assets/js/8fe7a387.2fa91d2e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5233],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=i.createContext({}),s=function(e){var t=i.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=s(e.components);return i.createElement(p.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(n),h=a,g=d["".concat(p,".").concat(h)]||d[h]||m[h]||r;return n?i.createElement(g,o(o({ref:t},c),{},{components:n})):i.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=h;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[d]="string"==typeof e?e:a,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const r={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"3 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"autobindings",permalink:"/es/blog/tags/autobindings"},{label:"libcwtch",permalink:"/es/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/es/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/es/blog/autobindings"}},p={authorsImageUrls:[void 0]},s=[{value:"The Structure of an Application Experiment",id:"the-structure-of-an-application-experiment",level:2},{value:"New Required Management APIs",id:"new-required-management-apis",level:3},{value:"Adding Support for Application Experiments in the Spec File",id:"adding-support-for-application-experiments-in-the-spec-file",level:3},{value:"Generation-Time Inclusion",id:"generation-time-inclusion",level:3},{value:"Cwtch UI Integration",id:"cwtch-ui-integration",level:3},{value:"Nightlies & Next Steps",id:"nightlies--next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:s},d="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,i.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"the-structure-of-an-application-experiment"},"The Structure of an Application Experiment"),(0,a.kt)("p",null,"An application-level experiment consists of:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"A set of top-level APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DeleteServer")," - these are the APIs that we want to expose to calling applications."),(0,a.kt)("li",{parentName:"ol"},"An encapsulating structure for the set of APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ServersFunctionality")," - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity."),(0,a.kt)("li",{parentName:"ol"},"A global variable that exists at the top level of libCwtch, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"var serverExperiment *servers.ServersFunctionality servers")," - our single pointer to the underlying functionality."),(0,a.kt)("li",{parentName:"ol"},"A set of management-related APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"Init"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"UpdateSettings"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"OnACNEvent")," - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers)."),(0,a.kt)("li",{parentName:"ol"},"Management code within ",(0,a.kt)("inlineCode",{parentName:"li"},"_startCwtch")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"_reconnectCwtch")," that calls the management APIs on the global variable.")),(0,a.kt)("p",null,"From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on ",(0,a.kt)("inlineCode",{parentName:"p"},"application")," or a specific ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"."),(0,a.kt)("p",null,"Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template."),(0,a.kt)("h3",{id:"new-required-management-apis"},"New Required Management APIs"),(0,a.kt)("p",null,"To achieve this weaving, we now require application-level experiments to implement an ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandlerInterface")," interface and expose itself via an\ninitialize constructor ",(0,a.kt)("inlineCode",{parentName:"p"},"Init(acn, appDir) -> EventHandlerInterface"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"Enable(app, acn)"),"."),(0,a.kt)("p",null,"For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface."),(0,a.kt)("p",null,"We can then generate, and optionally include blocks of code like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," = .Init(&globalACN, appDir)\n eventHandler.AddModule()\n .Enable(application, &globalACN)\n")),(0,a.kt)("p",null,"and place them at specific points in the code. ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandler")," has also been extended to maintain a collection of ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," so that it can\npass on interesting events."),(0,a.kt)("h3",{id:"adding-support-for-application-experiments-in-the-spec-file"},"Adding Support for Application Experiments in the Spec File"),(0,a.kt)("p",null,"We have introduced a new ",(0,a.kt)("inlineCode",{parentName:"p"},"!")," operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option ",(0,a.kt)("inlineCode",{parentName:"p"},"exp")," which will call the function on the configured experiment, and ",(0,a.kt)("inlineCode",{parentName:"p"},"global")," to allow the setting up\nof a global functionality within the library."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},' # Server Hosting Experiment\n !serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"\n !serverExperiment global serverExperiment *servers.ServersFunctionality servers\n !serverExperiment exp CreateServer application password string:description bool:autostart\n !serverExperiment exp SetServerAttribute application string:handle string:key string:val\n !serverExperiment exp LoadServers application acn password\n !serverExperiment exp LaunchServers application acn\n !serverExperiment exp LaunchServer application string:handle\n !serverExperiment exp StopServer application string:handle\n !serverExperiment exp StopServers application\n !serverExperiment exp DestroyServers\n !serverExperiment exp DeleteServer application string:handle password\n')),(0,a.kt)("h3",{id:"generation-time-inclusion"},"Generation-Time Inclusion"),(0,a.kt)("p",null," Without any arguments provided ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," will not generate code for any experiments."),(0,a.kt)("p",null," In order to determine what experimental code to generate, ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," now interprets arguments as enabled compile time experiments, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings serverExperiment")," will turn on\ngeneration of server hosting code, per the spec file above."),(0,a.kt)("h3",{id:"cwtch-ui-integration"},"Cwtch UI Integration"),(0,a.kt)("p",null,"The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"c_LoadServers")," - if it doesn't then the UI is safe to assume the\nfeature is not available."),(0,a.kt)("figure",null,(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7365).Z,width:"1290",height:"754"})),(0,a.kt)("figcaption",null,"A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.")),(0,a.kt)("h2",{id:"nightlies--next-steps"},"Nightlies & Next Steps"),(0,a.kt)("p",null,"We are now publishing ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/"},"nightlies")," of autobinding derived libCwtch-go, along with ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2"},"Repliqate scripts")," for reproducibility."),(0,a.kt)("p",null,"With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11."),(0,a.kt)("p",null,"However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),".")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}m.isMDXComponent=!0},7365:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png"},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/91341964.d796dbab.js b/build-staging/es/assets/js/91341964.d796dbab.js new file mode 100644 index 00000000..63d8a1df --- /dev/null +++ b/build-staging/es/assets/js/91341964.d796dbab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3214],{3905:(e,n,r)=>{r.d(n,{Zo:()=>l,kt:()=>f});var t=r(7294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=t.createContext({}),s=function(e){var n=t.useContext(p),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},l=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=s(r),d=a,f=u["".concat(p,".").concat(d)]||u[d]||m[d]||i;return r?t.createElement(f,o(o({ref:n},l),{},{components:r})):t.createElement(f,o({ref:n},l))}));function f(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var c={};for(var p in n)hasOwnProperty.call(n,p)&&(c[p]=n[p]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var s=2;s{r.r(n),r.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var t=r(7462),a=(r(7294),r(3905));const i={},o="References",c={unversionedId:"references",id:"references",title:"References",description:'* Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."',source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/references.md",sourceDirName:".",slug:"/references",permalink:"/es/security/references",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Development",permalink:"/es/security/development"}},p={},s=[],l={toc:s},u="wrapper";function m(e){let{components:n,...r}=e;return(0,a.kt)(u,(0,t.Z)({},l,r,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"references"},"References"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Brooks, John. Ricochet: Anonymous instant messaging for real privacy. ",(0,a.kt)("a",{parentName:"p",href:"https://ricochet.im."},"https://ricochet.im.")," Accessed: 2018-03-10")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata\u2014New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Langley, Adam. Pond. ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/agl/pond"},"https://github.com/agl/pond"),". Accessed: 2018-05-21.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Kalysch, A., Bove, D. and M\xfcller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn\u2019t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Unger, Nik et al. \u201cSoK: secure messaging\u201d. In: Security and Privacy (SP ), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232\u2013249 ",(0,a.kt)("a",{parentName:"p",href:"http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf"},"link")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/935f2afb.ee974ae8.js b/build-staging/es/assets/js/935f2afb.ee974ae8.js new file mode 100644 index 00000000..2fb4298d --- /dev/null +++ b/build-staging/es/assets/js/935f2afb.ee974ae8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Siguiente","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"\xbfQu\xe9 es Cwtch?","href":"/es/docs/intro","docId":"intro"},{"type":"category","label":"Getting started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Supported Platforms","href":"/es/docs/getting-started/supported_platforms","docId":"getting-started/supported_platforms"}],"href":"/es/docs/category/getting-started"},{"type":"category","label":"Perfiles","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Una Introducci\xf3n a los Perfiles de Cwtch","href":"/es/docs/profiles/introduction","docId":"profiles/introduction"},{"type":"link","label":"Crear un nuevo perfil","href":"/es/docs/profiles/create-a-profile","docId":"profiles/create-a-profile"},{"type":"link","label":"Cambiar tu nombre para mostrar","href":"/es/docs/profiles/change-name","docId":"profiles/change-name"},{"type":"link","label":"Cambiar tu contrase\xf1a","href":"/es/docs/profiles/change-password","docId":"profiles/change-password"},{"type":"link","label":"Cambiar tu imagen de perfil","href":"/es/docs/profiles/change-profile-image","docId":"profiles/change-profile-image"},{"type":"link","label":"Desbloquear perfiles cifrados","href":"/es/docs/profiles/unlock-profile","docId":"profiles/unlock-profile"},{"type":"link","label":"Eliminar un perfil","href":"/es/docs/profiles/delete-profile","docId":"profiles/delete-profile"},{"type":"link","label":"Copia de seguridad o Exportaci\xf3n de un perfil","href":"/es/docs/profiles/exporting-profile","docId":"profiles/exporting-profile"},{"type":"link","label":"Importar un perfil","href":"/es/docs/profiles/importing-a-profile","docId":"profiles/importing-a-profile"},{"type":"link","label":"Setting Availability Status","href":"/es/docs/profiles/availability-status","docId":"profiles/availability-status"},{"type":"link","label":"Setting Profile Attributes","href":"/es/docs/profiles/profile-info","docId":"profiles/profile-info"}],"href":"/es/docs/category/profiles"},{"type":"category","label":"Conversations","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Una Introducci\xf3n al Chat P2P de Cwtch","href":"/es/docs/chat/introduction","docId":"chat/introduction"},{"type":"link","label":"Starting a New Conversation","href":"/es/docs/chat/add-contact","docId":"chat/add-contact"},{"type":"link","label":"Aceptar/denegar nuevas conversaciones","href":"/es/docs/chat/accept-deny-new-conversation","docId":"chat/accept-deny-new-conversation"},{"type":"link","label":"Sharing Cwtch Addresses","href":"/es/docs/chat/share-address-with-friends","docId":"chat/share-address-with-friends"},{"type":"link","label":"Guardar el historial de conversaciones","href":"/es/docs/chat/save-conversation-history","docId":"chat/save-conversation-history"},{"type":"link","label":"Formato de mensajes","href":"/es/docs/chat/message-formatting","docId":"chat/message-formatting"},{"type":"link","label":"Accessing Conversation Settings","href":"/es/docs/chat/conversation-settings","docId":"chat/conversation-settings"},{"type":"link","label":"Contestar a un mensaje","href":"/es/docs/chat/reply-to-message","docId":"chat/reply-to-message"},{"type":"link","label":"Compartir un archivo","href":"/es/docs/chat/share-file","docId":"chat/share-file"},{"type":"link","label":"Bloquear un contacto","href":"/es/docs/chat/block-contact","docId":"chat/block-contact"},{"type":"link","label":"Desbloquear un contacto","href":"/es/docs/chat/unblock-contact","docId":"chat/unblock-contact"},{"type":"link","label":"Removing a Conversation","href":"/es/docs/chat/delete-contact","docId":"chat/delete-contact"}],"href":"/es/docs/category/conversations"},{"type":"category","label":"Groups","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Una Introducci\xf3n a los Grupos de Cwtch","href":"/es/docs/groups/introduction","docId":"groups/introduction"},{"type":"link","label":"Crea un grupo nuevo","href":"/es/docs/groups/create-group","docId":"groups/create-group"},{"type":"link","label":"Enviar invitaciones a un Grupo","href":"/es/docs/groups/send-invite","docId":"groups/send-invite"},{"type":"link","label":"Aceptar una invitaci\xf3n de grupo","href":"/es/docs/groups/accept-group-invite","docId":"groups/accept-group-invite"},{"type":"link","label":"C\xf3mo abandonar un grupo","href":"/es/docs/groups/leave-group","docId":"groups/leave-group"},{"type":"link","label":"Editar Nombre de un Grupo","href":"/es/docs/groups/edit-group-name","docId":"groups/edit-group-name"},{"type":"link","label":"Administrar servidores","href":"/es/docs/groups/manage-known-servers","docId":"groups/manage-known-servers"}],"href":"/es/docs/category/groups"},{"type":"category","label":"Servers","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introducci\xf3n a Servidores","href":"/es/docs/servers/introduction","docId":"servers/introduction"},{"type":"link","label":"C\xf3mo crear un servidor","href":"/es/docs/servers/create-server","docId":"servers/create-server"},{"type":"link","label":"C\xf3mo editar un servidor","href":"/es/docs/servers/edit-server","docId":"servers/edit-server"},{"type":"link","label":"C\xf3mo eliminar un servidor","href":"/es/docs/servers/delete-server","docId":"servers/delete-server"},{"type":"link","label":"C\xf3mo compartir tu Paquete de Claves del Servidor","href":"/es/docs/servers/share-key","docId":"servers/share-key"},{"type":"link","label":"C\xf3mo desbloquear un servidor","href":"/es/docs/servers/unlock-server","docId":"servers/unlock-server"}],"href":"/es/docs/category/servers"},{"type":"category","label":"Configuraci\xf3n","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Una Introducci\xf3n a la configuraci\xf3n de Cwtch","href":"/es/docs/settings/introduction","docId":"settings/introduction"},{"type":"category","label":"Apariencia","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cambiar idioma","href":"/es/docs/settings/appearance/change-language","docId":"settings/appearance/change-language"},{"type":"link","label":"Explicaci\xf3n de temas Claros/Oscuros","href":"/es/docs/settings/appearance/light-dark-mode","docId":"settings/appearance/light-dark-mode"},{"type":"link","label":"Columnas de interfaz","href":"/es/docs/settings/appearance/ui-columns","docId":"settings/appearance/ui-columns"},{"type":"link","label":"Modo de streaming/presentaci\xf3n","href":"/es/docs/settings/appearance/streamer-mode","docId":"settings/appearance/streamer-mode"}],"href":"/es/docs/category/appearance"},{"type":"category","label":"Comportamiento","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bloquear Conexiones Desconocidas","href":"/es/docs/settings/behaviour/block-unknown-connections","docId":"settings/behaviour/block-unknown-connections"},{"type":"link","label":"Pol\xedtica de notificaciones","href":"/es/docs/settings/behaviour/notification-policy","docId":"settings/behaviour/notification-policy"},{"type":"link","label":"Contenido de notificaciones","href":"/es/docs/settings/behaviour/notification-content","docId":"settings/behaviour/notification-content"}],"href":"/es/docs/category/behaviour"},{"type":"category","label":"Experiments","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Groups Experiment","href":"/es/docs/settings/experiments/group-experiment","docId":"settings/experiments/group-experiment"},{"type":"link","label":"Alojamiento de servidor","href":"/es/docs/settings/experiments/server-hosting","docId":"settings/experiments/server-hosting"},{"type":"link","label":"Compartir Archivos","href":"/es/docs/settings/experiments/file-sharing","docId":"settings/experiments/file-sharing"},{"type":"link","label":"Vista previa de im\xe1genes y fotos de perfil","href":"/es/docs/settings/experiments/image-previews-and-profile-pictures","docId":"settings/experiments/image-previews-and-profile-pictures"},{"type":"link","label":"Experimento de Enlaces Cliqueables","href":"/es/docs/settings/experiments/clickable-links","docId":"settings/experiments/clickable-links"},{"type":"link","label":"Formato de mensajes","href":"/es/docs/settings/experiments/message-formatting","docId":"settings/experiments/message-formatting"},{"type":"link","label":"QR Codes","href":"/es/docs/settings/experiments/qrcodes","docId":"settings/experiments/qrcodes"}],"href":"/es/docs/category/experiments"}],"href":"/es/docs/category/settings"},{"type":"link","label":"Tor","href":"/es/docs/tor","docId":"tor"},{"type":"category","label":"Contribuye","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Developing Cwtch","href":"/es/docs/contribute/developing","docId":"contribute/developing"},{"type":"link","label":"Pruebas de Cwtch","href":"/es/docs/contribute/testing","docId":"contribute/testing"},{"type":"link","label":"Translating Cwtch","href":"/es/docs/contribute/translate","docId":"contribute/translate"},{"type":"link","label":"Documentation Style Guide","href":"/es/docs/contribute/documentation","docId":"contribute/documentation"},{"type":"link","label":"Stickers","href":"/es/docs/contribute/stickers","docId":"contribute/stickers"}],"href":"/es/docs/category/contribute"},{"type":"category","label":"Platforms","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Running Cwtch on Tails","href":"/es/docs/platforms/tails","docId":"platforms/tails"}],"href":"/es/docs/category/platforms"}]},"docs":{"chat/accept-deny-new-conversation":{"id":"chat/accept-deny-new-conversation","title":"Aceptar/denegar nuevas conversaciones","description":"1. Ir a tu perfil","sidebar":"tutorialSidebar"},"chat/add-contact":{"id":"chat/add-contact","title":"Starting a New Conversation","description":"1. Selecciona un perfil","sidebar":"tutorialSidebar"},"chat/block-contact":{"id":"chat/block-contact","title":"Bloquear un contacto","description":"1. En una ventana de conversaci\xf3n","sidebar":"tutorialSidebar"},"chat/conversation-settings":{"id":"chat/conversation-settings","title":"Accessing Conversation Settings","description":"In a conversation window, click on the Settings icon in the top bar.","sidebar":"tutorialSidebar"},"chat/delete-contact":{"id":"chat/delete-contact","title":"Removing a Conversation","description":"This feature will result in irreversible deletion. This cannot be undone.","sidebar":"tutorialSidebar"},"chat/introduction":{"id":"chat/introduction","title":"Una Introducci\xf3n al Chat P2P de Cwtch","description":"Cwtch usa los servicios Onion de Tor v3 para establecer conexiones an\xf3nimas, peer-to-peer entre Perfiles.","sidebar":"tutorialSidebar"},"chat/message-formatting":{"id":"chat/message-formatting","title":"Formato de mensajes","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"chat/reply-to-message":{"id":"chat/reply-to-message","title":"Contestar a un mensaje","description":"1. Selecciona un mensaje al que deseas responder","sidebar":"tutorialSidebar"},"chat/save-conversation-history":{"id":"chat/save-conversation-history","title":"Guardar el historial de conversaciones","description":"Por defecto, por privacidad, Cwtch no conserva el historial de conversaciones entre sesiones.","sidebar":"tutorialSidebar"},"chat/share-address-with-friends":{"id":"chat/share-address-with-friends","title":"Sharing Cwtch Addresses","description":"There are many ways to share a Cwtch address.","sidebar":"tutorialSidebar"},"chat/share-file":{"id":"chat/share-file","title":"Compartir un archivo","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"chat/unblock-contact":{"id":"chat/unblock-contact","title":"Desbloquear un contacto","description":"1. Selecciona el contacto en tu lista de conversaci\xf3nes. Los contactos bloqueados se mueven al final de la lista.","sidebar":"tutorialSidebar"},"contribute/developing":{"id":"contribute/developing","title":"Developing Cwtch","description":"This section documents some ways to get started with Cwtch Development.","sidebar":"tutorialSidebar"},"contribute/documentation":{"id":"contribute/documentation","title":"Documentation Style Guide","description":"This section documents the expected structure and quality of Cwtch documentation.","sidebar":"tutorialSidebar"},"contribute/stickers":{"id":"contribute/stickers","title":"Stickers","description":"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email erinn@openprivacy.ca with details and an address for us to mail stickers to.","sidebar":"tutorialSidebar"},"contribute/testing":{"id":"contribute/testing","title":"Pruebas de Cwtch","description":"Esta secci\xf3n documenta algunas formas de comenzar con la prueba de Cwtch.","sidebar":"tutorialSidebar"},"contribute/translate":{"id":"contribute/translate","title":"Translating Cwtch","description":"Si quieres contribuir a la traducci\xf3n de Cwtch o de este manual puedes aprender c\xf3mo aqu\xed","sidebar":"tutorialSidebar"},"getting-started/supported_platforms":{"id":"getting-started/supported_platforms","title":"Supported Platforms","description":"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).","sidebar":"tutorialSidebar"},"groups/accept-group-invite":{"id":"groups/accept-group-invite","title":"Aceptar una invitaci\xf3n de grupo","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"groups/create-group":{"id":"groups/create-group","title":"Crea un grupo nuevo","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"groups/edit-group-name":{"id":"groups/edit-group-name","title":"Editar Nombre de un Grupo","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"groups/introduction":{"id":"groups/introduction","title":"Una Introducci\xf3n a los Grupos de Cwtch","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"groups/leave-group":{"id":"groups/leave-group","title":"C\xf3mo abandonar un grupo","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"groups/manage-known-servers":{"id":"groups/manage-known-servers","title":"Administrar servidores","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"groups/send-invite":{"id":"groups/send-invite","title":"Enviar invitaciones a un Grupo","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"\xbfQu\xe9 es Cwtch?","description":"Cwtch (/k\u028at\u0283/ - Una palabra galesa m\xe1s o menos traducida a \u201cun abrazo que crea un lugar seguro\u201d) es una aplicaci\xf3n de mensajer\xeda descentralizada, que preserva la privacidad.","sidebar":"tutorialSidebar"},"platforms/tails":{"id":"platforms/tails","title":"Running Cwtch on Tails","description":"This functionality is currently only available in the Nightly Release builds of Cwtch.","sidebar":"tutorialSidebar"},"profiles/availability-status":{"id":"profiles/availability-status","title":"Setting Availability Status","description":"This functionality is currently only available in the Nightly Release builds of Cwtch.","sidebar":"tutorialSidebar"},"profiles/change-name":{"id":"profiles/change-name","title":"Cambiar tu nombre para mostrar","description":"1. En la vista Administrar Perfiles, pulsa el l\xe1piz junto al perfil que deseas editar","sidebar":"tutorialSidebar"},"profiles/change-password":{"id":"profiles/change-password","title":"Cambiar tu contrase\xf1a","description":"1. Pulsa el l\xe1piz junto al perfil que quieres editar","sidebar":"tutorialSidebar"},"profiles/change-profile-image":{"id":"profiles/change-profile-image","title":"Cambiar tu imagen de perfil","description":"Esta funci\xf3n requiere Experimentos habilitados y tanto Archivos Compartidos como Im\xe1genes previas de imagen y fotos activadas.","sidebar":"tutorialSidebar"},"profiles/create-a-profile":{"id":"profiles/create-a-profile","title":"Crear un nuevo perfil","description":"1. Pulsa el bot\xf3n + en la esquina inferior derecha y selecciona \\"Nuevo perfil\\"","sidebar":"tutorialSidebar"},"profiles/delete-profile":{"id":"profiles/delete-profile","title":"Eliminar un perfil","description":"Esta funci\xf3n resultar\xe1 en la eliminaci\xf3n irreversible de material clave. Esto no se puede deshacer.","sidebar":"tutorialSidebar"},"profiles/exporting-profile":{"id":"profiles/exporting-profile","title":"Copia de seguridad o Exportaci\xf3n de un perfil","description":"En la pantalla de administraci\xf3n de perfiles:","sidebar":"tutorialSidebar"},"profiles/importing-a-profile":{"id":"profiles/importing-a-profile","title":"Importar un perfil","description":"1. Pulsa el bot\xf3n + en la esquina inferior derecha y selecciona \\"Importar perfil\\"","sidebar":"tutorialSidebar"},"profiles/introduction":{"id":"profiles/introduction","title":"Una Introducci\xf3n a los Perfiles de Cwtch","description":"Con Cwtch puedes crear uno o m\xe1s Perfiles. Cada perfil genera un par de claves aleatorias ed25519 compatibles con la Red Tor.","sidebar":"tutorialSidebar"},"profiles/profile-info":{"id":"profiles/profile-info","title":"Setting Profile Attributes","description":"This functionality is currently only available in the Nightly Release builds of Cwtch.","sidebar":"tutorialSidebar"},"profiles/unlock-profile":{"id":"profiles/unlock-profile","title":"Desbloquear perfiles cifrados","description":"Cuando reinicies Cwtch, si usaste una contrase\xf1a para proteger tu perfil, no se cargar\xe1 por defecto y necesitar\xe1s desbloquearlo.","sidebar":"tutorialSidebar"},"servers/create-server":{"id":"servers/create-server","title":"C\xf3mo crear un servidor","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"servers/delete-server":{"id":"servers/delete-server","title":"C\xf3mo eliminar un servidor","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"servers/edit-server":{"id":"servers/edit-server","title":"C\xf3mo editar un servidor","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"servers/introduction":{"id":"servers/introduction","title":"Introducci\xf3n a Servidores","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"servers/share-key":{"id":"servers/share-key","title":"C\xf3mo compartir tu Paquete de Claves del Servidor","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"servers/unlock-server":{"id":"servers/unlock-server","title":"C\xf3mo desbloquear un servidor","description":"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.","sidebar":"tutorialSidebar"},"settings/appearance/change-language":{"id":"settings/appearance/change-language","title":"Cambiar idioma","description":"Gracias a la ayuda de voluntarios, la aplicaci\xf3n Cwtch ha sido traducida a muchos idiomas.","sidebar":"tutorialSidebar"},"settings/appearance/light-dark-mode":{"id":"settings/appearance/light-dark-mode","title":"Explicaci\xf3n de temas Claros/Oscuros","description":"1. Pulsa el icono de configuraci\xf3n","sidebar":"tutorialSidebar"},"settings/appearance/streamer-mode":{"id":"settings/appearance/streamer-mode","title":"Modo de streaming/presentaci\xf3n","description":"El modo de streaming / presentaci\xf3n hace la aplicaci\xf3n m\xe1s visualmente privada. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens.","sidebar":"tutorialSidebar"},"settings/appearance/ui-columns":{"id":"settings/appearance/ui-columns","title":"Columnas de interfaz","description":"1. Pulsa el icono de configuraci\xf3n","sidebar":"tutorialSidebar"},"settings/behaviour/block-unknown-connections":{"id":"settings/behaviour/block-unknown-connections","title":"Bloquear Conexiones Desconocidas","description":"By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. Puede cambiar este comportamiento a trav\xe9s de la configuraci\xf3n de Bloquear Conexiones Desconocidas.","sidebar":"tutorialSidebar"},"settings/behaviour/notification-content":{"id":"settings/behaviour/notification-content","title":"Contenido de notificaciones","description":"1. Ir a la configuraci\xf3n","sidebar":"tutorialSidebar"},"settings/behaviour/notification-policy":{"id":"settings/behaviour/notification-policy","title":"Pol\xedtica de notificaciones","description":"1. Ir a la configuraci\xf3n","sidebar":"tutorialSidebar"},"settings/experiments/clickable-links":{"id":"settings/experiments/clickable-links","title":"Experimento de Enlaces Cliqueables","description":"Esta funci\xf3n, si est\xe1 activada, presenta un riesgo de desanonimizaci\xf3n.","sidebar":"tutorialSidebar"},"settings/experiments/file-sharing":{"id":"settings/experiments/file-sharing","title":"Compartir Archivos","description":"These setting enables Cwtch filesharing functionality. This reveals the \\"Share File\\" option in the conversation pane, and allows you to download files from conversations.","sidebar":"tutorialSidebar"},"settings/experiments/group-experiment":{"id":"settings/experiments/group-experiment","title":"Groups Experiment","description":"Enables Cwtch to connect to untrusted servers and use them to host private, asynchronous, groups.","sidebar":"tutorialSidebar"},"settings/experiments/image-previews-and-profile-pictures":{"id":"settings/experiments/image-previews-and-profile-pictures","title":"Vista previa de im\xe1genes y fotos de perfil","description":"This experiment requires the File Sharing experiment enabled.","sidebar":"tutorialSidebar"},"settings/experiments/message-formatting":{"id":"settings/experiments/message-formatting","title":"Formato de mensajes","description":"When enabled, this experiment changes the conversation compose box to add message formatting UX.","sidebar":"tutorialSidebar"},"settings/experiments/qrcodes":{"id":"settings/experiments/qrcodes","title":"QR Codes","description":"This documentation page is a stub. You can help by expanding it.","sidebar":"tutorialSidebar"},"settings/experiments/server-hosting":{"id":"settings/experiments/server-hosting","title":"Alojamiento de servidor","description":"El alojamiento del servidor es actualmente una caracter\xedstica experimental en Cwtch, no est\xe1 habilitado por defecto.","sidebar":"tutorialSidebar"},"settings/introduction":{"id":"settings/introduction","title":"Una Introducci\xf3n a la configuraci\xf3n de Cwtch","description":"Apariencia","sidebar":"tutorialSidebar"},"tor":{"id":"tor","title":"Tor","description":"Cwtch utiliza Tor para proporcionar enrutamiento y conexiones. Usar servicios ocultos de Tor para albergar perfiles y conexiones \\"ef\xedmeras\\" proporciona fuertes garant\xedas de anonimato a los usuarios de Cwtch a la hora de hacer conexiones.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/94594657.90c23965.js b/build-staging/es/assets/js/94594657.90c23965.js new file mode 100644 index 00000000..cd3794e4 --- /dev/null +++ b/build-staging/es/assets/js/94594657.90c23965.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5467],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),l=p(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[l]="string"==typeof e?e:o,s[1]=a;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:9},s="QR Codes",a={unversionedId:"settings/experiments/qrcodes",id:"settings/experiments/qrcodes",title:"QR Codes",description:"This documentation page is a stub. You can help by expanding it.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/qrcodes.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/qrcodes",permalink:"/es/docs/settings/experiments/qrcodes",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/qrcodes.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{sidebar_position:9},sidebar:"tutorialSidebar",previous:{title:"Formato de mensajes",permalink:"/es/docs/settings/experiments/message-formatting"},next:{title:"Tor",permalink:"/es/docs/tor"}},c={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"qr-codes"},"QR Codes"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9479ba79.bb5c5d71.js b/build-staging/es/assets/js/9479ba79.bb5c5d71.js new file mode 100644 index 00000000..e3482ec3 --- /dev/null +++ b/build-staging/es/assets/js/9479ba79.bb5c5d71.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6433],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),p=o,m=d["".concat(c,".").concat(p)]||d[p]||h[p]||i;return n?a.createElement(m,r(r({ref:t},u),{},{components:n})):a.createElement(m,r({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,r[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var a=n(7462),o=(n(7294),n(3905));const i={sidebar_position:2},r="Risk Model",s={unversionedId:"risk",id:"risk",title:"Risk Model",description:"Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/risk.md",sourceDirName:".",slug:"/risk",permalink:"/es/security/risk",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch Security Handbook",permalink:"/es/security/intro"},next:{title:"Cwtch Components",permalink:"/es/security/category/cwtch-components"}},c={},l=[{value:"Threat Model",id:"threat-model",level:2},{value:"Active Attacks",id:"active-attacks",level:3},{value:"Misrepresentation Attacks",id:"misrepresentation-attacks",level:4},{value:"A note on Physical Attacks",id:"a-note-on-physical-attacks",level:2}],u={toc:l},d="wrapper";function h(e){let{components:t,...i}=e;return(0,o.kt)(d,(0,a.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"risk-model"},"Risk Model"),(0,o.kt)("p",null,"Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking."),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(5448).Z,width:"1920",height:"1080"})),(0,o.kt)("p",null,"Cwtch was originally conceived as an extension of the metadata resistant protocol Ricochet to support asynchronous, multi-peer group communications through the use of discardable, untrusted, anonymous infrastructure."),(0,o.kt)("p",null,"Since then, Cwtch has evolved into a protocol in its own right, this section will outline the various known risks that Cwtch attempts to mitigate and will be heavily referenced throughout the rest of the document when discussing the various sub-components of the Cwtch Architecture."),(0,o.kt)("h2",{id:"threat-model"},"Threat Model"),(0,o.kt)("p",null,"It is important to identify and understand that metadata is ubiquitous in communication protocols, it is indeed necessary for such protocols to function efficiently and at scale. However, information that is useful to facilitating peers and servers is also highly relevant to adversaries wishing to exploit such information."),(0,o.kt)("p",null,"For our problem definition, we will assume that the content of a communication is encrypted in such a way that an adversary is practically unable to break (see ",(0,o.kt)("a",{parentName:"p",href:"/security/category/tapir"},"tapir")," and ",(0,o.kt)("a",{parentName:"p",href:"security/category/cwtch"},"cwtch")," for details on the encryption that we use, a and as such we will focus to the context to the communication metadata."),(0,o.kt)("p",null,"We seek to protect the following communication contexts:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Who is involved in a communication? It may be possible to identify people or simply device or network identifiers. E.g., \u201cthis communication involves Alice, a journalist, and Bob a government employee.\u201d."),(0,o.kt)("li",{parentName:"ul"},"Where are the participants of the conversation? E.g., \u201cduring this communication Alice was in France and Bob was in Canada.\u201d"),(0,o.kt)("li",{parentName:"ul"},"When did a conversation take place? The timing and length of communication can reveal a large amount about the nature of a call, e.g., \u201cBob a government employee, talked to Alice on the phone for an hour yesterday evening. This is the first time they have communicated.\u201d *How was the conversation mediated? Whether a conversation took place over an encrypted or unencrypted email can provide useful intelligence. E.g., \u201cAlice sent an encrypted email to Bob yesterday, whereas they usually only send plaintext emails to each other.\u201d"),(0,o.kt)("li",{parentName:"ul"},"What is the conversation about? Even if the content of the communication is encrypted it is sometimes possible to derive a probable context of a conversation without knowing exactly what is said, e.g. \u201ca person called a pizza store at dinner time\u201d or \u201csomeone called a known suicide hotline number at 3am.\u201d")),(0,o.kt)("p",null,"Beyond individual conversations, we also seek to defend against context correlation attacks, whereby multiple conversations are analyzed to derive higher level information:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Relationships: Discovering social relationships between a pair of entities by analyzing the frequency and length of their communications over a period of time. E.g. Carol and Eve call each other every single day for multiple hours at a time."),(0,o.kt)("li",{parentName:"ul"},"Cliques: Discovering social relationships between a group of entities that all interact with each other. E.g. Alice, Bob and Eve all communicate with each other."),(0,o.kt)("li",{parentName:"ul"},"Loosely Connected Cliques and Bridge Individuals: Discovering groups that communicate to each other through intermediaries by analyzing communication chains (e.g. everytime Alice talks to Bob she talks to Carol almost immediately after; Bob and Carol never communicate.)"),(0,o.kt)("li",{parentName:"ul"},"Pattern of Life: Discovering which communications are cyclical and predictable. E.g. Alice calls Eve every Monday evening for around an hour.")),(0,o.kt)("h3",{id:"active-attacks"},"Active Attacks"),(0,o.kt)("h4",{id:"misrepresentation-attacks"},"Misrepresentation Attacks"),(0,o.kt)("p",null,"Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks based around misrepresentation i.e. people pretending to be other people:"),(0,o.kt)("p",null,"A basic flow of one of these attacks is as follows, although other flows also exist:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Alice has a friend named Bob and another called Eve"),(0,o.kt)("li",{parentName:"ul"},"Eve finds out Alice has a friend named Bob"),(0,o.kt)("li",{parentName:"ul"},"Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)"),(0,o.kt)("li",{parentName:"ul"},'Eve calls this new account "Eve New Account" and adds Alice as a friend.'),(0,o.kt)("li",{parentName:"ul"},'Eve then changes her name on "Eve New Account" to "Bob"'),(0,o.kt)("li",{parentName:"ul"},'Alice sends messages intended for "Bob" to Eve\'s fake Bob account')),(0,o.kt)("p",null,"Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them is for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply ",(0,o.kt)("em",{parentName:"p"},"won't-happen"),"."),(0,o.kt)("p",null,"As such we aim to provide some user-experience hints in the ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," to guide people in making choices around whether to trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users."),(0,o.kt)("h2",{id:"a-note-on-physical-attacks"},"A note on Physical Attacks"),(0,o.kt)("p",null,"Cwtch does not consider attacks that require physical access (or equivalent) to the users machine as practically defendable. However, in the interests of good security engineering, throughout this document we will still refer to attacks or conditions that require such privilege and point out where any mitigations we have put in place will fail."))}h.isMDXComponent=!0},5448:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/4-698e941dd333a7200cddec8d926e9ca9.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/95c68178.210d403e.js b/build-staging/es/assets/js/95c68178.210d403e.js new file mode 100644 index 00000000..fc8ea156 --- /dev/null +++ b/build-staging/es/assets/js/95c68178.210d403e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6205],{3264:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"cwtch-stable-roadmap-update-june","metadata":{"permalink":"/es/blog/cwtch-stable-roadmap-update-june","source":"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","date":"2023-06-30T00:00:00.000Z","formattedDate":"30 de junio de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/es/blog/tags/planning"}],"readingTime":5.26,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","slug":"cwtch-stable-roadmap-update-june","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"nextItem":{"title":"Cwtch Beta 1.12","permalink":"/es/blog/cwtch-nightly-1-12"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the Cwtch Stable Roadmap\\n\\nBack in March we extended and updated several goals from [our January roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document \u2705 - [Release Process](https://docs.cwtch.im/developing/release/#official-releases)\\n - A Cwtch Packaging Document \u2705 - [Packaging Documentation](https://docs.cwtch.im/developing/release/)\\n - Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new [documentation style guide](/docs/contribute/documentation), and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries \u2705 - [Building a Cwtch App](https://docs.cwtch.im/developing/category/building-a-cwtch-app)\\n - Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. \\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129) \ud83d\udfe1 - currently in [active development](https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information \u2705 - released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12)\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593) \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12). We now believe these changes will be complete in Cwtch Beta 1.13.\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms) \ud83d\udfe1 - we have already launched an environment for testing [Tails](/docs/platforms/tails). Other platforms are underway.\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\n\\n## Next Steps, Refinements, Additional Work\\n\\nAs you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. \\n\\nOther work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.\\n\\nHowever, [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12) featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.\\n\\nThe work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.\\n\\nWe are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-12","metadata":{"permalink":"/es/blog/cwtch-nightly-1-12","source":"@site/blog/2023-06-16-cwtch-1.12.md","title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","date":"2023-06-16T00:00:00.000Z","formattedDate":"16 de junio de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"release","permalink":"/es/blog/tags/release"}],"readingTime":2.455,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","slug":"cwtch-nightly-1-12","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog13_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/es/blog/cwtch-stable-roadmap-update-june"},"nextItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/es/blog/cwtch-nightly-v.11-74"}},"content":"[Cwtch 1.12 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new features like [profile attributes](https://docs.cwtch.im/docs/profiles/profile-info), support for new platforms like [Tails](https://docs.cwtch.im/docs/platforms/tails), and multiple improvements to performance and stability.\\n\\n![](/img/devlog13.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n
\\n\\n[![](/img/picnic1.12.png)](/img/picnic1.12.png)\\n\\n
A screenshot of Cwtch 1.12
\\n
\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Profile Attributes** - profiles can now be augmented with [additional public information](https://docs.cwtch.im/docs/profiles/profile-info)\\n - **Availability Status** - you can now notify contacts that you [are **away** or **busy**](https://docs.cwtch.im/docs/profiles/availability-status)\\n - **Five New Supported Localizations**: **Japanese**, **Korean**, **Slovak**, **Swahili** and **Swedish**\\n - **Support for Tails** - adds an [OnionGrater](https://docs.cwtch.im/docs/platforms/tails) configuration and a new `CWTCH_TAILS` environment variable that enables special Tor behaviour.\\n- **Bug Fixes / Improvements:**\\n - Based on Flutter 3.10\\n - Inter is now the main UI font\\n - New Font Scaling setting\\n - New Network Management code to better manage Tor on unstable networks\\n - File Sharing Experiment Fixes\\n \\t- Fix performance issues for file bubble\\n \\t- Allow restarting of file shares that have timed out\\n \\t- Fix NPE in FileBubble caused by deleting the underlying file\\n \\t- Move from RetVal to UpdateConversationAttributes to minimze UI thread issues\\n - Updates to Linux install scripts to support more distributions\\n - Add a Retry Peer connection to prioritize connection attempts for certain conversations\\n - Updates to `_FlDartProject` to allow custom setting of Flutter asset paths\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Slovak**, **Spanish**, **Swahili**, **Swedish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Japanese** (29%), **Korean** (23%), **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n## Reproducible Bindings\\n\\nCwtch 1.12 is based on libCwtch version `libCwtch-autobindings-2023-06-13-10-50-v0.0.5`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-v.11-74","metadata":{"permalink":"/es/blog/cwtch-nightly-v.11-74","source":"@site/blog/2023-06-07-new-nightly.md","title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","date":"2023-06-07T00:00:00.000Z","formattedDate":"7 de junio de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/es/blog/tags/developer-documentation"}],"readingTime":1.845,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","slug":"cwtch-nightly-v.11-74","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog10_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.12","permalink":"/es/blog/cwtch-nightly-1-12"},"nextItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/es/blog/cwtch-developer-documentation"}},"content":"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog10.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-06-05-17-36-v1.11.0-74-g0406](https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/).\\n\\nThis version has a large number of improvements and bug fixes including:\\n\\n* A new Font Scaling setting\\n* Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.\\n* Updated UI font styles\\n* Dependency updates, including a new base of Flutter 3.10.\\n* A fix for stuck file downloading notifications on Android\\n* A fix for missing profile images in certain edge cases on Android\\n* Japanese, Swedish, and Swahili translation options\\n* A new retry peer connection button for prompting Cwtch to prioritize specific connections\\n* [Tails support](/docs/platforms/tails)\\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-developer-documentation","metadata":{"permalink":"/es/blog/cwtch-developer-documentation","source":"@site/blog/2023-04-28-developer-docs.md","title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","date":"2023-04-28T00:00:00.000Z","formattedDate":"28 de abril de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/es/blog/tags/developer-documentation"}],"readingTime":2.595,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","slug":"cwtch-developer-documentation","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/es/blog/cwtch-nightly-v.11-74"},"nextItem":{"title":"Availability Status and Profile Attributes","permalink":"/es/blog/availability-status-profile-attributes"}},"content":"One of the larger remaining goals outlined in our [Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. \\n\\nIn this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!\\n\\nWe are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog9.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Cwtch Development Handbook\\n\\nWe have created a new documentation section, [the developers handbook](/developing/intro). This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).\\n\\n### Release and Packaging Process\\n\\nThe new handbook features a breakdown of [Cwtch release processes](/developing/release) - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.\\n\\n### Cwtch Application Development and Cwtchbot v0.1.0!\\n\\nFor the first time ever we now have [comprehensive documentation on how to build a Cwtch Application](/developing/category/building-a-cwtch-app). This section of the development handbook covers everything from [choosing a Cwtch library](/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library), to [building your first application](/developing/building-a-cwtch-app/building-an-echobot).\\n\\nTogether with this new documentation we have also [released version 0.1 of the Cwtchbot framework](https://git.openprivacy.ca/sarah/cwtchbot), updating calls to use the [new Cwtch Stable API](/blog/cwtch-stable-api-design).\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-04-26-20-57-v1.11.0-33-gb4371](https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/).\\n\\nThis version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the [in-development Tails support](/docs/platforms/tails). \\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"availability-status-profile-attributes","metadata":{"permalink":"/es/blog/availability-status-profile-attributes","source":"@site/blog/2023-04-06-availability-and-profile-attributes.md","title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","date":"2023-04-06T00:00:00.000Z","formattedDate":"6 de abril de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"nightly","permalink":"/es/blog/tags/nightly"}],"readingTime":1.445,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","slug":"availability-status-profile-attributes","tags":["cwtch","cwtch-stable","nightly"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/es/blog/cwtch-developer-documentation"},"nextItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/es/blog/cwtch-stable-roadmap-update"}},"content":"Two new Cwtch features are now available to test in nightly: [Availability Status](/docs/profiles/availability-status) and [Profile Information](/docs/profiles/profile-info).\\n\\nAdditionally, we have also published draft guidance on [running Cwtch on Tails](/docs/platforms/tails) that we would like volunteers to test and report back on.\\n \\nThe Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like\\nours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Availability Status\\n\\nNew in this nightly is the ability to notify your conversations that you are \\"Away\\" or \\"Busy\\".\\n\\n
\\n\\n[![](/img/profiles/status-tooltip-busy-set.png)](/img/profiles/status-tooltip-busy-set.png)\\n\\n
\\n
\\n\\nRead more: [Availability Status](/docs/profiles/availability-status)\\n\\n## Profile Attributes\\n\\nAlso new is the ability to augment your profile with a few small pieces of **public** information.\\n\\n
\\n\\n[![](/img/profiles/attributes-set.png)](/img/profiles/attributes-set.png)\\n\\n
\\n
\\n\\nRead more: [Profile Information](/docs/profiles/profile-info)\\n \\n## Downloading the Nightly\\n\\n[Nightly builds](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. Download links for **2023-04-05-18-28-v1.11.0-7-g0290** are available below.\\n\\n* Windows: [https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/)\\n* Linux: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n* Mac: [https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/)\\n* Android: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-roadmap-update","metadata":{"permalink":"/es/blog/cwtch-stable-roadmap-update","source":"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","date":"2023-03-31T00:00:00.000Z","formattedDate":"31 de marzo de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/es/blog/tags/planning"}],"readingTime":5.61,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","slug":"cwtch-stable-roadmap-update","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Availability Status and Profile Attributes","permalink":"/es/blog/availability-status-profile-attributes"},"nextItem":{"title":"Cwtch Beta 1.11","permalink":"/es/blog/cwtch-nightly-1-11"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap](/blog/path-to-cwtch-stable) we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the January Roadmap\\n\\nBack in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)\\n\\n- By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705\\n- By **1st February 2023**, the Cwtch team will have [finalized a feature set that defines Cwtch Stable](/blog/cwtch-stable-api-design) and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705\\n- By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:\\n - [Security and Design Documents](/security/intro) \u2705\\n - Infrastructure and [Support](/docs/getting-started/supported_platforms) \ud83d\udfe1\\n - in addition to a new development blog. \u2705\\n- By **31st March 2023**, the Cwtch team will have created:\\n - a [style guide for documentation](/docs/contribute/documentation), and \u2705\\n - have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1\\n - with at least one screenshot (where applicable). \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have published: \\n - a Cwtch [Interface Specification Document](/blog/cwtch-stable-api-design) \u2705\\n - a Cwtch Release Process Document \ud83d\udfe1\\n - a Cwtch [Support Plan document](/blog/cwtch-platform-support) \u2705\\n - a Cwtch Packaging Document \ud83d\udfe1\\n - a document describing the [Reproducible Builds Process](/blog/cwtch-bindings-reproducible) \u2705\\n - These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705\\n- By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c\\n- By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)\\n\\nWhile we didn\'t hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:\\n\\n* [Cwtch Autobindings](/blog/autobindings) with [compile-time optional experiments](/blog/autobindings-ii)\\n* [Cwtch 1.11](/blog/cwtch-nightly-1-11) - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements.\\n* [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.\\n\\n## A Timeline for Cwtch Stable\\n\\nNow for the big news, we plan on releasing a candidate Cwtch Stable release during **Summer 2023**. Here is our plan for getting there:\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document\\n - A Cwtch Packaging Document\\n - Completion of documentation of existing Cwtch features, including relevant screenshots.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries\\n - Automatically generated API documentation for libCwtch\\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593)\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms)\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-11","metadata":{"permalink":"/es/blog/cwtch-nightly-1-11","source":"@site/blog/2023-03-29-cwtch-1.11.md","title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","date":"2023-03-29T00:00:00.000Z","formattedDate":"29 de marzo de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"release","permalink":"/es/blog/tags/release"}],"readingTime":2.365,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","slug":"cwtch-nightly-1-11","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog12_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/es/blog/cwtch-stable-roadmap-update"},"nextItem":{"title":"Updates to Cwtch Documentation","permalink":"/es/blog/cwtch-documentation"}},"content":"[Cwtch 1.11 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new [reproducible](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) and [automatically generated](https://docs.cwtch.im/blog/autobindings) bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.\\n\\n![](/img/devlog12.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n
\\n\\n[![](/img/picnic.png)](/img/picnic.png)\\n\\n
A screenshot of Cwtch 1.11
\\n
\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Based on new Reproducible Cwtch Stable Autobuilds** - this is the first release of cwtch based on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) in addition to our new [automatically generated](https://docs.cwtch.im/blog/autobindings)\\n - **Two New Supported Localizations**: **Slovak** and **Korean**\\n- **Bug Fixes / Improvements:**\\n - When preserving a message draft, quoted messages are now also saved\\n - Layout issues caused by pathological unicode are now prevented\\n - Improved performance of message row rendering\\n - Clickable Links: Links in replies are now selectable\\n - Clickable Links: Fixed error when highlighting certain URIs \\n - File Downloading: Fixes for file downloading and exporting on 32bit Android devices\\n - Server Hosting: Fixes for several layout issues\\n - Build pipeline now runs automated UI tests\\n - Fix issues caused by scrollbar controller overriding\\n - Initial support for the Blodeuwedd Assistant (currently compile-time disabled)\\n - Cwtch Library:\\n - [New Stable Cwtch Peer API](/blog/cwtch-stable-api-design)\\n - Ported File Downloading and Image Previews experiments into Cwtch\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Spanish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n\\n\\n## Reproducible Bindings\\n\\nCwtch 1.11 is based on libCwtch version `2023-03-16-15-07-v0.0.3-1-g50c853a`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-documentation","metadata":{"permalink":"/es/blog/cwtch-documentation","source":"@site/blog/2023-03-10-cwtch-documentation.md","title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","date":"2023-03-10T00:00:00.000Z","formattedDate":"10 de marzo de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"documentation","permalink":"/es/blog/tags/documentation"},{"label":"security-handbook","permalink":"/es/blog/tags/security-handbook"}],"readingTime":2.57,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","slug":"cwtch-documentation","tags":["cwtch","cwtch-stable","documentation","security-handbook"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.11","permalink":"/es/blog/cwtch-nightly-1-11"},"nextItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/es/blog/autobindings-ii"}},"content":"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.\\n\\n![](/img/devlog9.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Cwtch Secure Development Handbook\\n \\nOne of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.\\n\\nWe have [now ported the the handbook to this documentation site](/security/intro), along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. \\n\\n## Volunteer Development\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Next Steps\\n\\nWe still have more work to do on the documentation front:\\n\\n* Ensuring all pages [implement the new documentation style guide](/docs/contribute/documentation), and include appropriate screenshots and descriptions.\\n* Expanding the security handbook to provide information on [reproducible builds](/blog/cwtch-bindings-reproducible), [the new Cwtch Stable API](/blog/cwtch-stable-api-design) and upcoming improvements around fuzz testing.\\n* Creating new documentation sections on the [libCwtch autobindings API](/blog/autobindings) and building applications on top of Cwtch.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings-ii","metadata":{"permalink":"/es/blog/autobindings-ii","source":"@site/blog/2023-03-03-autobindings-optional-experiments.md","title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","date":"2023-03-03T00:00:00.000Z","formattedDate":"3 de marzo de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/es/blog/tags/bindings"},{"label":"autobindings","permalink":"/es/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/es/blog/tags/libcwtch"}],"readingTime":4.655,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","slug":"autobindings-ii","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Updates to Cwtch Documentation","permalink":"/es/blog/cwtch-documentation"},"nextItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/es/blog/autobindings"}},"content":"[Last time we looked at autobindings](https://docs.cwtch.im/blog/autobindings) we mentioned that one of the next steps was introducing support for **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)**. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## The Structure of an Application Experiment\\n\\nAn application-level experiment consists of:\\n\\n1. A set of top-level APIs, e.g. `CreateServer`, `LoadServer`, `DeleteServer` - these are the APIs that we want to expose to calling applications.\\n2. An encapsulating structure for the set of APIs, e.g. `ServersFunctionality` - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.\\n3. A global variable that exists at the top level of libCwtch, e.g. `var serverExperiment *servers.ServersFunctionality servers` - our single pointer to the underlying functionality.\\n4. A set of management-related APIs, e.g. `Init`, `UpdateSettings`, `OnACNEvent` - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).\\n5. Management code within `_startCwtch` and `_reconnectCwtch` that calls the management APIs on the global variable.\\n\\nFrom a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\\nof on `application` or a specific `profile`.\\n\\nMost of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.\\n\\n### New Required Management APIs\\n\\nTo achieve this weaving, we now require application-level experiments to implement an `EventHandlerInterface` interface and expose itself via an\\ninitialize constructor `Init(acn, appDir) -> EventHandlerInterface`, and `Enable(app, acn)`.\\n\\nFor now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.\\n\\nWe can then generate, and optionally include blocks of code like:\\n\\n\\t\\t = .Init(&globalACN, appDir)\\n\\t\\teventHandler.AddModule()\\n\\t\\t.Enable(application, &globalACN)\\n\\nand place them at specific points in the code. `EventHandler` has also been extended to maintain a collection of `modules` so that it can\\npass on interesting events.\\n\\n### Adding Support for Application Experiments in the Spec File\\n\\nWe have introduced a new `!` operator which can be used to gate APIs behind a configured experiment. Along with a new\\ntemplating option `exp` which will call the function on the configured experiment, and `global` to allow the setting up\\nof a global functionality within the library.\\n\\n\\t\\t# Server Hosting Experiment\\n\\t\\t!serverExperiment import \\"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\\"\\n\\t\\t!serverExperiment global serverExperiment *servers.ServersFunctionality servers\\n\\t\\t!serverExperiment exp CreateServer application password string:description bool:autostart\\n\\t\\t!serverExperiment exp SetServerAttribute application string:handle string:key string:val\\n\\t\\t!serverExperiment exp LoadServers application acn password\\n\\t\\t!serverExperiment exp LaunchServers application acn\\n\\t\\t!serverExperiment exp LaunchServer application string:handle\\n\\t\\t!serverExperiment exp StopServer application string:handle\\n\\t\\t!serverExperiment exp StopServers application\\n\\t\\t!serverExperiment exp DestroyServers\\n\\t\\t!serverExperiment exp DeleteServer application string:handle password\\n\\n### Generation-Time Inclusion\\n\\n Without any arguments provided `generate-bindings` will not generate code for any experiments.\\n\\n In order to determine what experimental code to generate, `generate-bindings` now interprets arguments as enabled compile time experiments, e.g. `generate-bindings serverExperiment` will turn on\\n generation of server hosting code, per the spec file above.\\n\\n### Cwtch UI Integration\\n\\nThe UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. `c_LoadServers` - if it doesn\'t then the UI is safe to assume the\\nfeature is not available.\\n\\n
\\n\\n![](/img/dev9-host-disabled.png)\\n\\n
A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.
\\n
\\n\\n## Nightlies & Next Steps\\n\\nWe are now publishing [nightlies](https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/) of autobinding derived libCwtch-go, along with [Repliqate scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2) for reproducibility.\\n\\nWith application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.\\n\\nHowever, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:\\n\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs).\\n * **Documentation generation**: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings","metadata":{"permalink":"/es/blog/autobindings","source":"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md","title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","date":"2023-02-24T00:00:00.000Z","formattedDate":"24 de febrero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/es/blog/tags/bindings"},{"label":"autobindings","permalink":"/es/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/es/blog/tags/libcwtch"}],"readingTime":4.545,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","slug":"autobindings","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/es/blog/autobindings-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/es/blog/cwtch-testing-ii"}},"content":"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to **automatically generate** these bindings: [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings).\\n\\nThis this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the [path to Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable).\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## A Brief History of Cwtch Bindings\\n\\nPrior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by [therecipe/qt](https://github.com/therecipe/qt). However, after encountering numerous\\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.\\n\\nAs part of early prototyping efforts for Flutter we built out a first version of [libCwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go), and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.\\n\\nThis approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular [experimental features](https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape) - handle settings, [duplication of logic between Cwtch and libCwtch-go](https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings), and [special behaviour in libCwtch-go that better belongs in the core Cwtch library](https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go).\\n\\nAs part of a broader effort to [refine the Cwtch API in preparation for Cwtch Stable](https://docs.cwtch.im/blog/cwtch-stable-api-design) we have taken the opportunity to fix many of these problems.\\n\\n## Cwtch Autobindings\\n\\nThe current `lib.go` file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the `BlockContact` API implementation is:\\n\\n\\t//export c_BlockContact\\n\\tfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\\n\\t\\tBlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\\n\\t}\\n\\n\\tfunc BlockContact(profileOnion string, conversationID int) {\\n\\t\\tprofile := application.GetPeer(profileOnion)\\n\\t\\tif profile != nil {\\n\\t\\t\\tprofile.BlockConversation(conversationID)\\n\\t\\t}\\n\\t}\\n\\nAll that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.\\n\\nIn the new [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings) we reduce these multiple lines to [a single one](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19):\\n\\n\\tprofile BlockConversation conversation\\n\\nDefining a `profile`-level function, called `BlockConversation` which takes in a single parameter of type `conversation`.\\n\\nUsing a similar boilerplate-reduction for the reset of `lib.go` yields [5-basic function prototypes](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format):\\n\\n* Application-level functions e.g. `CreateProfile`\\n* Profile-level functions e.g. `BlockConversation`\\n* Profile-level functions that return data e.g. `GetMessage`\\n* Experimental Profile-level feature functions e.g. `DownloadFile`\\n* Experimental Profile-level feature functions that return data e.g. `ShareFile`\\n\\nOnce aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be [described in fewer than 50 lines, including comments](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec). Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).\\n\\n## Next Steps\\n\\nCwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:\\n\\n * **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)** (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on `cwtch-server`). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don\'t support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart-side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs)\\n * **Documentation generation**: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n * **Cwtch API**: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the [Cwtch Stable API redesign](https://docs.cwtch.im/blog/cwtch-stable-api-design). In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-ii","metadata":{"permalink":"/es/blog/cwtch-testing-ii","source":"@site/blog/2023-02-17-cwtch-testing-ii.md","title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","date":"2023-02-17T00:00:00.000Z","formattedDate":"17 de febrero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"support","permalink":"/es/blog/tags/support"},{"label":"testing","permalink":"/es/blog/tags/testing"}],"readingTime":1.75,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","slug":"cwtch-testing-ii","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog7_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/es/blog/autobindings"},"nextItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/es/blog/cwtch-android-reproducibility"}},"content":"In this development log, we investigate some text-based UI bugs encountered by [Fuzzbot](https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot), add more [automated UI tests](/blog/cwtch-testing-i) to the pipeline, and announce a new release of the Cwtchbot library.\\n\\n![](/img/devlog7.png)\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Constraining Cwtch UI Fields\\n\\nFuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\\ndoesn\'t pose a safety issue, it is unsightly.\\n\\n
\\n\\n[![](/img/dl7-before.png)](/img/dl7-before.png)\\n\\n
Screenshot demonstrating how certain strings would violate the bounds of their containers.
\\n
\\n\\nThese cases were fixed by parenting impacted elements in a `Container` with `clip: hardEdge` and `decoration:BoxDecoration()` (note that both of these are required as Container widgets in Flutter cannot set clipping logic\\nwithout an associated decoration).\\n\\n
\\n\\n[![](/img/dl7-after.png)](/img/dl7-after.png)\\n\\n
Now these clipped strings are tightly constrained to their container bounds.
\\n
\\n\\nThese fixes are available in the [latest Cwtch Nightly](/docs/contribute/testing#cwtch-nightlies), and will be officially released in Cwtch 1.11.\\n\\n## More Automated UI Tests\\n\\nWe have added two new sets of automated UI tests to our pipeline:\\n\\n- *02: Global Settings* - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. ([PR: 628](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628))\\n- *04: Profile Management* - these tests check that creating, unlocking, and deleting a profile work as expected. ([PR: 632](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632))\\n\\n## New Release of Cwtchbot\\n\\n[Cwtchbot](https://git.openprivacy.ca/sarah/cwtchbot) has been updated to use the latest Cwtch 0.18.10 API.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-android-reproducibility","metadata":{"permalink":"/es/blog/cwtch-android-reproducibility","source":"@site/blog/2023-02-10-android-reproducibility.md","title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","date":"2023-02-10T00:00:00.000Z","formattedDate":"10 de febrero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/es/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/es/blog/tags/bindings"},{"label":"repliqate","permalink":"/es/blog/tags/repliqate"}],"readingTime":2.92,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","slug":"cwtch-android-reproducibility","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog6_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/es/blog/cwtch-testing-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing","permalink":"/es/blog/cwtch-testing-i"}},"content":"In this development log, we continue our previous work on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible), uncovering the final few sources of variation between our [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!\\n\\n![](/img/devlog6.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Changes Necessary for Reproducible Android Bindings\\n\\nAfter a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:\\n\\n- **Insufficient path stripping introduced by Android NDK tools** - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 [changed the binutils and default linker](https://github.com/android/ndk/wiki/Changelog-r22) to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our [long term support plan](https://docs.cwtch.im/blog/cwtch-platform-support), we will be moving towards adopting the latest NDK in the future.\\n- **Paths in DWARF entries** - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.\\n\\n
\\n\\n[![](/img/aar-diff.png)](/img/aar-diff.png)\\n\\n
Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
\\n
\\n\\n- **Go Compiler Acquisition** - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there *was* a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.\\n\\n## Repliqate Scripts\\n\\nWith those issues now fixed, Cwtch Android bindings are **officially reproducible!** The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under [cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script) in the [Cwtch Repliqate scripts repository](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/).\\n\\nThis is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-i","metadata":{"permalink":"/es/blog/cwtch-testing-i","source":"@site/blog/2023-02-03-cwtch-testing-i.md","title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","date":"2023-02-03T00:00:00.000Z","formattedDate":"3 de febrero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"support","permalink":"/es/blog/tags/support"},{"label":"testing","permalink":"/es/blog/tags/testing"}],"readingTime":4.74,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","slug":"cwtch-testing-i","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog5_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/es/blog/cwtch-android-reproducibility"},"nextItem":{"title":"Cwtch UI Platform Support","permalink":"/es/blog/cwtch-platform-support"}},"content":"We first [introduced UI tests last January](https://openprivacy.ca/discreet-log/23-cucumber-testing/). At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.\\n\\nOne of the main threads of work that needs to be complete early in the [Cwtch Stable roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.\\n\\n![](/img/devlog5.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Current Limitations of Flutter Gherkin\\n\\nThe original [flutter_gherkin](https://pub.dev/packages/flutter_gherkin) is under semi-active development; however, the latest published versions don\'t support using it with `flutter test`.\\n\\n- **Flutter Test** was originally intended to run single widget/unit tests for a Flutter project.\\n- **Flutter Drive** was originally intended to run integration tests *on a device or an emulator*.\\n\\nHowever, in recent releases these lines have become blurred. The new [integration_test](https://docs.flutter.dev/testing/integration-tests) package that comes built into newer Flutter releases has support for both `flutter drive` and `flutter test`. This was a great change because it decreases the required overhead to run larger integration tests (`flutter drive` sets up a host-controller model that requires a dedicated control channel to be setup, whereas `flutter test` can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).\\n\\nThere is thankfully code in the `flutter_gherkin` repository that supports running tests with `flutter test`, however this code currently has a few issues:\\n\\n- The test code generation produces code that doesn\'t compile without minor changes.\\n- Certain functionality like \\"take a screenshot\\" does not work on desktop.\\n\\nAdditionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:\\n\\n- Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.\\n- Certain Flutter widgets like `DropdownButton` are not compatible with built-in steps like `tap` because they internally contain multiple copies of the same widget.\\n\\nBecause of the above issues we have chosen to [fork flutter_gherkin](https://git.openprivacy.ca/openprivacy/flutter_gherkin) to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.\\n\\n## Integrating Tests into the Pipeline\\n\\nOne of the major limitations of `flutter test` is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.\\n\\nThankfully it is possible to use [Xfvb](https://en.wikipedia.org/wiki/Xvfb) to create a virtual framebuffer, and set `DISPLAY` to render to that buffer:\\n\\n export DISPLAY=:99\\n Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\\n\\nThis allows us to neutralize our main issue with `flutter test`, and efficiently run tests in our pipeline.\\n\\n## Catching Bugs!\\n\\nThis small amount of integration work has already caught its first bug.\\n\\nOnce we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. [02_save_load.feature](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature) simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.\\n\\nThe cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory `$USER_HOME/Downloads` didn\'t exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.\\n\\nAs we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!\\n\\n## Next Steps\\n\\n- **More automated tests:** We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.\\n- **More platforms:** Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across [our target platforms](https://docs.cwtch.im/docs/getting-started/supported_platforms). We expect to start this work soon; expect more news in a future Cwtch Testing update!\\n\\n- **More steps:** One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the `expect to see the message` step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. `send a file` or `set profile picture`.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-platform-support","metadata":{"permalink":"/es/blog/cwtch-platform-support","source":"@site/blog/2023-01-27-platform-support.md","title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","date":"2023-01-27T00:00:00.000Z","formattedDate":"27 de enero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"support","permalink":"/es/blog/tags/support"}],"readingTime":10.535,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","slug":"cwtch-platform-support","tags":["cwtch","cwtch-stable","support"],"image":"/img/devlog4_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing","permalink":"/es/blog/cwtch-testing-i"},"nextItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/es/blog/cwtch-bindings-reproducible"}},"content":"One of the [tenets for Cwtch Stable is **Universal Availability and Cohesive Support**](https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable):\\n\\n> \\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\"\\n\\nThis development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.\\n\\nThe questions we aim to answer in this post are: \\n\\n- What systems do we currently support?\\n- How do we decide what systems are supported?\\n- How do we handle new OS versions?\\n- How does application support differ from library support?\\n- What blockers exist for systems we wish to support, but currently cannot e.g ios?\\n\\n![](/img/devlog4.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Constraints on support\\n\\nFrom CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. \\n\\nIn this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.\\n\\n### Limitations on general-purpose computing \\n\\nIn order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to *other* onion services). \\n\\nOn desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, **blocked entirely**. \\n\\nThis is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.\\n\\nWhile we expect that [Arti](https://gitlab.torproject.org/tpo/core/arti) will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. \\n\\nAs Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.\\n\\nWe encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don\'t place restrictions on what you can do with your own device.\\n\\n### Constraints introduced by the Flutter SDK\\n\\nThe Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by [platforms that are supported by the Flutter SDK](https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms).\\n\\nTo summarize, as of writing this document those platforms are:\\n\\n- Android API 16 and above (arm, arm64, and amd64)\\n- Debian-based Linux Distributions (64-bit only)\\n- macOS El Capitan (10.11) and above\\n- Windows 7 & above (64-bit only)\\n\\nTo put it plainly, without porting Cwtch UI to a different UI platform **we cannot support a 32-bit desktop version**.\\n\\n### Constraints introduced by Appstore Policy \\n\\nAs of writing, [Google is pushing applications to target API 31 or above](https://developer.android.com/google/play/requirements/target-sdk). This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.\\n\\n### CPU Architecture and Cwtch Bindings\\n\\nWe currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.\\n\\nIt is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.\\n\\n| Architecture / Platform | Windows | Linux | macOS | Android |\\n|--------------------------|---------|-----|-------| -------------|\\n| arm | \u274c | \u274c | \u274c | \u2705\ufe0f| \\n| arm64 | \u274c | \ud83d\udfe1 | \u2705 | \u2705\ufe0f | \\n| x86-64 / amd64 | \u2705 | \u2705 | \u2705\ufe0f | \u2705\ufe0f |\\n\\n\\"\ud83d\udfe1\\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).\\n\\n### Testing and official support\\n\\nAs a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the [Cwtch Release Candidate Testers](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.\\n\\nWe officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.\\n\\n### End-of-life platforms\\n\\nOperating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. [Windows 7 fell out of support on January 14, 2020](https://www.microsoft.com/en-us/windows/end-of-support), Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.\\n\\nLikewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.\\n\\nThe same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. [Cwtch currently requires libc 2.31+](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations).\\n\\nAndroid versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our [Cwtch Release Candidate Testers groups](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to help us understand the limitations of Android support across different API versions.\\n\\n## How we decide to officially support a platform\\n\\nTo help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:\\n\\n1. **The target platform needs to be officially supported by our development tools** - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.\\n2. **The target operating system needs to be supported by the Vendor** - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).\\n3. **The target platform must be backwards compatible with the most recent version in general use** - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch *may* run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).\\n4. **People want to use Cwtch on that platform** - We will generally only consider new platform support if people ask us about it. If Cwtch isn\'t available for a platform you want to use it on, then please get in touch and ask us about it!\\n\\n## Summary of official support\\n\\nThe table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). \\n\\nIn many cases we are looking for testers to confirm that various functionality works. A version of this table will be [maintained as part of the Cwtch Handbook](/docs/getting-started/supported_platforms).\\n\\n**Legend:**\\n\\n- \u2705: **Officially Supported**. Cwtch should work on these platforms without issue. Regressions are treated as high priority.\\n- \ud83d\udfe1: **Best Effort Support**. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.\\n- \u274c: **Not Supported**. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.\\n\\n\\n\\n| Platform | Official Cwtch Builds | Source Support | Notes |\\n|-----------------------------|-----------------------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------|\\n| Windows 11 | \u2705 | \u2705 | 64-bit amd64 only. |\\n| Windows 10 |\u2705 | \u2705 | 64-bit amd64 only. Not officially supported, but official builds may work. |\\n| Windows 8 and below | \u274c | \ud83d\udfe1 | Not supported. Dedicated builds from source may work. Testing Needed. |\\n| OSX 10 and below | \u274c | \ud83d\udfe1 | 64-bit Only. Official builds have been reported to work on Catalina but not High Sierra |\\n| OSX 11 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 12 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 13 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| Debian 11 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Debian 10 | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. |\\n| Debian 9 and below | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies. |\\n| Ubuntu 22.04 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Other Ubuntu | \ud83d\udfe1 | \u2705 | 64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies. | \\n| CentOS | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Gentoo | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Arch | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Whonix | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support. ](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550) |\\n| Raspian (arm64) | \ud83d\udfe1 | \u2705 | Builds from source work. |\\n| Other Linux Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Android 9 and below | \ud83d\udfe1 | \ud83d\udfe1 | Official builds may work. |\\n| Android 10 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 11 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 12 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 13 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| LineageOS | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support.](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607) |\\n| Other Android Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-bindings-reproducible","metadata":{"permalink":"/es/blog/cwtch-bindings-reproducible","source":"@site/blog/2023-01-20-reproducible-builds-bindings.md","title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","date":"2023-01-20T00:00:00.000Z","formattedDate":"20 de enero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/es/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/es/blog/tags/bindings"},{"label":"repliqate","permalink":"/es/blog/tags/repliqate"}],"readingTime":7.915,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","slug":"cwtch-bindings-reproducible","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog3_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch UI Platform Support","permalink":"/es/blog/cwtch-platform-support"},"nextItem":{"title":"Cwtch Stable API Design","permalink":"/es/blog/cwtch-stable-api-design"}},"content":"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.\\n\\nBut open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.\\n\\nThe whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can **independently verify** that the binaries we release are built from the Cwtch source code.\\n\\nIn this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.\\n\\n\x3c!--truncate--\x3e\\n\\n## How Cwtch Bindings are Built\\n\\nSince we launched Cwtch Beta we have used Docker containers as part of our continuous build process.\\n\\nWhen a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.\\n\\nThe Cwtch Bindings build pipeline results in four compiled libraries:\\n\\n- **libcwtch.so** \u2013 For Linux Platforms, built using the [official golang:1.19.X Docker Image](https://hub.docker.com/_/golang)\\n- **libcwtch.dll** \u2013 For Windows Platforms, built using our own [mingw-go Docker Image](https://git.openprivacy.ca/openprivacy/mingw-go)\\n- **libcwtch.ld** \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)\\n- **cwtch.aar** \u2013 For Android Platforms, built using our own [Android/GoMobile Docker Image](https://git.openprivacy.ca/openprivacy/android-go-mobile)\\n\\nThese compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.\\n\\n## Making libCwtch Reproducible\\n\\nDocker containers alone aren\'t enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:\\n\\n* **Go Build ID**: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.\\n* **Build Paths and Go Environment Variables**: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the `trimPath` option, which we now specify for all bindings builds.\\n\\n### Linux Specific Considerations\\n\\nAfter the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.\\n\\nOur Drone/Docker build environments are based on [Debian Bullseye](https://www.debian.org/releases/bullseye/) which provides [libc6-dev version 2.31](https://packages.debian.org/bullseye/i386/libc6-dev). Other development setups will likely link libc-dev 2.34+.\\n\\nlibc6-dev 2.34 is notable [because it removed dependencies on libpthread and libdl](https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread) \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.\\n\\nThis means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on [Next Steps](#next-steps) for more information).\\n\\n### Windows Specific Considerations\\n\\nThe headers of PE files technically contain a timestamp field. In recent years an [effort has been made to use this field for other purposes](https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705), but by default `go build` will still include the timestamp of the file when producing a DLL file (at least when using CGO).\\n\\nFortunately this field can be zeroed out through passing `-Xlinker \u2013no-insert-timestamp` into the `mingw32-gcc` process.\\n\\nWith that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.\\n\\n\\n### Android Specific Considerations\\n\\nWith the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:\\n\\n* Cwtch makes use of [GoMobile](https://github.com/golang/mobile) for compiling Android libraries. We pin to a specific version `43a0384520996c8376bfb8637390f12b44773e65` in our Docker containers. Unlike `go build`, the `trimpPath` parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized `/tmp/go-build*` references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.\\n* We still use [sdk-tools](https://developer.android.com/studio/releases/sdk-tools) instead of the new [commandline-tools](https://developer.android.com/studio/command-line). The latest version of sdk-tools is `4333796` and available from: [https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip](https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip). As part of our plans for Cwtch Stable we will be updating this dependency.\\n* Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated `openjdk:8` image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. \\n\\nAll of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.\\n\\n### OSX Specific Considerations\\n\\nPerhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.\\n\\nAs with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.\\n\\nIn order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.\\n\\nIn an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a [proprietary SDK](https://www.apple.com/legal/sla/docs/xcode.pdf). There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.\\n\\nBecause of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.\\n\\n## Introducing Repliqate!\\n\\nWith all the above changes, **Cwtch Bindings for Linux and Windows are fully reproducible!**\\n\\nThat alone is great, but we also want to make it easier for **you** to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.\\n\\nTo make this process accessible we are releasing a new tool called [repliqate](https://git.openprivacy.ca/openprivacy/repliqate).\\n\\nRepliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.\\n\\nRepliqate runs [build-scripts](https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script) to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from [builds.openprivacy.ca](https://build.openprivacy.ca/files/).\\n\\nWe now provide [Repliqate build-scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts) for reproducible both [Linux libCwtch.so builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script), [Windows libCwtch.dll builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script)!\\n\\nWe also have a partially repeatable [Android cwtch.aar build](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script) script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.\\n\\nYou can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.\\n\\n## Next Steps\\n\\nReproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.\\n\\nAs we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-api-design","metadata":{"permalink":"/es/blog/cwtch-stable-api-design","source":"@site/blog/2023-01-13-cwtch-stable-api-design.md","title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","date":"2023-01-13T00:00:00.000Z","formattedDate":"13 de enero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/es/blog/tags/planning"},{"label":"api","permalink":"/es/blog/tags/api"}],"readingTime":17.28,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","slug":"cwtch-stable-api-design","tags":["cwtch","cwtch-stable","planning","api"],"image":"/img/devlog2_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/es/blog/cwtch-bindings-reproducible"},"nextItem":{"title":"Path to Cwtch Stable","permalink":"/es/blog/path-to-cwtch-stable"}},"content":"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. \\n\\nAs we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.\\n\\nAs we move out of Beta and [towards Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable) it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.\\n\\nIn this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.\\n\\n![](/img/devlog2.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Clarifying Terminology\\n\\nOver the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:\\n\\n- **Cwtch** refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. \\n- **Cwtchlib** refers to the [reference implementation of the Cwtch Protocol](https://git.openprivacy.ca/cwtch.im/cwtch) / Application framework, currently written in Go.\\n- **Bindings** refers to C/Java/Kotlin/Rust bindings (primarily [libcwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go)) that act as an interface between Cwtchlib and downstream applications.\\n- `CwtchPeer` is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).\\n- `ProtocolEngine` is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, `ProtocolEngine` is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.\\n\\n\\n### Tenets of the Cwtch API Design\\n\\nBased on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:\\n\\n- **Robustness** - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.\\n- **Completeness** - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.\\n- **Security** \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.\\n\\n### The Cwtch Experiment Landscape\\n\\nA summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.\\n\\n- **Groups** \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized `ProtocolEngine` functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. \\n - **Hybrid Groups** - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.\\n- **Filesharing** \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in `ProtocolEngine`.\\n- **Profile Images** \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.\\n- **Server Hosting** \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.\\n- **Message Formatting** \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history\\n- **Search / Microblogging** \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.\\n- **Status / Profile Metadata** \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.\\n\\n### The Problem with Experiments\\n\\nWe have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the `SendMessages` interface that only allows callers to send messages.\\n\\nWe have also worked to package experimental functionality into so-called **Gated Functionalities** that are only available if a given experiment is turned on.\\n\\nTogether, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:\\n\\n- The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. `SendMessages` \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).\\n- The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.\\n- This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.\\n\\n### Restricting Powerful Cwtch APIs\\n\\nTo carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:\\n\\n- Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through `Application` and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.\\n- Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a `RestrictedCwtchConversationInterface` which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact.\\n- Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow `CwtchPeer` to control which experiments get access to which events at a given time.\\n\\n#### Pre-Registered Hooks\\n\\nIn order to implement certain functionality actions need to take place in-between events handled by `CwtchPeer`. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).\\n\\nThis is currently only possible with invasive changes to the `CwtchPeer` interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.\\n\\nWe are introducing a new set of Cwtch APIs designed for this purpose:\\n\\n- `OnNewPeerMessage` - hooked prior to inserting the message into the database.\\n- `OnPeerMessageConfirmed` \u2013 hooked after a peer message has been inserted into the database.\\n- `OnEncryptedGroupMessage` \u2013 hooked after receiving an encrypted message from a group server.\\n- `OnGroupMessageReceived` \u2013 hooked after a successful decryption of a group message, but before inserting it into the database.\\n- `OnContactRequestValue` \u2013 hooked on request of a scoped (the permission level of the attribute e.g. `public` or `conversation` level attributes), zoned ( relating to a specific feature e.g. `filesharing` or `chat`), and keyed (the name of the attribute e.g. `name` or `manifest`) value from a contact.\\n- `OnContactReceiveValue` \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.\\n\\nIncluding the following APIs for managing hooked functionality:\\n\\n- `RegisterEvents` - returns a set of events that the extension is interested processing.\\n- `RegisterExperiments` - returns a set of experiments that the extension is interested in being notified about\\n- `OnEvent` - to be called by `CwtchPeer` whenever an event registered with `RegisterEvents` is called (assuming all experiments registered through `RegisterExperiments` is active)\\n\\n#### `ProtocolEngine` Subsystems\\n\\nAs mentioned in our experiment summary, some functionality needs to be implemented directly in the `ProtocolEngine`. The `ProtocolEngine` is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).\\n\\nSome types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a `ProtocolEngine`.\\n\\nAt the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to `ProtocolEngine` that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider `ProtocolEngine` ecosystem. \\n\\nWe are formalizing this subsystem into an interface, similar to the hooked functionality in `CwtchPeer`:\\n\\n- `RegisterEvents` - returns a set of events that the subsystem needs to consume to operate.\\n- `OnEvent` \u2013 to be called by `ProtocolEngine` whenever an event registered with `RegisterEvents` is called (when all the experiments registered through `RegisterExperiments` are active)\\n- `RegisterContexts` - returns the set of contexts that the subsystem implements e.g. `im.cwtch.filesharing`\\n\\nThis also requires a formalization of two *engine specific* events (for use on the event bus):\\n\\n- `SendCwtchMessage` \u2013 encapsulating the existing `CwtchPeerMessage` that is used internally in `ProtocolEngine` for messages between subsystems.\\n- `CwtchMessageReceived` \u2013 encapsulating the existing `handlePeerMessage` function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.\\n\\nAnd the introduction of three **additional** `ProtocolEnine` specific events:\\n\\n- `StartEngineSubsystem` \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.\\n- `StopEngineSubsystem` \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.\\n- `SubsystemStatus` \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging\\n\\nThis will allow us to move the following functionality, currently part of `ProtocolEngine` itself, into generic subsystems:\\n\\n- **Attribute Lookup Handling** - this functionality is currently part of the overloaded `handlePeerMessage` function, filtered using the `Context` parameter of the `CwtchPeerMessage`. As such it can be entirely delegated to a subsystem. \\n- **Filesharing Chunk Request Handling** \u2013 this is also part of handlePeerMessage, also filtered using the `Context` parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by `handlePeerMessage`)\\n- **Filesharing Start File Share/Stop File Share** \u2013 this is currently part of the `handleEvent` behaviour of `ProtocolEngine` and can be moved into an `OnEvent` handler of the file sharing subsystem (where such events are already processed).\\n\\nThe introduction of pre-registered hooks in combination with the formalizations of `ProtocolEngine` subsystems will allow the follow functionality, currently implemented in `CwtchPeer` or libcwtch-go to be moved to standalone packages:\\n\\n- **Filesharing** makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. \\n - Filesharing also depends on the file sharing subsystem to be enabled in a `ProtocolEngine`. This subsystem is responsible for processing chunk requests.\\n- **Profile Images** \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)\\n- **Legacy Groups** \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.\\n- **Status/Profile Metadata** \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.\\n \\n#### Impact on Enabling (Powerful) New Functionality\\n\\nNone of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:\\n\\n- **Search** \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.\\n- **Non Chat Conversation Contexts** - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.\\n\\n## Application Experiments\\n\\nOne kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers.\\n\\nThis kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library.\\n\\nThis functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.\\n\\n## Bindings\\n\\nThe last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.\\n\\nWe can split the bindings into four core areas:\\n\\n- **Application Management** - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.\\n- **Application Experiments** - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.\\n- **Core Profile Management** - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.\\n- **Experimental Profile Features** \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.\\n\\nThe flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.\\n\\nIn an ideal future, all of these bindings could be **generated automatically** from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)\\n\\nWe can define three types of C/Java/Kotlin interface function templates:\\n\\n- `ProfileMethodName(profilehandle String, args...)` \u2013 which directly resolves the Cwtch Profile and calls the function.\\n- `ProfileExperimentalMethodName(profilehandle String, args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.\\n- `ApplicationExperimentalMethodName(args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.\\n\\nAll we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context `ProfileInterface` for the first, exported methods of the various `Functionalities` for the second, and `ApplicationExperiment` definitions for the third.\\n\\n## Timelines and Next Actions\\n\\n- **Freeze any changes to the bindings interface** - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib.\\n- As part of Cwtch 1.11 and 1.12 Release Cycles\\n - Implement the `ProtocolEngine` Subsystem Design as outlined above.\\n - Implement the Hooks API.\\n - Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting).\\n - Move event handling from the bindings into Application.\\n - Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions.\\n- Once Automated UI Tests have been integrated into the Cwtch UI Repository:\\n - Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings **and** a dart calling convention library from cwtchlib and any configured application experiments libraries\\n - Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).\\n - At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)\\n\\n## Appendix A: Special Behaviour Defined by libcwtch-go\\n\\nThe following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:\\n\\n- Application Settings\\n - Including Enabling / Disabling Experiment\\n- ACN Process Management - starting/stopping/restarting/configuring Tor.\\n- Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)\\n- Logging Levels - configuring appropriate logging levels (e.g. `INFO` or `DEBUG`)\\n- Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.\\n- UI Contact Structures - aggregating contact information for the main Cwtch UI.\\n- Group Experiment Functionality\\n - Experiment Gating\\n - GetServerInfoList\\n - GetServerInfo\\n - UI Server Struct Definition\\n- Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.\\n- \\"Unencrypted\\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \\"unencrypted\\".\\n- Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).\\n- Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.\\n- Cwtch Profile Engine Activation - starting/stopping a `ProtocolEngine` when requested by the UI, or in response to changes in ACN state.\\n- UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.\\n- File sharing restarts \\n- UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn\'t directly embedded within the event (e.g. converting `handle` to a `conversation id`). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.\\n- Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)"},{"id":"path-to-cwtch-stable","metadata":{"permalink":"/es/blog/path-to-cwtch-stable","source":"@site/blog/2023-01-06-path-to-cwtch-stable.md","title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","date":"2023-01-06T00:00:00.000Z","formattedDate":"6 de enero de 2023","tags":[{"label":"cwtch","permalink":"/es/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/es/blog/tags/planning"}],"readingTime":9.995,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","slug":"path-to-cwtch-stable","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable API Design","permalink":"/es/blog/cwtch-stable-api-design"}},"content":"As of December 2022 we have released 10 versions of Cwtch Beta since the [initial launch, 18 months ago, in June 2021](https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/).\\n\\nThere is a consensus among the team that the next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable.\\n\\nThis post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.\\n\\n![](/img/devlog1.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Tenets of Cwtch Stable\\n\\nIt is important to state that Cwtch Stable **does not mean an end to Cwtch development**. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:\\n\\n1. **Consistent Interface** \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.\\n2. **Universal Availability and Cohesive Support** \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\n3. **Reproducible Builds** \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.\\n4. **Proven Security** \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.\\n\\n### Known Problems\\n\\nTo begin, let\'s outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.\\n\\n1. **Lack of a Stable API for future feature development** \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)\\n2. **Special functionality in libCwtch-go** \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)\\n3. **libCwtch-rs partial support** - we currently do not officially consider [libCwtch-rs](https://lib.rs/crates/libcwtch) when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)\\n4. **Lack of Reproducible Pipelines** - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)\\n5. **Lack of up to date, and translated, Security Documentation** \u2013 the [Cwtch security handbook](https://docs.openprivacy.ca/cwtch-security-handbook/) is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)\\n6. **No Automated UI Tests** \u2013 we put a lot of work into [building out a testing framework for the UI](https://openprivacy.ca/discreet-log/23-cucumber-testing/), but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)\\n7. **Code Signing Provider** \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)\\n8. **Second-class Android Support** - while we have put [a lot of effort behind Android support](https://openprivacy.ca/discreet-log/27-android-improvements/) across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)\\n9. **Lack of Fuzzing** \u2013 while [Fuzzbot](https://openprivacy.ca/discreet-log/07-fuzzbot/) sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)\\n10. **Lack of Formal Release Acceptance Process** \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)\\n11. **Inconsistent Cwtch Information Discovery** \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)\\n12. **Incomplete Documentation** \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)\\n\\n### Plan of Action\\n\\nOutside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:\\n\\n1. **Define, Publish, and Implement a Cwtch Interface Specification Documentation** \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)\\n2. **Define, Publish, and Implement a Cwtch Release Process** \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)\\n3. **Define, Publish, and Implement a Cwtch Support Document** - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)\\n4. **Define, Publish, and Implement a Cwtch Packaging Document** - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)\\n5. **Define, Publish, and Implement a Reproducible Builds Document** \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)\\n6. **Expand the Cwtch Documentation Site** \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)\\n7. **Expand our Automated Testing to include UI and Fuzzing** - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)\\n8. **Re-evaluate all Issues across all Cwtch related repositories** \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.\\n9. **Define a Stable Feature Set** \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)\\n\\n### Goals and Timelines\\n\\nWith all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:\\n\\n1. By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).\\n2. By **1st February 2023**, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.\\n3. By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.\\n4. By **31st March 2023**, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).\\n5. By **31st March 2023** the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.\\n6. By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.\\n7. By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.\\n8. By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.\\n\\nAs these documents are written, and these goals met we will be posting them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, Cwtch development.\\n\\n### Help us get there!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"}]}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/95f63404.dce04067.js b/build-staging/es/assets/js/95f63404.dce04067.js new file mode 100644 index 00000000..f91e23b0 --- /dev/null +++ b/build-staging/es/assets/js/95f63404.dce04067.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7075],{1632:e=>{e.exports=JSON.parse('{"title":"Experiments","slug":"/category/experiments","permalink":"/es/docs/category/experiments","navigation":{"previous":{"title":"Contenido de notificaciones","permalink":"/es/docs/settings/behaviour/notification-content"},"next":{"title":"Groups Experiment","permalink":"/es/docs/settings/experiments/group-experiment"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9785.e0c467d7.js b/build-staging/es/assets/js/9785.e0c467d7.js new file mode 100644 index 00000000..b1c5c624 --- /dev/null +++ b/build-staging/es/assets/js/9785.e0c467d7.js @@ -0,0 +1 @@ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9785],{3905:(e,t,n)=>{"use strict";n.d(t,{Zo:()=>u,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),s=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return o.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=s(n),p=a,f=m["".concat(i,".").concat(p)]||m[p]||d[p]||r;return n?o.createElement(f,c(c({ref:t},u),{},{components:n})):o.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,c=new Array(r);c[0]=p;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[m]="string"==typeof e?e:a,c[1]=l;for(var s=2;s{"use strict";n.d(t,{Z:()=>u});var o=n(7294),a=n(5999),r=n(5281),c=n(7462),l=n(6010);const i={iconEdit:"iconEdit_Z9Sw"};function s(e){let{className:t,...n}=e;return o.createElement("svg",(0,c.Z)({fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,l.Z)(i.iconEdit,t),"aria-hidden":"true"},n),o.createElement("g",null,o.createElement("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})))}function u(e){let{editUrl:t}=e;return o.createElement("a",{href:t,target:"_blank",rel:"noreferrer noopener",className:r.k.common.editThisPage},o.createElement(s,null),o.createElement(a.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page"},"Edit this page"))}},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var o=n(7462),a=n(7294),r=n(6010),c=n(5999),l=n(6668),i=n(9960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function u(e){let{as:t,id:n,...u}=e;const{navbar:{hideOnScroll:m}}=(0,l.L)();if("h1"===t||!n)return a.createElement(t,(0,o.Z)({},u,{id:void 0}));const d=(0,c.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return a.createElement(t,(0,o.Z)({},u,{className:(0,r.Z)("anchor",m?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n}),u.children,a.createElement(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d},"\u200b"))}},1506:(e,t,n)=>{"use strict";n.d(t,{Z:()=>he});var o=n(7294),a=n(3905),r=n(7462),c=n(5742);var l=n(2389),i=n(6010),s=n(2949),u=n(6668);function m(){const{prism:e}=(0,u.L)(),{colorMode:t}=(0,s.I)(),n=e.theme,o=e.darkTheme||n;return"dark"===t?o:n}var d=n(5281),p=n(7594),f=n.n(p);const g=/title=(?["'])(?.*?)\1/,h=/\{(?<range>[\d,-]+)\}/,y={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function b(e,t){const n=e.map((e=>{const{start:n,end:o}=y[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${o})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:o,magicComments:a,metastring:r}=t;if(r&&h.test(r)){const e=r.match(h).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${r}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,o=f()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(o),code:n}}if(void 0===o)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);default:return b(Object.keys(y),t)}}(o,a),l=n.split("\n"),i=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),s=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let p=0;p<l.length;){const e=l[p].match(c);if(!e){p+=1;continue}const t=e.slice(1).find((e=>void 0!==e));s[t]?i[s[t]].range+=`${p},`:u[t]?i[u[t]].start=p:m[t]&&(i[m[t]].range+=`${i[m[t]].start}-${p-1},`),l.splice(p,1)}n=l.join("\n");const d={};return Object.entries(i).forEach((e=>{let[t,{range:n}]=e;f()(n).forEach((e=>{d[e]??=[],d[e].push(t)}))})),{lineClassNames:d,code:n}}const E={codeBlockContainer:"codeBlockContainer_Ckt0"};function k(e){let{as:t,...n}=e;const a=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[o,a]=e;const r=t[o];r&&"string"==typeof a&&(n[r]=a)})),n}(m());return o.createElement(t,(0,r.Z)({},n,{style:a,className:(0,i.Z)(n.className,E.codeBlockContainer,d.k.common.codeBlock)}))}const N={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function C(e){let{children:t,className:n}=e;return o.createElement(k,{as:"pre",tabIndex:0,className:(0,i.Z)(N.codeBlockStandalone,"thin-scrollbar",n)},o.createElement("code",{className:N.codeBlockLines},t))}var w=n(902);const B={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Z(e,t){const[n,a]=(0,o.useState)(),r=(0,o.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,o.useEffect)((()=>{r()}),[r]),function(e,t,n){void 0===n&&(n=B);const a=(0,w.zX)(t),r=(0,w.Ql)(n);(0,o.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,r),()=>t.disconnect()}),[e,a,r])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),r())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}const T={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]};var L={Prism:n(7410).Z,theme:T};function j(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _(){return _=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},_.apply(this,arguments)}var x=/\r\n|\r|\n/,O=function(e){0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},S=function(e,t){var n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)};function P(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&-1===t.indexOf(o)&&(n[o]=e[o]);return n}var z=function(e){function t(){for(var t=this,n=[],o=arguments.length;o--;)n[o]=arguments[o];e.apply(this,n),j(this,"getThemeDict",(function(e){if(void 0!==t.themeDict&&e.theme===t.prevTheme&&e.language===t.prevLanguage)return t.themeDict;t.prevTheme=e.theme,t.prevLanguage=e.language;var n=e.theme?function(e,t){var n=e.plain,o=Object.create(null),a=e.styles.reduce((function(e,n){var o=n.languages,a=n.style;return o&&!o.includes(t)||n.types.forEach((function(t){var n=_({},e[t],a);e[t]=n})),e}),o);return a.root=n,a.plain=_({},n,{backgroundColor:null}),a}(e.theme,e.language):void 0;return t.themeDict=n})),j(this,"getLineProps",(function(e){var n=e.key,o=e.className,a=e.style,r=_({},P(e,["key","className","style","line"]),{className:"token-line",style:void 0,key:void 0}),c=t.getThemeDict(t.props);return void 0!==c&&(r.style=c.plain),void 0!==a&&(r.style=void 0!==r.style?_({},r.style,a):a),void 0!==n&&(r.key=n),o&&(r.className+=" "+o),r})),j(this,"getStyleForToken",(function(e){var n=e.types,o=e.empty,a=n.length,r=t.getThemeDict(t.props);if(void 0!==r){if(1===a&&"plain"===n[0])return o?{display:"inline-block"}:void 0;if(1===a&&!o)return r[n[0]];var c=o?{display:"inline-block"}:{},l=n.map((function(e){return r[e]}));return Object.assign.apply(Object,[c].concat(l))}})),j(this,"getTokenProps",(function(e){var n=e.key,o=e.className,a=e.style,r=e.token,c=_({},P(e,["key","className","style","token"]),{className:"token "+r.types.join(" "),children:r.content,style:t.getStyleForToken(r),key:void 0});return void 0!==a&&(c.style=void 0!==c.style?_({},c.style,a):a),void 0!==n&&(c.key=n),o&&(c.className+=" "+o),c})),j(this,"tokenize",(function(e,t,n,o){var a={code:t,grammar:n,language:o,tokens:[]};e.hooks.run("before-tokenize",a);var r=a.tokens=e.tokenize(a.code,a.grammar,a.language);return e.hooks.run("after-tokenize",a),r}))}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.render=function(){var e=this.props,t=e.Prism,n=e.language,o=e.code,a=e.children,r=this.getThemeDict(this.props),c=t.languages[n];return a({tokens:function(e){for(var t=[[]],n=[e],o=[0],a=[e.length],r=0,c=0,l=[],i=[l];c>-1;){for(;(r=o[c]++)<a[c];){var s=void 0,u=t[c],m=n[c][r];if("string"==typeof m?(u=c>0?u:["plain"],s=m):(u=S(u,m.type),m.alias&&(u=S(u,m.alias)),s=m.content),"string"==typeof s){var d=s.split(x),p=d.length;l.push({types:u,content:d[0]});for(var f=1;f<p;f++)O(l),i.push(l=[]),l.push({types:u,content:d[f]})}else c++,t.push(u),n.push(s),o.push(0),a.push(s.length)}c--,t.pop(),n.pop(),o.pop(),a.pop()}return O(l),i}(void 0!==c?this.tokenize(t,o,c,n):[o]),className:"prism-code language-"+n,style:void 0!==r?r.root:{},getLineProps:this.getLineProps,getTokenProps:this.getTokenProps})},t}(o.Component);const A=z,I={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function W(e){let{line:t,classNames:n,showLineNumbers:a,getLineProps:c,getTokenProps:l}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const s=c({line:t,className:(0,i.Z)(n,a&&I.codeLine)}),u=t.map(((e,t)=>o.createElement("span",(0,r.Z)({key:t},l({token:e,key:t})))));return o.createElement("span",s,a?o.createElement(o.Fragment,null,o.createElement("span",{className:I.codeLineNumber}),o.createElement("span",{className:I.codeLineContent},u)):u,o.createElement("br",null))}var M=n(5999);function H(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"}))}function D(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))}const V={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function R(e){let{code:t,className:n}=e;const[a,r]=(0,o.useState)(!1),c=(0,o.useRef)(void 0),l=(0,o.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const o=document.createElement("textarea"),a=document.activeElement;o.value=e,o.setAttribute("readonly",""),o.style.contain="strict",o.style.position="absolute",o.style.left="-9999px",o.style.fontSize="12pt";const r=document.getSelection(),c=r.rangeCount>0&&r.getRangeAt(0);n.append(o),o.select(),o.selectionStart=0,o.selectionEnd=e.length;let l=!1;try{l=document.execCommand("copy")}catch{}o.remove(),c&&(r.removeAllRanges(),r.addRange(c)),a&&a.focus()}(t),r(!0),c.current=window.setTimeout((()=>{r(!1)}),1e3)}),[t]);return(0,o.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),o.createElement("button",{type:"button","aria-label":a?(0,M.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,M.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,M.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.Z)("clean-btn",n,V.copyButton,a&&V.copyButtonCopied),onClick:l},o.createElement("span",{className:V.copyButtonIcons,"aria-hidden":"true"},o.createElement(H,{className:V.copyButtonIcon}),o.createElement(D,{className:V.copyButtonSuccessIcon})))}function $(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"}))}const F={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function q(e){let{className:t,onClick:n,isEnabled:a}=e;const r=(0,M.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return o.createElement("button",{type:"button",onClick:n,className:(0,i.Z)("clean-btn",t,a&&F.wordWrapButtonEnabled),"aria-label":r,title:r},o.createElement($,{className:F.wordWrapButtonIcon,"aria-hidden":"true"}))}function G(e){let{children:t,className:n="",metastring:a,title:c,showLineNumbers:l,language:s}=e;const{prism:{defaultLanguage:d,magicComments:p}}=(0,u.L)(),f=s??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??d,h=m(),y=function(){const[e,t]=(0,o.useState)(!1),[n,a]=(0,o.useState)(!1),r=(0,o.useRef)(null),c=(0,o.useCallback)((()=>{const n=r.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[r,e]),l=(0,o.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=r.current,n=e>t||r.current.querySelector("code").hasAttribute("style");a(n)}),[r]);return Z(r,l),(0,o.useEffect)((()=>{l()}),[e,l]),(0,o.useEffect)((()=>(window.addEventListener("resize",l,{passive:!0}),()=>{window.removeEventListener("resize",l)})),[l]),{codeBlockRef:r,isEnabled:e,isCodeScrollable:n,toggle:c}}(),b=function(e){return e?.match(g)?.groups.title??""}(a)||c,{lineClassNames:E,code:C}=v(t,{metastring:a,language:f,magicComments:p}),w=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return o.createElement(k,{as:"div",className:(0,i.Z)(n,f&&!n.includes(`language-${f}`)&&`language-${f}`)},b&&o.createElement("div",{className:N.codeBlockTitle},b),o.createElement("div",{className:N.codeBlockContent},o.createElement(A,(0,r.Z)({},L,{theme:h,code:C,language:f??"text"}),(e=>{let{className:t,tokens:n,getLineProps:a,getTokenProps:r}=e;return o.createElement("pre",{tabIndex:0,ref:y.codeBlockRef,className:(0,i.Z)(t,N.codeBlock,"thin-scrollbar")},o.createElement("code",{className:(0,i.Z)(N.codeBlockLines,w&&N.codeBlockLinesWithNumbering)},n.map(((e,t)=>o.createElement(W,{key:t,line:e,getLineProps:a,getTokenProps:r,classNames:E[t],showLineNumbers:w})))))})),o.createElement("div",{className:N.buttonGroup},(y.isEnabled||y.isCodeScrollable)&&o.createElement(q,{className:N.codeButton,onClick:()=>y.toggle(),isEnabled:y.isEnabled}),o.createElement(R,{className:N.codeButton,code:C}))))}function U(e){let{children:t,...n}=e;const a=(0,l.Z)(),c=function(e){return o.Children.toArray(e).some((e=>(0,o.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof c?G:C;return o.createElement(i,(0,r.Z)({key:String(a)},n),c)}var Q=n(9960);var X=n(6043);const Y={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function J(e){return!!e&&("SUMMARY"===e.tagName||J(e.parentElement))}function K(e,t){return!!e&&(e===t||K(e.parentElement,t))}function ee(e){let{summary:t,children:n,...a}=e;const c=(0,l.Z)(),s=(0,o.useRef)(null),{collapsed:u,setCollapsed:m}=(0,X.u)({initialState:!a.open}),[d,p]=(0,o.useState)(a.open),f=o.isValidElement(t)?t:o.createElement("summary",null,t??"Details");return o.createElement("details",(0,r.Z)({},a,{ref:s,open:d,"data-collapsed":u,className:(0,i.Z)(Y.details,c&&Y.isBrowser,a.className),onMouseDown:e=>{J(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;J(t)&&K(t,s.current)&&(e.preventDefault(),u?(m(!1),p(!0)):m(!0))}}),f,o.createElement(X.z,{lazy:!1,collapsed:u,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{m(e),p(!e)}},o.createElement("div",{className:Y.collapsibleContent},n)))}const te={details:"details_b_Ee"},ne="alert alert--info";function oe(e){let{...t}=e;return o.createElement(ee,(0,r.Z)({},t,{className:(0,i.Z)(ne,te.details,t.className)}))}var ae=n(2503);function re(e){return o.createElement(ae.Z,e)}const ce={containsTaskList:"containsTaskList_mC6p"};const le={img:"img_ev3q"};const ie="admonition_LlT9",se="admonitionHeading_tbUL",ue="admonitionIcon_kALy",me="admonitionContent_S0QG";const de={note:{infimaClassName:"secondary",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:o.createElement(M.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:o.createElement(M.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 16 16"},o.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:o.createElement(M.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},pe={secondary:"note",important:"info",success:"tip",warning:"danger"};function fe(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=o.Children.toArray(e),n=t.find((e=>o.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n,rest:a}}(e.children);return{...e,title:e.title??t,children:n}}const ge={head:function(e){const t=o.Children.map(e.children,(e=>o.isValidElement(e)?function(e){if(e.props?.mdxType&&e.props.originalType){const{mdxType:t,originalType:n,...a}=e.props;return o.createElement(e.props.originalType,a)}return e}(e):e));return o.createElement(c.Z,e,t)},code:function(e){const t=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return o.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")||(0,o.isValidElement)(e)&&t.includes(e.props?.mdxType)))?o.createElement("code",e):o.createElement(U,e)},a:function(e){return o.createElement(Q.Z,e)},pre:function(e){return o.createElement(U,(0,o.isValidElement)(e.children)&&"code"===e.children.props?.originalType?e.children.props:{...e})},details:function(e){const t=o.Children.toArray(e.children),n=t.find((e=>o.isValidElement(e)&&"summary"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return o.createElement(oe,(0,r.Z)({},e,{summary:n}),a)},ul:function(e){return o.createElement("ul",(0,r.Z)({},e,{className:(t=e.className,(0,i.Z)(t,t?.includes("contains-task-list")&&ce.containsTaskList))}));var t},img:function(e){return o.createElement("img",(0,r.Z)({loading:"lazy"},e,{className:(t=e.className,(0,i.Z)(t,le.img))}));var t},h1:e=>o.createElement(re,(0,r.Z)({as:"h1"},e)),h2:e=>o.createElement(re,(0,r.Z)({as:"h2"},e)),h3:e=>o.createElement(re,(0,r.Z)({as:"h3"},e)),h4:e=>o.createElement(re,(0,r.Z)({as:"h4"},e)),h5:e=>o.createElement(re,(0,r.Z)({as:"h5"},e)),h6:e=>o.createElement(re,(0,r.Z)({as:"h6"},e)),admonition:function(e){const{children:t,type:n,title:a,icon:r}=fe(e),c=function(e){const t=pe[e]??e,n=de[t];return n||(console.warn(`No admonition config found for admonition type "${t}". Using Info as fallback.`),de.info)}(n),l=a??c.label,{iconComponent:s}=c,u=r??o.createElement(s,null);return o.createElement("div",{className:(0,i.Z)(d.k.common.admonition,d.k.common.admonitionType(e.type),"alert",`alert--${c.infimaClassName}`,ie)},o.createElement("div",{className:se},o.createElement("span",{className:ue},u),l),o.createElement("div",{className:me},t))},mermaid:n(1875).Z};function he(e){let{children:t}=e;return o.createElement(a.Zo,{components:ge},t)}},2244:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var o=n(7294),a=n(6010),r=n(9960);function c(e){const{permalink:t,title:n,subLabel:c,isNext:l}=e;return o.createElement(r.Z,{className:(0,a.Z)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},c&&o.createElement("div",{className:"pagination-nav__sublabel"},c),o.createElement("div",{className:"pagination-nav__label"},n))}},3008:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var o=n(7294),a=n(6010),r=n(9960);const c={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function l(e){let{permalink:t,label:n,count:l}=e;return o.createElement(r.Z,{href:t,className:(0,a.Z)(c.tag,l?c.tagWithCount:c.tagRegular)},n,l&&o.createElement("span",null,l))}},1526:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var o=n(7294),a=n(6010),r=n(5999),c=n(3008);const l={tags:"tags_jXut",tag:"tag_QGVx"};function i(e){let{tags:t}=e;return o.createElement(o.Fragment,null,o.createElement("b",null,o.createElement(r.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list"},"Tags:")),o.createElement("ul",{className:(0,a.Z)(l.tags,"padding--none","margin-left--sm")},t.map((e=>{let{label:t,permalink:n}=e;return o.createElement("li",{key:n,className:l.tag},o.createElement(c.Z,{label:t,permalink:n}))}))))}},7594:(e,t)=>{function n(e){let t,n=[];for(let o of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(o))n.push(parseInt(o,10));else if(t=o.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,o,a,r]=t;if(o&&r){o=parseInt(o),r=parseInt(r);const e=o<r?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(r+=e);for(let t=o;t!==r;t+=e)n.push(t)}}return n}t.default=n,e.exports=n}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9af9bb9d.c9dc5261.js b/build-staging/es/assets/js/9af9bb9d.c9dc5261.js new file mode 100644 index 00000000..749a059d --- /dev/null +++ b/build-staging/es/assets/js/9af9bb9d.c9dc5261.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5841],{2707:e=>{e.exports=JSON.parse('{"label":"release","permalink":"/es/blog/tags/release","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9b12a270.47315695.js b/build-staging/es/assets/js/9b12a270.47315695.js new file mode 100644 index 00000000..17c8ebc7 --- /dev/null +++ b/build-staging/es/assets/js/9b12a270.47315695.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9249],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>g});var r=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function o(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?a(Object(i),!0).forEach((function(t){n(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):a(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function s(e,t){if(null==e)return{};var i,r,n=function(e,t){if(null==e)return{};var i,r,n={},a=Object.keys(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var c=r.createContext({}),l=function(e){var t=r.useContext(c),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(i),h=n,g=p["".concat(c,".").concat(h)]||p[h]||u[h]||a;return i?r.createElement(g,o(o({ref:t},d),{},{components:i})):r.createElement(g,o({ref:t},d))}));function g(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=i.length,o=new Array(a);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:n,o[1]=s;for(var l=2;l<a;l++)o[l]=i[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,i)}h.displayName="MDXCreateElement"},9816:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=i(7462),n=(i(7294),i(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/es/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"10 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/es/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"repliqate",permalink:"/es/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/es/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/es/blog/cwtch-testing-i"}},c={authorsImageUrls:[void 0]},l=[{value:"Changes Necessary for Reproducible Android Bindings",id:"changes-necessary-for-reproducible-android-bindings",level:2},{value:"Repliqate Scripts",id:"repliqate-scripts",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:l},p="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,r.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(4756).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"changes-necessary-for-reproducible-android-bindings"},"Changes Necessary for Reproducible Android Bindings"),(0,n.kt)("p",null,"After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Insufficient path stripping introduced by Android NDK tools")," - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/android/ndk/wiki/Changelog-r22"},"changed the binutils and default linker")," to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our ",(0,n.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-platform-support"},"long term support plan"),", we will be moving towards adopting the latest NDK in the future."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Paths in DWARF entries")," - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.")),(0,n.kt)("figure",null,(0,n.kt)("p",null,(0,n.kt)("a",{target:"_blank",href:i(4560).Z},(0,n.kt)("img",{src:i(9842).Z,width:"1863",height:"428"}))),(0,n.kt)("figcaption",null,"Vimdiff comparing the decoded (",(0,n.kt)("code",null,"readelf --debug-dump=line"),") DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Go Compiler Acquisition")," - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there ",(0,n.kt)("em",{parentName:"li"},"was")," a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.")),(0,n.kt)("h2",{id:"repliqate-scripts"},"Repliqate Scripts"),(0,n.kt)("p",null,"With those issues now fixed, Cwtch Android bindings are ",(0,n.kt)("strong",{parentName:"p"},"officially reproducible!")," The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script"},"cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script")," in the ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/"},"Cwtch Repliqate scripts repository"),"."),(0,n.kt)("p",null,"This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4560:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},9842:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},4756:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"},4515:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9dd8190d.f4e110b9.js b/build-staging/es/assets/js/9dd8190d.f4e110b9.js new file mode 100644 index 00000000..3ede8c57 --- /dev/null +++ b/build-staging/es/assets/js/9dd8190d.f4e110b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2688],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),s=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(n),g=a,m=h["".concat(c,".").concat(g)]||h[g]||d[g]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=g;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var s=2;s<o;s++)r[s]=n[s];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}g.displayName="MDXCreateElement"},7561:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const o={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/es/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"24 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"autobindings",permalink:"/es/blog/tags/autobindings"},{label:"libcwtch",permalink:"/es/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/es/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/es/blog/cwtch-testing-ii"}},c={authorsImageUrls:[void 0]},s=[{value:"A Brief History of Cwtch Bindings",id:"a-brief-history-of-cwtch-bindings",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:s},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,a.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,a.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"a-brief-history-of-cwtch-bindings"},"A Brief History of Cwtch Bindings"),(0,a.kt)("p",null,"Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/therecipe/qt"},"therecipe/qt"),". However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework."),(0,a.kt)("p",null,"As part of early prototyping efforts for Flutter we built out a first version of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libCwtch-go"),", and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings."),(0,a.kt)("p",null,"This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape"},"experimental features")," - handle settings, ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings"},"duplication of logic between Cwtch and libCwtch-go"),", and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go"},"special behaviour in libCwtch-go that better belongs in the core Cwtch library"),"."),(0,a.kt)("p",null,"As part of a broader effort to ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"refine the Cwtch API in preparation for Cwtch Stable")," we have taken the opportunity to fix many of these problems."),(0,a.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,a.kt)("p",null,"The current ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockContact")," API implementation is:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"//export c_BlockContact\nfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\n BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\n}\n\nfunc BlockContact(profileOnion string, conversationID int) {\n profile := application.GetPeer(profileOnion)\n if profile != nil {\n profile.BlockConversation(conversationID)\n }\n}\n")),(0,a.kt)("p",null,"All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively."),(0,a.kt)("p",null,"In the new ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings")," we reduce these multiple lines to ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19"},"a single one"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"profile BlockConversation conversation\n")),(0,a.kt)("p",null,"Defining a ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"-level function, called ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockConversation")," which takes in a single parameter of type ",(0,a.kt)("inlineCode",{parentName:"p"},"conversation"),"."),(0,a.kt)("p",null,"Using a similar boilerplate-reduction for the reset of ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," yields ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format"},"5-basic function prototypes"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateProfile")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"BlockConversation")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"GetMessage")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"DownloadFile")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareFile"))),(0,a.kt)("p",null,"Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec"},"described in fewer than 50 lines, including comments"),". Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.)."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments"))," (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on ",(0,a.kt)("inlineCode",{parentName:"li"},"cwtch-server"),"). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart-side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch API"),": This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the ",(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"Cwtch Stable API redesign"),". In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9e2a7473.1f61baec.js b/build-staging/es/assets/js/9e2a7473.1f61baec.js new file mode 100644 index 00000000..18a49bf9 --- /dev/null +++ b/build-staging/es/assets/js/9e2a7473.1f61baec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1258],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),c=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return i.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),u=a,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var c=2;c<o;c++)r[c]=n[c];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},8725:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var i=n(7462),a=(n(7294),n(3905));const o={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/es/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"13 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"},{label:"api",permalink:"/es/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/es/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/es/blog/path-to-cwtch-stable"}},s={authorsImageUrls:[void 0]},c=[{value:"Clarifying Terminology",id:"clarifying-terminology",level:3},{value:"Tenets of the Cwtch API Design",id:"tenets-of-the-cwtch-api-design",level:3},{value:"The Cwtch Experiment Landscape",id:"the-cwtch-experiment-landscape",level:3},{value:"The Problem with Experiments",id:"the-problem-with-experiments",level:3},{value:"Restricting Powerful Cwtch APIs",id:"restricting-powerful-cwtch-apis",level:3},{value:"Pre-Registered Hooks",id:"pre-registered-hooks",level:4},{value:"<code>ProtocolEngine</code> Subsystems",id:"protocolengine-subsystems",level:4},{value:"Impact on Enabling (Powerful) New Functionality",id:"impact-on-enabling-powerful-new-functionality",level:4},{value:"Application Experiments",id:"application-experiments",level:2},{value:"Bindings",id:"bindings",level:2},{value:"Timelines and Next Actions",id:"timelines-and-next-actions",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2},{value:"Appendix A: Special Behaviour Defined by libcwtch-go",id:"appendix-a-special-behaviour-defined-by-libcwtch-go",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,a.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,a.kt)("p",null,"As we move out of Beta and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,a.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(4867).Z,width:"1005",height:"481"})),(0,a.kt)("h3",{id:"clarifying-terminology"},"Clarifying Terminology"),(0,a.kt)("p",null,"Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch")," refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtchlib")," refers to the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"reference implementation of the Cwtch Protocol")," / Application framework, currently written in Go."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Bindings")," refers to C/Java/Kotlin/Rust bindings (primarily ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libcwtch-go"),") that act as an interface between Cwtchlib and downstream applications."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.")),(0,a.kt)("h3",{id:"tenets-of-the-cwtch-api-design"},"Tenets of the Cwtch API Design"),(0,a.kt)("p",null,"Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Robustness")," - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Completeness")," - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Security")," \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.")),(0,a.kt)("h3",{id:"the-cwtch-experiment-landscape"},"The Cwtch Experiment Landscape"),(0,a.kt)("p",null,"A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Groups")," \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Hybrid Groups")," - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Server Hosting")," \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Message Formatting")," \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search / Microblogging")," \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status / Profile Metadata")," \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.")),(0,a.kt)("h3",{id:"the-problem-with-experiments"},"The Problem with Experiments"),(0,a.kt)("p",null,"We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"SendMessages")," interface that only allows callers to send messages."),(0,a.kt)("p",null,"We have also worked to package experimental functionality into so-called ",(0,a.kt)("strong",{parentName:"p"},"Gated Functionalities")," that are only available if a given experiment is turned on."),(0,a.kt)("p",null,"Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"SendMessages")," \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing)."),(0,a.kt)("li",{parentName:"ul"},"The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality."),(0,a.kt)("li",{parentName:"ul"},"This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.")),(0,a.kt)("h3",{id:"restricting-powerful-cwtch-apis"},"Restricting Powerful Cwtch APIs"),(0,a.kt)("p",null,"To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through ",(0,a.kt)("inlineCode",{parentName:"li"},"Application")," and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile."),(0,a.kt)("li",{parentName:"ul"},"Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a ",(0,a.kt)("inlineCode",{parentName:"li"},"RestrictedCwtchConversationInterface")," which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact."),(0,a.kt)("li",{parentName:"ul"},"Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," to control which experiments get access to which events at a given time.")),(0,a.kt)("h4",{id:"pre-registered-hooks"},"Pre-Registered Hooks"),(0,a.kt)("p",null,"In order to implement certain functionality actions need to take place in-between events handled by ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),". As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group)."),(0,a.kt)("p",null,"This is currently only possible with invasive changes to the ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort."),(0,a.kt)("p",null,"We are introducing a new set of Cwtch APIs designed for this purpose:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnNewPeerMessage")," - hooked prior to inserting the message into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnPeerMessageConfirmed")," \u2013 hooked after a peer message has been inserted into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEncryptedGroupMessage")," \u2013 hooked after receiving an encrypted message from a group server."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnGroupMessageReceived")," \u2013 hooked after a successful decryption of a group message, but before inserting it into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactRequestValue")," \u2013 hooked on request of a scoped (the permission level of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"public")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation")," level attributes), zoned ( relating to a specific feature e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"filesharing")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"chat"),"), and keyed (the name of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"name")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest"),") value from a contact."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactReceiveValue")," \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.")),(0,a.kt)("p",null,"Including the following APIs for managing hooked functionality:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the extension is interested processing."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," - returns a set of experiments that the extension is interested in being notified about"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," - to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (assuming all experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," is active)")),(0,a.kt)("h4",{id:"protocolengine-subsystems"},(0,a.kt)("inlineCode",{parentName:"h4"},"ProtocolEngine")," Subsystems"),(0,a.kt)("p",null,"As mentioned in our experiment summary, some functionality needs to be implemented directly in the ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),". The ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus)."),(0,a.kt)("p",null,"Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),"."),(0,a.kt)("p",null,"At the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," ecosystem. "),(0,a.kt)("p",null,"We are formalizing this subsystem into an interface, similar to the hooked functionality in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the subsystem needs to consume to operate."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," \u2013 to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (when all the experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," are active)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterContexts")," - returns the set of contexts that the subsystem implements e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"im.cwtch.filesharing"))),(0,a.kt)("p",null,"This also requires a formalization of two ",(0,a.kt)("em",{parentName:"p"},"engine specific")," events (for use on the event bus):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SendCwtchMessage")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage")," that is used internally in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," for messages between subsystems."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchMessageReceived")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.")),(0,a.kt)("p",null,"And the introduction of three ",(0,a.kt)("strong",{parentName:"p"},"additional")," ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEnine")," specific events:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StartEngineSubsystem")," \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StopEngineSubsystem")," \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SubsystemStatus")," \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging")),(0,a.kt)("p",null,"This will allow us to move the following functionality, currently part of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," itself, into generic subsystems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Attribute Lookup Handling")," - this functionality is currently part of the overloaded ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function, filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter of the ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage"),". As such it can be entirely delegated to a subsystem. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Chunk Request Handling")," \u2013 this is also part of handlePeerMessage, also filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage"),")"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Start File Share/Stop File Share")," \u2013 this is currently part of the ",(0,a.kt)("inlineCode",{parentName:"li"},"handleEvent")," behaviour of ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," and can be moved into an ",(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," handler of the file sharing subsystem (where such events are already processed).")),(0,a.kt)("p",null,"The introduction of pre-registered hooks in combination with the formalizations of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," subsystems will allow the follow functionality, currently implemented in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," or libcwtch-go to be moved to standalone packages:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Filesharing also depends on the file sharing subsystem to be enabled in a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),". This subsystem is responsible for processing chunk requests."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Legacy Groups")," \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status/Profile Metadata")," \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.")),(0,a.kt)("h4",{id:"impact-on-enabling-powerful-new-functionality"},"Impact on Enabling (Powerful) New Functionality"),(0,a.kt)("p",null,"None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search")," \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Non Chat Conversation Contexts")," - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.")),(0,a.kt)("h2",{id:"application-experiments"},"Application Experiments"),(0,a.kt)("p",null,"One kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers."),(0,a.kt)("p",null,"This kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library."),(0,a.kt)("p",null,"This functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface."),(0,a.kt)("h2",{id:"bindings"},"Bindings"),(0,a.kt)("p",null,"The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications."),(0,a.kt)("p",null,"We can split the bindings into four core areas:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Management")," - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Experiments")," - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Core Profile Management")," - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Experimental Profile Features")," \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.")),(0,a.kt)("p",null,"The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings."),(0,a.kt)("p",null,"In an ideal future, all of these bindings could be ",(0,a.kt)("strong",{parentName:"p"},"generated automatically")," from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)"),(0,a.kt)("p",null,"We can define three types of C/Java/Kotlin interface function templates:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileMethodName(profilehandle String, args...)")," \u2013 which directly resolves the Cwtch Profile and calls the function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileExperimentalMethodName(profilehandle String, args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ApplicationExperimentalMethodName(args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.")),(0,a.kt)("p",null,"All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ",(0,a.kt)("inlineCode",{parentName:"p"},"ProfileInterface")," for the first, exported methods of the various ",(0,a.kt)("inlineCode",{parentName:"p"},"Functionalities")," for the second, and ",(0,a.kt)("inlineCode",{parentName:"p"},"ApplicationExperiment")," definitions for the third."),(0,a.kt)("h2",{id:"timelines-and-next-actions"},"Timelines and Next Actions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Freeze any changes to the bindings interface")," - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib."),(0,a.kt)("li",{parentName:"ul"},"As part of Cwtch 1.11 and 1.12 Release Cycles",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Implement the ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," Subsystem Design as outlined above."),(0,a.kt)("li",{parentName:"ul"},"Implement the Hooks API."),(0,a.kt)("li",{parentName:"ul"},"Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting)."),(0,a.kt)("li",{parentName:"ul"},"Move event handling from the bindings into Application."),(0,a.kt)("li",{parentName:"ul"},"Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions."))),(0,a.kt)("li",{parentName:"ul"},"Once Automated UI Tests have been integrated into the Cwtch UI Repository:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings ",(0,a.kt)("strong",{parentName:"li"},"and")," a dart calling convention library from cwtchlib and any configured application experiments libraries"),(0,a.kt)("li",{parentName:"ul"},"Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process)."),(0,a.kt)("li",{parentName:"ul"},"At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.")))),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})),(0,a.kt)("h2",{id:"appendix-a-special-behaviour-defined-by-libcwtch-go"},"Appendix A: Special Behaviour Defined by libcwtch-go"),(0,a.kt)("p",null,"The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application Settings",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Including Enabling / Disabling Experiment"))),(0,a.kt)("li",{parentName:"ul"},"ACN Process Management - starting/stopping/restarting/configuring Tor."),(0,a.kt)("li",{parentName:"ul"},"Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)"),(0,a.kt)("li",{parentName:"ul"},"Logging Levels - configuring appropriate logging levels (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"INFO")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"DEBUG"),")"),(0,a.kt)("li",{parentName:"ul"},"Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled."),(0,a.kt)("li",{parentName:"ul"},"UI Contact Structures - aggregating contact information for the main Cwtch UI."),(0,a.kt)("li",{parentName:"ul"},"Group Experiment Functionality",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Experiment Gating"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfoList"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfo"),(0,a.kt)("li",{parentName:"ul"},"UI Server Struct Definition"))),(0,a.kt)("li",{parentName:"ul"},"Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients."),(0,a.kt)("li",{parentName:"ul"},'"Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".'),(0,a.kt)("li",{parentName:"ul"},"Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled)."),(0,a.kt)("li",{parentName:"ul"},"Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Profile Engine Activation - starting/stopping a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," when requested by the UI, or in response to changes in ACN state."),(0,a.kt)("li",{parentName:"ul"},"UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event."),(0,a.kt)("li",{parentName:"ul"},"File sharing restarts "),(0,a.kt)("li",{parentName:"ul"},"UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting ",(0,a.kt)("inlineCode",{parentName:"li"},"handle")," to a ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation id"),"). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself."),(0,a.kt)("li",{parentName:"ul"},"Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)")))}d.isMDXComponent=!0},4867:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9e4087bc.582408aa.js b/build-staging/es/assets/js/9e4087bc.582408aa.js new file mode 100644 index 00000000..6b05be93 --- /dev/null +++ b/build-staging/es/assets/js/9e4087bc.582408aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3608],{3169:(e,t,a)=>{a.r(t),a.d(t,{default:()=>o});var r=a(7294),l=a(9960),n=a(5999),c=a(1944),m=a(7961);function s(e){let{year:t,posts:a}=e;return r.createElement(r.Fragment,null,r.createElement("h3",null,t),r.createElement("ul",null,a.map((e=>r.createElement("li",{key:e.metadata.date},r.createElement(l.Z,{to:e.metadata.permalink},e.metadata.formattedDate," - ",e.metadata.title))))))}function i(e){let{years:t}=e;return r.createElement("section",{className:"margin-vert--lg"},r.createElement("div",{className:"container"},r.createElement("div",{className:"row"},t.map(((e,t)=>r.createElement("div",{key:t,className:"col col--4 margin-vert--lg"},r.createElement(s,e)))))))}function o(e){let{archive:t}=e;const a=(0,n.I)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),l=(0,n.I)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),s=function(e){const t=e.reduceRight(((e,t)=>{const a=t.metadata.date.split("-")[0],r=e.get(a)??[];return e.set(a,[t,...r])}),new Map);return Array.from(t,(e=>{let[t,a]=e;return{year:t,posts:a}}))}(t.blogPosts);return r.createElement(r.Fragment,null,r.createElement(c.d,{title:a,description:l}),r.createElement(m.Z,null,r.createElement("header",{className:"hero hero--primary"},r.createElement("div",{className:"container"},r.createElement("h1",{className:"hero__title"},a),r.createElement("p",{className:"hero__subtitle"},l))),r.createElement("main",null,s.length>0&&r.createElement(i,{years:s}))))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9ef77088.cdd221d9.js b/build-staging/es/assets/js/9ef77088.cdd221d9.js new file mode 100644 index 00000000..88e9ad40 --- /dev/null +++ b/build-staging/es/assets/js/9ef77088.cdd221d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5602],{3308:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/planning","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/9f1c7621.657f8b4f.js b/build-staging/es/assets/js/9f1c7621.657f8b4f.js new file mode 100644 index 00000000..711dd3f4 --- /dev/null +++ b/build-staging/es/assets/js/9f1c7621.657f8b4f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1312],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>g});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function s(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=l(a),h=r,g=u["".concat(p,".").concat(h)]||u[h]||d[h]||i;return a?n.createElement(g,o(o({ref:t},c),{},{components:a})):n.createElement(g,o({ref:t},c))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:r,o[1]=s;for(var l=2;l<i;l++)o[l]=a[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},4387:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/es/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"17 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"support",permalink:"/es/blog/tags/support"},{label:"testing",permalink:"/es/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/es/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/es/blog/cwtch-android-reproducibility"}},p={authorsImageUrls:[void 0]},l=[{value:"Constraining Cwtch UI Fields",id:"constraining-cwtch-ui-fields",level:2},{value:"More Automated UI Tests",id:"more-automated-ui-tests",level:2},{value:"New Release of Cwtchbot",id:"new-release-of-cwtchbot",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:l},u="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(u,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,r.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6097).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraining-cwtch-ui-fields"},"Constraining Cwtch UI Fields"),(0,r.kt)("p",null,"Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3785).Z},(0,r.kt)("img",{src:a(6561).Z,width:"410",height:"90"}))),(0,r.kt)("figcaption",null,"Screenshot demonstrating how certain strings would violate the bounds of their containers.")),(0,r.kt)("p",null,"These cases were fixed by parenting impacted elements in a ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"clip: hardEdge")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"decoration:BoxDecoration()")," (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration)."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3551).Z},(0,r.kt)("img",{src:a(9812).Z,width:"427",height:"76"}))),(0,r.kt)("figcaption",null,"Now these clipped strings are tightly constrained to their container bounds.")),(0,r.kt)("p",null,"These fixes are available in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"latest Cwtch Nightly"),", and will be officially released in Cwtch 1.11."),(0,r.kt)("h2",{id:"more-automated-ui-tests"},"More Automated UI Tests"),(0,r.kt)("p",null,"We have added two new sets of automated UI tests to our pipeline:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"02: Global Settings")," - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628"},"PR: 628"),")"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"04: Profile Management")," - these tests check that creating, unlocking, and deleting a profile work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632"},"PR: 632"),")")),(0,r.kt)("h2",{id:"new-release-of-cwtchbot"},"New Release of Cwtchbot"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"Cwtchbot")," has been updated to use the latest Cwtch 0.18.10 API."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3551:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png"},3785:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},6097:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"},9812:(e,t,a)=>{a.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAasAAABMCAIAAABcRQ+0AAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO2deUBU57n/n3Nm34cBZhiYYVhkXwURxAV0kLggauK1McSkadIm2i1tr/mV5N70Nm1q9zXVtvc2aWLV2zSrsTFBiGiMYECibAIjwjBsMwPD7Ps55/4xhhIYYVhC7C/vR/+YOed93+/zDMzDe97lebHnD+4FBAKB+PxR06nFP2sbEAgE4jMDRUAEAvH5BUVABALx+QVFQAQC8fkFRUAEAvH5hf7pNS2JUUkUKpEsRhApE4RL2QIhmy+iMRgAQPh8brvFbbPaxg02o96iHzINak1D2k/PGAQCgZjJEkdABostT8mUrUiTxidLE5Jvq8pk8iWRfElkhCpx8qLhZo+hr0d/4/pId7vP415awxAIBGImSxYBxXJFbHaBMitPGn8r8Fmt1qampra2tp6eHq1Wq9frLRaL2+0GADabLRKJoqKiYmNjk5OTc3JyioqKpAnJ0oTkTHWFoa9H19Yy0NpkHhlcKvMQCARiJksQASUxqvj84ri8ImFkFADodLrTp0/X1tZevnz5dlXcbjeO426X++rVq3Q6vXRtiQQTSIQSM9glsvCY+GRpfHLSmtL+lsa+K5fQ0zECgfiUWFQEZPH4SWs2Jq0pFUcpAKCuru748eM1NTVzVuRxeU8+/sSHHzW9eea0ShH75aqHaGZK3zfYbun56R9+UVS8pqqqSq1WZ9+1KzZnlaahXtNwzuOwL8ZUBAKBmMnCI6AiIzd5bZkqpwAA6urqjhw5Mkunbyo4hlduqViZkD1hmWCz2dvLt0VwJGatEaPhToeDpKiampqamprCwsKDBw+q1eqC3fdLE1J6Pqgd7Li6YGsRCARiJguKgBiWXro1vXSrIEKq0+kOHz586tSp0Guz2exdm7a7BqxZaZkRYeEbVq91jdpJH0HDMLvdQVJkoNjly5cvX75cWVlZXV2tyimQxKg668901p8BilqIzQgEAjGDea8H5AhEBburCvc8KIiQnjx5ctOmTfMKfwCQkZrO93AoP8VhsMPDw8P4Iq/NAwCAgZ/wU58McKdOndq0adPJkycFEdLCPQ8W7K7iCETztRmBQCCCMr8IKIiQ5e/cl6neAQDV1dWHDh1yuVzzlcxITfdYXEABHaOnJaXQKBrpJwAAo+Eur5skyGnlXS7XoUOHqqurASBTvSN/5z5BhGy+oggEAjGTeURAQYRs5bY9SWs2Wq3WqqqqY8eOLUySz+H53X4KKBrQlDEK0k9SBAUANB5DNzro8/uC1jp27FhVVZXVak1as3Hltj0oCCIQiMUTagTkCEQ5W3YnFm4wGAz79u07f/78wjUxAIoCCiiSxHEa6SOAojAa7mX4R8f0JDm9DzjJ+fPn9+3bZzAYEgs35GzZjR6HEQjEIgktAmJY5uYdgd7fQw89dO3atcVIerwenEEHDEggHQ4H4fYDAI1B09uMo0b97HWvXbv20EMPBXqCmZt3AIYtxhIEAvE5J6S54PTSrYGxvwMHDiwy/AFAt6Zne5Ka9GMYEzebLaSfBAAan3GpsdFiscxZ/dq1awcOHDh+/HimeodjwtR57u1F2rMMVBx6Vhgpsxr1vU3vX69/Z9rdtJIteTv2ep1OfW9Xa80bQXfCzN5CgHt//CegqHFdf9f7Nbq2KzMLhCK0/oGvxmbnO80Tuo6W5tePf7ZCc3q9bEKheB2KEOJOA5szS74iI7do78OCCGl1dfWCx/5uiWFYrCK2vFR9f8W9gGMjFsMrb7zy8Ob9jhGrV0z+6MVftF/vCLGp/fv3Hz582DZmaHz5z2idIAKBWAA1nVrazoKMWUqwePyV2/dKE5JPnjz585//fDFiXA73sS9++dDXvpOfk8fksegsukDAz8/Jo9yE3+Vr13efOV/j9XlDbK21tVUul+cXFtGZ7OGuViLkistP6vry9Q9+NXX9ZtuY3jamX1v1aNHehzQN50i/P1Bgyzf+M0NdIU/O6P+okS0Q3f2fvxRFxejaW0JvAQDWVj2at+PepMKSnkvvAcC2b39/RVHpjcb6qZbMKcQWiHY88aPU9Zs5QvGopjNx9YZtj3/PaTFNDA0sv1AoXi+b0JxehyKEuNPoNVrmGAdMWrNRlVOg0+mefvrpxSiJheIfP/3DL+z+NwGfz2AwAhdpOI3D4fAVIjyKdfGjBvs89709/fTTOp1OlVOQtGbjYmz7tJEmJBn7NKTfF5dXlLxWHZ9frO/t9rn/uYqIIwrrvlgrT84AgI0PP85gc9rOnppXCwAgUcR1XXhXEBmlylldtPehyPik/pbGaZbMKaTIyPV53KbB/pj03AhVYl7FXrvJ2Pvh+5+JUCheL5vQnF6HIoS4A5mtDyiJUeVVfoHNF1ZXV3d0hPp8OhOhQPCT7z27MnsljUabeRej4Xaf4/W33xwzjc+rWb/fbzQat2/fzguTGHq7Xba5xxA/E5xWszIzT5aYQni9SWtKR7ra6v/866kFuCJx2oa7KJJMXb+ZFxZ++dUXRzWd82oBACiCSN1QzhWJBREyRUZux3v/aH33jWll5hQyDWplK9Jis1f5ve7U9eUep+3Ci8+5P/nBLptQKF4vm9CcXocihLjT6DVaZpsJic8vFkcp6urq5rvrYyocNuc/vl2dlZ6F47f6myRFulwuDpszeSVCEpGfk9d9Q0PNc8fbqVOn7rnnHrVaHZ9ffMemkDH2aVg8vtflwOn05jdPzBxod1ktDA7H63Qa+28EHc6fswUA0DTW5++6z+d2eV3O+ud/E3Sofk6hj6FwnKZpPBd0OH/ZhELxetmEQvF6TiHEHchtn4LFckVcXhEAHDlyZOGt43jllor83Lypvb9uTc+2vZVdvT2TV+h0+oqEFRw2ZwESAfPi8orEcsWC7fy0Of2zp0488cjpnz0V9NsVt7KQ8PkmhgcuvPicY2L8337w3NqqR6cWYAtEbL6AJIjRno7r9e8krl5f9fPnpz37p67fTBEESRKaS+/p2q4U7/vy3mePMD75kYYiJEtMIXw+XduV5tePL1goLFrp93r9Xs+FF58zjwxu+9b3t3/nmWle8yURhM9nG9M3v36cwebMNCZ1/WaeWOL3edvPnrpe/86nJxTKx1u878sUSXoc9rNHDuvarixMCHEHctsIGJtdIIyMqqurmyXjC5POwD4Gx3E6bXqPUiQUbd5YxuVwp14Ml0iy0jP5XN4nmmIwJ7uE8+Ly5ct1dXXCyKjY7IIFVA+Rgrv3P/T7v2WoKyavMBYUr4Miliu73j8rW5EKABsf+RaLyw8Mt0+SuGotRZLGPk10WrZQKs/dtsdlNWsazk0tI0/NGh/s97ndsTmr4vOLE1atHdfenDaYtWxCssRUTcM5niQicfWG/J37IhOSZs7Xz2nMsgmF4vWSCCHuQIKPAzJY7LwdX+CFhf/whz/s7e0NWpNBZ5Tnlo5M6EVcEZvBihSFKyNi9GbjZAEMw1TK2B2bttK8OI1Fn9z7wePytm3eKhJ+YkfHlWstzVev+HzBt8TNjtPp3LlzJ53J7L/SQBL+uSvcntIvfXPjI9/O2lzZc+k9v9czeT0mLUeakDx0vdXY1wMA6+5/rOSL3+AIRIMdHy1GLoAwUhafX4wBJKxaFxYde+XNkwPXmqYWMI8OylMyZStSCa83ZZ0aKOrCS793mk1Ty5B+nzw5U6JQEV5v0pqN47q+s0cOf1ZCTDZXtbKIKxKzuLz4vCLNpXPNb56YrzHLJhSK10sihLjTuO04oDwlUxqfrNPpZkl3KuYKB8dHwngiuUTOoNH8pL9d2zW1AIvB5DO5tkELU4AzeEygKDqbEbQpDIMNGzb0Dw+8U/Ouw+GYrxs1NTU6nU4ZnyxPyRxobZ5v9alExie57TY2X5Cprmh+47ZDOSRBkISfJInFaE0yMayLW1nkdTmshuELL/5u5mCWz+1y26wUSQJAf0vjh6++NLORgdbm7PJdHocdp9Gv/uPvHcEWii+bUGvNG2mlW1wWMwDUP/+boD+UOY1ZNqFQvF4SIcQdSPAV0QV3789UVxw9evTZZ5+9XU0eiwsAHp/HTxLKiJgwnqhD1018HBQwwBh0RkJs3H8eeiohLp4iKYqiaIxgc8EYxuaxxZFhhjHj95/5QcPlhgmLeZbdwUF56qmnDhw40F53uum1ha/ZTly9YcMDBzvqz6SsVZtHBt/66ZOTtwIfyIevHeuoO73g9hEIxCJRZuZt+OLXZxuDoqih69fOHvlxKK3VdGqD9wEDpx3V1tbOUtnhcU6+HhofzkvLHTbrxyy3VrRQQPkJvzRalpieyKaxvG5vIAXWNDAMY3JYwnARRsNFAtG3HvtGcV5h7du1A/pBrUHnI0J9KK6trT1w4MDkIU0LI2FVsd/n7ag9LUtMDYtW8sThDvP8FujMl9xtexJXr+cIRDQG0+tyWEaHm988YbjZPbXM+ge+Kk/OYPH4GIZ7nHb9jesfnPjT1OGwcGV8we77xXIFi8snCL/bbu1rvnTl1MlPuFawLqtsBy8snMHh+t1uh3m84723pw11LZvQkni9bEKheL0kQoiQwDAAwD5+MZP5ricJMg4oiVHlV95rtVqffPLJoHVmguO0L6mrGrubHe5/PsNSQK1cuXLLXVuEYSIGk4HTaDgGGAYYjuM4TqPRmGwmT8QXSIR0Bt3v8o1r9DQ6TRUbmx6elB2TzsDpPcO9IfozNDT0yCOPSKKiB641LXhhYOGeBy36kY73TovlClliKgA1dL01cGvaOGDB3fvv+tpTPo878BYAMtUV6x84uGrXfbnb7klZV8bkcAML01YUlZR88RsFu+/P2bI7Pr/YY7OaR4cCVdbc+0iWugIADH09Y9peoEAan6TMzu9rvjT5xdj+nWeUWfkeh83Q220eHWSyufLkDHlyxuQQO1sg2vat/5JEx1oNI/ob151mE18SochYyRNLJldsrCgqWVv1KJsvHBu4abzZ7XW5JApVbHaBc2LcNNi/zEJL4vWyCYXi9ZIIIULEahhpq3kTp9GiVqTNvGsbN5x44uGbTRdDbC34OKBEoQKApqYgg7gsBksiCJuwmT0+T2D+N1oSpTMOifnCmNgYu3v6EN7Q0LDX66WJaBwBl83jUCRJEiQFt4IajU7HaTiGgc/pHWrp9xE+tpRPo9NkGTHimHAhV9A9fKNjoGuGFcFpampSq9UShWphCwOzNley+cLui7UA0HWhJnXd5qik9BDr5lfuy9y8w2oY7WtpoDOYQqnc7/MCQOLq9cX3PmI3jd24fJ7OZCszVxbf92XT8IDVMMIWiBJWrXXZrbVHfzKmvTXXtPqeBzI2bc/fdd+Fv/wOAFLXl0fGJ49pe6c+j299/HuyFWmp68u73q8BgMJ7HuCKwjQN5y7+9Q+BAoII2dZvPh2XV/Tha8cC38CMTdsxDG98+fmAdwAQl1e04YGvpW/cqmmsX06hpfJ62YTm9HqphBCfFUEWoIhkMQDQ1tY28xaHxU5XJCdGqVYmZCXI4nLjMyMEEsDgi/seEIaLD3zpK4poBYP+z+kOl8tFkiSGAYYBTsNoDBqDzWCwmEw2k8li0ug4hgHhJQxdI5aRCZxFx2k4ANA5DF6UICJOujo9Hws5/1XA4IDxC0CZme9zuwJ7qqyGEYthWCxXhJKHlcHmJK/dZNWPvP6Db188drT++d+c+vF322reBIBMdYXP7Xr7V//V8L9/fv+l3ze/cYLJ5WdtrgQAZcZKJoc72N4y+bUBgA9ffclls4hl0YG30oRkDMMCTU1y9cyrGIZFxq0IvBVFKTwO2+T3EwBsY3pdewuTw1Nm5Qeu8CWRpsH+yWABAP0tjeO6m3xJ5DILLZXXyyY0p9dLJYT4rAjSBxREygCgp6dn5i2/3+/xe8dtE06PM4wvlvDF73c2UhRVuqGUB9zKrRXFq4v6tP3Xe7qGRoa5XO72u7byeXygAg/uH0NRgGEURQWiG+EjTH1jOJvOELAAA6CAAgrDMGG85AsP3vth/9WOrpA25AUMDhg/X9gCkUQZ57Ka8ypuzQt5XU4ag5leuuXyKy/OXjc+bw2bL+xrvjTzllAqNw32T/6Wu2wWn9spCJcCgFAmBwCLYaTi0LNh0cqJYd3pnz0FAB67jcUTBMpzhGLC7/N53Hu+/1u2QKRru3L+hd+OdLf7vR6OKCxQhsXjue223G170jaUA4Zfrz9z9cyrZv0QAITJFQDAYHOYbI7TMlH6pW8qMlZ6nPb3Xzoyqul0mici45PZApHbZlk2oSXxetmEQvF6qYQQnxXBImC4FAC02iDPkk6P63J3M0GSJEV6/F6nx+32eQCg+4OOtqFOVXLCuqLiNQVFq1bmE34Cx3Emk2nXW3wmN1fCp7PogGE4HSP9BE6n+VxeigS73uq2OAmfz2vxskRsBp/lGLYKYkV0DhOn417Ce+PmjRA9CRgcMH6+ZJXtYLDYjMio9I3bpl6XrZj7QTgsWgkATsvEtOsRqkQ6kyVNSCl77IlP3MAwAHDbbQAQrojjhYU3vf7Xor1fUmbl69qukIQfp99aK+5zu2g0etKaUpfNou/tVmTkBq6TBEGj3/rB+b1eJoerzMofaG2WKOMVGSuvnnnV7/EAAJ3JCjRC+H1MLk8cldz0+l/zKvYmrFo7qukkCD+GYRyhyG2zLJvQkni9bEKheL1UQojPiiA/ALZACAB6fZB0zSRFTp5k5PF5x3zjgf5aJFPyRu1p77u+438/cf/eqvVFxXweHwAoijJeH3UZ7BiG0ZgMDAcmj9XVc1Mg5HExJpvJYgvZOIcuTpVatSazZgwoABwEKnFAok/b75myLHl2AgYHjJ8v8pQsr9Nx/NCXpl7c+eRPxfIYoVRuNYzMUtfrcgIAVyyZdn1M20v4fKbB/tM//4+ZtfqvNKzadR9bIHKYxgr3fJGiSJOuf1qZiRGdKne13+flCETSuCTbuGFmOw6TUZSafbPp4orCDWyBaKgzSKpEp2VCECEd6W4vuHs/g8WeOVO0bEJL5fWyCc3p9VIJIeYF9zZ9ZwZr3ju1gowDsvkiAAglXfOtOQ0KXqg9YXFYXW7XTW3fj3/9k8f+/evvvFfjcDr8Th9OYkABRsO9To/b4jIOjz3/xitHThzXG8YooMLSZMKEMDqXIUqMYIdxSYIEDAscnAQAVrstdE8CBgeMnxfhyvgwuWL84znESYx9GhqdkV66dfJK0H17+t5ukiTkKZkzb9lNxrCY2Ljcwpm3HOZxt80qiJB2f1BHkcSYtnfmypvBjo+Aonji8KHOa4Bhw11BRmYt+mEMx0mSsBpHSZK4ESwdk2NinCsM63r/rNflcNss7bVvfVZCS+X1sgnN6fVSCSHmhSzYRDAAsHn83G175tXU9D4gTqPTGAwAcLvdITZBAXW+44NbrynK4/X29vX+8Oc/kkvlD27fv/WebQwZVxAlcgxZTd16sZC3d/s2h8eTvjadJ+VRtFtjhDQmLSwtksLBqbfpm3V2iZchYB9/ZfrGo1kIGExjBN92MgtpJXfhdPrMP++axvqk4o2BbZ7OiXEAiM1eRZLktEXRw12toz2d0alZO5/82WhPO+H3SxRxoz0drTVvtNedLtr70NqqR2NzCiz6YUGETCSTf3DiT4HdAm67VSxXFN/7iMdpb3rtrzMNM/ZpfB63LDElOiVzTNt76eR/zywzMawDgPTSrXQmS9NQH3QdgNNswnB888HvYhje/MbxmWvQlk1oqbxeNqFQvF4SIUQoMNicFYUlyWs3CSOjgpfAsKzNlbyw8N4P35+WJ+12hDQMwWFycuIzbE6bZqTPR/hSFUl8FtdgHR8cGyYpksNkS0URTo9LzBPRcPz6oIaiKD9BOK3e02fqm5s6FdFycYSYw2fTSVwVpizasprDZc/sT2E4Pu60vnOxXszl/e3yyw/ed39Pb6iDgItBlpjqdTqmZdYEAGOfxmbUi2UxYTGxHefejssriohNFETIej6om1by3d/9cOPD35IlpaWW3EX6/U6zaQQoAOj5oI7weTPLdigz8+JXFRNer21MLwiXBiKg3+vBcZrZMNT48vPTVs9OQvi8DJZwqKvt3P/8MmgBx8Q4AGAYfv38u40vPx+0jM/jDshdPfPq7Q7BWDahJfF62YRC8XpJhBChkLW5MmfL3bOXoTNZycWb5CmZrzz99VDaDLIrbv+vjtGZzKSkpMnT0MU8UWZs2pBpWMAR8FhcwEDAEdwc7ZOHRdndjhiJvN84MDox6vX5IoXhvXotANBp9F2F29anrdNZjG2abrvDwefxKRqFAQYYJhYLv/zYfTw+FwAIggAA0u23DZgtw+Y/nXpFbx4fsfV7KIdrPivmORyORqPxe73HvrU/9FoIBOJfhbwdX5gzAgawjRtCiYDBd8W57Ra+JFIkEgUiIIZhXr+3TdvpI/wDxiEcwwUcPo7jE3az1jBIARUbqRi3ToxZJwDA6rqV6V4eJtuQXRwtkSpk0tWJaeMWy5jFzIrkuq1unoRPY9Id3RNevsND+j648pFSFBkjiqAIkoHT0lSJ4zZzOEfWPxHqWugAIpEoYPy8aiEQiH8VWt76W/f7n9iqm1VemVayxT5ufPuX35t6nQg5R1SwCGiz8iWRMplsdHQUACiKcnpcALe6YwQQJvvE5GsAqPnoPZf3E4OGDBojOy5j3GSz273x0dFMBjM6WhYVGY4z6DQ5nUbHSYIk/CRh99Hp2Nq0bMLlB5ICDAOKSlclfNjV6ifYAlaY2T0WohsAIJPJAsaHXgWBQPxrMW2iKZDRhwJqwVv4g0xuBmbrVSpViE1MC38AECkKX5dW1Nnfe+1Gl8ftZQvY/AgBjUGnCNI1YbcbrWaD2WQw2SfsLpPDPeH0ON2EnwCKAoBwkYjL5mCASbhSHJtHztSAwWipAQKBCJ0gfUCbUQ8AyckLzLPCpDPyE3NVUkUYX+Lxer0+H0mRkSlyl9XlmXAAgM/vr7/aPDRmyEtOV0RIO7W941bL6tRMeXgEBsCg0fKS0t776DILuAJmmMUTamgPGBwwHoFAIEIhSAS06IcAICsra2EthvHFG7PWEQTJpNFrWxspitrF2eSt66Azb2kNj49d6rhKUuSIySgLCx80jpIUhWP49qJ1NBwHgBRF3IXWK36CCOfJbN4JkgopV2DA4IDxCAQCEQpBHjNNg1oAKChYyLEbTDojPzHHanfXtlwes5jj5THFWbksFhMoivARgQXUfoKgKBIA3F6PVj9MfJwMdTIPlkQoDBMIAYCOM1m0UBd5BwwOGI9AIBChEKQPaBrSGm72SBOSCwsLZzkmKSh8Dn9LXpnT5fMTpIjPj4uSs8VceYbSMmSyjVoCiQ9iIiJlkshR0z9PFOGzuamxcXTarXBMw/GcxKTrgx02j8VLhLQrrrCwUCgUGm72LCw1VlhMbP6Oe6NTs9rOnvroH39XZuZllu0Qy5VMLtfv8Yxpe8//5XfTzn5Vf+XfY3P++UfCbbOc/O5XAq+T1mzMVFfwwsJxOt1pNl098+qNxvMLsAqBQHzaBF8RbejrkSYkl5WVzSsCMmj0NamrpKIIUkDFRESyGEwMA9JHep0eu9E2uYmOxWRWFpe+dal+dGIMAPgcblleUVxU9NSmkhQqi3fM6XUGFZpJWVlZwOzQrZ1kw4Nfi81e5bSYJrPO0ugMj8P+0emX7SZDTHpuYsG6dVWP1v7hp1Nr0RgM05D2zR89Ma211PWbC+7eP9LT0XHubZ/LGZORa9EPL8AqBAIxJzevXFJkrNS2LvxEquARUH/jeqa6oqKiYpZzQmZCAVgdtjZtpzIiRsgVBOKJz+UdadNRJPVxEcAAosMj9paWX77ebjCbSnNXRYdHMj+ZJCNcIE6OTrjW3xFijuiKioqA2aFbO5VrZ15rqz11/y/+Enjbf/Vy/9VboX+w46owMmpm4gOcziD9QdYcJa8tM/Zpao/+JPC2r6VhYSYhEIg5MfZpXv3+44tpIXgEHOluN/T1KOOTy8vLZzkubhoE4W/sbr7a185hsiWCsCR5YnJMYmykIlIczqQxPg6CAAA4hkkEorK8Qh/h57BYOIYBAIWBw+WwOGy6saE+vVZvNoYY/srLy5VKpaGvZ6S7PURTp3Lhxedud0uZla/MzItQrei+eBYAssp35my5+/r5d668eZLGYBDBzvYMi1E2nPyfBZiBQCCWn+AR0Odx69papPHJVVVVoUdACsBH+H0uu81lN1rHe0f661rP8zi8Xz7zU5lCSbgJiqT8Lp/f7QMKAmlTMQxoLDqdy8RomMVp++mvnuu5qfETfh/h94e8qruqqgoAdG0tge2iS8WO/3c4IjYBAAx9PYHTEd02q8syEVh0TaMzwpTKB393gvD5bGOGjvdO32g8H5dXhGM4i8vf8/3fckUSn8fV13yp8e8vLKFVCARiCbltZoSB1qakNaVqtXoB8yEAQFGUj/D5CJ/L6/6wtVkVr2JzuXArA/Qni2K3/nXoum8O9Vud88iIBQCFhYVqtdpqHB1YxFhAUN76SbVYrojNXpW6bnPpw4+/8vTXNQ3nJk8j66w/4/d6xgf6lJl5aSV3Fezer7/RxQ+LIClyxZrSnkvv6dpbssoqU9ZvHtf1BQ6vQCAQdxq33XRhHhnsb2kEgIMHDy5GgKKoV956zWKzAhbo9GEY/sn/GAYYuNyut945bbaY59t+wLz+lsZP44Bq88hg67tvNL3+V0G4NGnNxqm3bjSe729ptI3pO+vPfHDiT2wePz5/jcUwguO0znNvt777xsTQwIUXn3NaTEFTByIQiDuB2bad9V25ZB4dVKvVlZWVi9EY0Y++9Ldj7ts/olIUdeHSxQ8+vDTfg9IrKyvVarV5dLDvSpBjOpYKt8MGFOW/vf2E30cB+D0eXdsVn9sVeHaexB9ymmsEArHMzJYf0DSk1TTUF+y+v7q6+uzZs5PJshbA66dPpSSmbFGX0+l0AKCA8nq9LCYLACiKuq7peuHEi/p/rJQAAAUuSURBVDa7fV5tcjic6upqANA01C9sGeDtWLWrSqJQjXS3m0cG5ckZyqx8m8nY19Kwoqgku3xn14WznfVn1I8eMvZrDDd7xFExaSVbnBZT4FF3uKstPr/YaZkYut6aun4zi8tH08EIxB3LHBlSNQ3npAkpqpyCZ5555tChQwuW8RP+Xx79DZvNKllbwqDTKZKaMJujpDKSJG/09f741z/r1807hD3zzDNKpVJ7rWlybG6pcFnNbH529l276SwW4fWaRwavnnkFALjCMF5YBFcs4YnDmRxupnoHo4Lj93gs+uHmN08EMhW/99+/KHvsibSSLdnluxzm8Y9Ov7ywGWoEArEMBMmQOg1FRm7R3ocFEdLq6upjx44tRozNYn3z0a/v3r7T7/d39lzPTMvQDmiffPZ7fdq++Ta1f//+w4cP28YMjS//ebAjyKk9CAQCMTs1ndq5008NdlztrD8DAIcPHy4pKVmMntvj+c0fnyMIgiRJ49iY2+0+8vwfFxD+SkpKDh8+DACd9WdQ+EMgEAsmpAR8nfVn2uveAoCjR4/m5OQsRk8oEOI47vF6hoYHcRxfEZ843xZycnKOHj0KAO11bwVCMwKBQCyM0FKQUlT72bc0DeeEQuELL7ywmCC4tnANAHR0dXZpuul0elFBIYfNDr16Tk7OCy+8IBQKNQ3n2s++BaFtGkEgEIighJqE2WWzXHvn9d7LF6RS6cmTJxfwOMxiMpUxyrsrdlEUdfrdt691tE2YzcoY5arcfB6XF/Qo3mmUlJScPHlSKpX2Xr5w7Z3XZ56TjUAgEPOCtrMgI8SiXqfDNDTAYLOjV6Tec889RqOxtbU1lIpMJrNo1epd23fuu/sLSYkrRg36o3/5o8vtjlOq0pJS8nJWxilVIqHYOG6c5XC4/fv3HzlyhMViaRrOXT3zmm0M5YJGIBCLotdomUcEBACv02Hs0wAG0oSUsrIyuVx+8eJFf7AUKVNhs9n377kvXhXvdruaWq688L8v9Wn7SZLs6ulyezwMOiNcIomSRfUP9OuNQU754HA4hw8ffvzxxwGgve6ta2+/uuBTURAIBGKSXqNl7tUwQcCw9NKt6aVbBRFSnU53+PDhU6emHzc+FTqdLuQLGEym3+93u1wOl/PjZjAGg8HjcJlMJklRNpvV7Zm+faKysrK6ulqpVNrGDJ31Zzrrz6CxPwQCsSTUdGoXFAEBAECRkZu8tkyVUwAAdXV1R44cWUAChVkoLCw8ePCgWq0GAO21pp4PatHCFwQCsYQsKgICAIvHT1qzMWlNqThKAQB1dXXHjx8PPZvW7SgvL6+qqgrEPvPooKahXtNwzuOY3545BAKBmJ3FRsAAkhhVfH5xXF6RMDIKAHQ63enTp2tra+fbJSwsLCwrK6uoqFAqlQBgNY72tzT2Xbm0tHt+EQgEIsDSRMAAYrkiNrtAmZUnjb910LDVam1qampra+vp6dFqtXq93mKxuN1uAGCz2SKRSCaTqVSq5OTkrKysgoICoVAYqGjo69G1tQy0Nn0aCa8QCAQiwFJGwAAMFluekilbkSaNT5YmzO/MdcPNHkNfj/7G9ZHu9qXN9oxAIBAzqenUzpEbZr74PO6B1uZATnlJjEqiUIlkMYJImSBcyhYI2XwRjcEAAMLnc9stbpvVNm6wGfUW/ZBpUIuedhEIxDKzxBFwKqahIEENp9EBgAz5DBAEAoH49PgUI2BQUOxDIBB3DqHuC0YgEIj//0AREIFAfH5BERCBQHx+QREQgUB8fvk/oU/HigH/qfEAAAAASUVORK5CYII="},6561:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/a02b4022.ff8b72fb.js b/build-staging/es/assets/js/a02b4022.ff8b72fb.js new file mode 100644 index 00000000..5f96ca52 --- /dev/null +++ b/build-staging/es/assets/js/a02b4022.ff8b72fb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3492],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(a),u=r,d=m["".concat(s,".").concat(u)]||m[u]||h[u]||i;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:r,o[1]=l;for(var p=2;p<i;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},4889:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"16 de junio de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"release",permalink:"/es/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/es/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/es/blog/cwtch-nightly-v.11-74"}},s={authorsImageUrls:[void 0]},p=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},m="wrapper";function h(e){let{components:t,...i}=e;return(0,r.kt)(m,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(159).Z,width:"1004",height:"480"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(8173).Z},(0,r.kt)("img",{src:a(5726).Z,width:"1388",height:"828"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.12")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Profile Attributes")," - profiles can now be augmented with ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"additional public information")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Availability Status")," - you can now notify contacts that you ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/availability-status"},"are ",(0,r.kt)("strong",{parentName:"a"},"away")," or ",(0,r.kt)("strong",{parentName:"a"},"busy"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Five New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Japanese"),", ",(0,r.kt)("strong",{parentName:"li"},"Korean"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili")," and ",(0,r.kt)("strong",{parentName:"li"},"Swedish")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Support for Tails")," - adds an ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/platforms/tails"},"OnionGrater")," configuration and a new ",(0,r.kt)("inlineCode",{parentName:"li"},"CWTCH_TAILS")," environment variable that enables special Tor behaviour."))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Based on Flutter 3.10"),(0,r.kt)("li",{parentName:"ul"},"Inter is now the main UI font"),(0,r.kt)("li",{parentName:"ul"},"New Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"New Network Management code to better manage Tor on unstable networks"),(0,r.kt)("li",{parentName:"ul"},"File Sharing Experiment Fixes",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Fix performance issues for file bubble"),(0,r.kt)("li",{parentName:"ul"},"Allow restarting of file shares that have timed out"),(0,r.kt)("li",{parentName:"ul"},"Fix NPE in FileBubble caused by deleting the underlying file"),(0,r.kt)("li",{parentName:"ul"},"Move from RetVal to UpdateConversationAttributes to minimze UI thread issues"))),(0,r.kt)("li",{parentName:"ul"},"Updates to Linux install scripts to support more distributions"),(0,r.kt)("li",{parentName:"ul"},"Add a Retry Peer connection to prioritize connection attempts for certain conversations"),(0,r.kt)("li",{parentName:"ul"},"Updates to ",(0,r.kt)("inlineCode",{parentName:"li"},"_FlDartProject")," to allow custom setting of Flutter asset paths"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili"),", ",(0,r.kt)("strong",{parentName:"li"},"Swedish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Japanese")," (29%), ",(0,r.kt)("strong",{parentName:"li"},"Korean")," (23%), ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.12 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"libCwtch-autobindings-2023-06-13-10-50-v0.0.5"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},8173:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},159:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"},5726:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/a65a3c47.360aa4d8.js b/build-staging/es/assets/js/a65a3c47.360aa4d8.js new file mode 100644 index 00000000..ae53e0ef --- /dev/null +++ b/build-staging/es/assets/js/a65a3c47.360aa4d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7591],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var o=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,o)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,o,n=function(e,t){if(null==e)return{};var a,o,n={},r=Object.keys(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=o.createContext({}),p=function(e){var t=o.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return o.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(a),u=n,m=h["".concat(c,".").concat(u)]||h[u]||d[u]||r;return a?o.createElement(m,i(i({ref:t},s),{},{components:a})):o.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var p=2;p<r;p++)i[p]=a[p];return o.createElement.apply(null,i)}return o.createElement.apply(null,a)}u.displayName="MDXCreateElement"},5432:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=a(7462),n=(a(7294),a(3905));const r={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"28 de abril de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/es/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/es/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/es/blog/availability-status-profile-attributes"}},c={authorsImageUrls:[void 0]},p=[{value:"Cwtch Development Handbook",id:"cwtch-development-handbook",level:2},{value:"Release and Packaging Process",id:"release-and-packaging-process",level:3},{value:"Cwtch Application Development and Cwtchbot v0.1.0!",id:"cwtch-application-development-and-cwtchbot-v010",level:3},{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(h,(0,o.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(3466).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"cwtch-development-handbook"},"Cwtch Development Handbook"),(0,n.kt)("p",null,"We have created a new documentation section, ",(0,n.kt)("a",{parentName:"p",href:"/developing/intro"},"the developers handbook"),". This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients)."),(0,n.kt)("h3",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"The new handbook features a breakdown of ",(0,n.kt)("a",{parentName:"p",href:"/developing/release"},"Cwtch release processes")," - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created."),(0,n.kt)("h3",{id:"cwtch-application-development-and-cwtchbot-v010"},"Cwtch Application Development and Cwtchbot v0.1.0!"),(0,n.kt)("p",null,"For the first time ever we now have ",(0,n.kt)("a",{parentName:"p",href:"/developing/category/building-a-cwtch-app"},"comprehensive documentation on how to build a Cwtch Application"),". This section of the development handbook covers everything from ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"choosing a Cwtch library"),", to ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot"},"building your first application"),"."),(0,n.kt)("p",null,"Together with this new documentation we have also ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"released version 0.1 of the Cwtchbot framework"),", updating calls to use the ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-api-design"},"new Cwtch Stable API"),"."),(0,n.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,n.kt)("p",null,"There is a ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,n.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/"},"2023-04-26-20-57-v1.11.0-33-gb4371"),"."),(0,n.kt)("p",null,"This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"in-development Tails support"),". "),(0,n.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,n.kt)("p",null,"Please see the contribution documentation for advice on ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,n.kt)("p",null,"Subscribe to our ",(0,n.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,n.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,n.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3466:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/a6aa9e1f.8ac198c5.js b/build-staging/es/assets/js/a6aa9e1f.8ac198c5.js new file mode 100644 index 00000000..f9d14373 --- /dev/null +++ b/build-staging/es/assets/js/a6aa9e1f.8ac198c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3089],{46:(e,t,a)=>{a.r(t),a.d(t,{default:()=>u});var n=a(7294),r=a(6010),l=a(2263),i=a(1944),o=a(5281),s=a(9058),m=a(9703),c=a(197),g=a(9985);function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,l.Z)(),{blogDescription:r,blogTitle:o,permalink:s}=t,m="/"===s?a:o;return n.createElement(n.Fragment,null,n.createElement(i.d,{title:m,description:r}),n.createElement(c.Z,{tag:"blog_posts_list"}))}function d(e){const{metadata:t,items:a,sidebar:r}=e;return n.createElement(s.Z,{sidebar:r},n.createElement(g.Z,{items:a}),n.createElement(m.Z,{metadata:t}))}function u(e){return n.createElement(i.FG,{className:(0,r.Z)(o.k.wrapper.blogPages,o.k.page.blogListPage)},n.createElement(p,e),n.createElement(d,e))}},9703:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(5999),l=a(2244);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,r.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(l.Z,{permalink:a,title:n.createElement(r.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),i&&n.createElement(l.Z,{permalink:i,title:n.createElement(r.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(9460),l=a(390);function i(e){let{items:t,component:a=l.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(r.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/a79c88c2.bfaf70a8.js b/build-staging/es/assets/js/a79c88c2.bfaf70a8.js new file mode 100644 index 00000000..027578dc --- /dev/null +++ b/build-staging/es/assets/js/a79c88c2.bfaf70a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9976],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=r,u=h["".concat(c,".").concat(m)]||h[m]||g[m]||i;return a?n.createElement(u,o(o({ref:t},p),{},{components:a})):n.createElement(u,o({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,o[1]=l;for(var s=2;s<i;s++)o[s]=a[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},8553:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"13 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"},{label:"api",permalink:"/es/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/es/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/es/blog/path-to-cwtch-stable"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...i}=e;return(0,r.kt)(h,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,r.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,r.kt)("p",null,"As we move out of Beta and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,r.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(4867).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},4867:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/a8c7fdc6.8abc03ab.js b/build-staging/es/assets/js/a8c7fdc6.8abc03ab.js new file mode 100644 index 00000000..857e22e0 --- /dev/null +++ b/build-staging/es/assets/js/a8c7fdc6.8abc03ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1602],{6454:e=>{e.exports=JSON.parse('{"pluginId":"docs-security","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Cwtch Security Handbook","href":"/es/security/intro","docId":"intro"},{"type":"link","label":"Risk Model","href":"/es/security/risk","docId":"risk"},{"type":"category","label":"Cwtch Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cwtch Technical Basics","href":"/es/security/components/intro","docId":"components/intro"},{"type":"link","label":"Component Ecosystem Overview","href":"/es/security/components/ecosystem-overview","docId":"components/ecosystem-overview"},{"type":"category","label":"Connectivity & Tor","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Connectivity","href":"/es/security/components/connectivity/intro","docId":"components/connectivity/intro"}],"href":"/es/security/category/connectivity--tor"},{"type":"category","label":"Tapir","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Packet Format","href":"/es/security/components/tapir/packet_format","docId":"components/tapir/packet_format"},{"type":"link","label":"Authentication Protocol","href":"/es/security/components/tapir/authentication_protocol","docId":"components/tapir/authentication_protocol"}],"href":"/es/security/category/tapir"},{"type":"category","label":"Cwtch","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Message Formats","href":"/es/security/components/cwtch/message_formats","docId":"components/cwtch/message_formats"},{"type":"link","label":"Key Bundles","href":"/es/security/components/cwtch/key_bundles","docId":"components/cwtch/key_bundles"},{"type":"link","label":"Groups","href":"/es/security/components/cwtch/groups","docId":"components/cwtch/groups"},{"type":"link","label":"Cwtch Server","href":"/es/security/components/cwtch/server","docId":"components/cwtch/server"}],"href":"/es/security/category/cwtch"},{"type":"category","label":"Cwtch UI","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Android Service","href":"/es/security/components/ui/android","docId":"components/ui/android"},{"type":"link","label":"Image Previews","href":"/es/security/components/ui/image_previews","docId":"components/ui/image_previews"},{"type":"link","label":"Input","href":"/es/security/components/ui/input","docId":"components/ui/input"},{"type":"link","label":"Message Overlays","href":"/es/security/components/ui/overlays","docId":"components/ui/overlays"}],"href":"/es/security/category/cwtch-ui"}],"href":"/es/security/category/cwtch-components"},{"type":"link","label":"Deployment","href":"/es/security/deployment","docId":"deployment"},{"type":"link","label":"Development","href":"/es/security/development","docId":"development"},{"type":"link","label":"References","href":"/es/security/references","docId":"references"}]},"docs":{"components/connectivity/intro":{"id":"components/connectivity/intro","title":"Connectivity","description":"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.","sidebar":"tutorialSidebar"},"components/cwtch/groups":{"id":"components/cwtch/groups","title":"Groups","description":"For the most part the Cwtch risk model for groups is split into two distinct profiles:","sidebar":"tutorialSidebar"},"components/cwtch/key_bundles":{"id":"components/cwtch/key_bundles","title":"Key Bundles","description":"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant.","sidebar":"tutorialSidebar"},"components/cwtch/message_formats":{"id":"components/cwtch/message_formats","title":"Message Formats","description":"Peer to Peer Messages","sidebar":"tutorialSidebar"},"components/cwtch/server":{"id":"components/cwtch/server","title":"Cwtch Server","description":"The goal of the Cwtch protocol is to enable group communication through Untrusted Infrastructure.","sidebar":"tutorialSidebar"},"components/ecosystem-overview":{"id":"components/ecosystem-overview","title":"Component Ecosystem Overview","description":"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem.","sidebar":"tutorialSidebar"},"components/intro":{"id":"components/intro","title":"Cwtch Technical Basics","description":"This page presents a brief technical overview of the Cwtch protocol.","sidebar":"tutorialSidebar"},"components/tapir/authentication_protocol":{"id":"components/tapir/authentication_protocol","title":"Authentication Protocol","description":"Each peer, given an open connection $C$:","sidebar":"tutorialSidebar"},"components/tapir/packet_format":{"id":"components/tapir/packet_format","title":"Packet Format","description":"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, len bytes of data, and the rest zero padded:","sidebar":"tutorialSidebar"},"components/ui/android":{"id":"components/ui/android","title":"Android Service","description":"Adapted from Integrating FFI processes with Android services","sidebar":"tutorialSidebar"},"components/ui/image_previews":{"id":"components/ui/image_previews","title":"Image Previews","description":"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.","sidebar":"tutorialSidebar"},"components/ui/input":{"id":"components/ui/input","title":"Input","description":"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices","sidebar":"tutorialSidebar"},"components/ui/overlays":{"id":"components/ui/overlays","title":"Message Overlays","description":"Adapted from Notes on the Cwtch Chat API","sidebar":"tutorialSidebar"},"deployment":{"id":"deployment","title":"Deployment","description":"Risk: Binaries are replaced on the website with malicious ones","sidebar":"tutorialSidebar"},"development":{"id":"development","title":"Development","description":"The main process to counter malicious actors in development of Cwtch is the openness of the process.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Cwtch Security Handbook","description":"Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes.","sidebar":"tutorialSidebar"},"references":{"id":"references","title":"References","description":"* Atwater, Erinn, and Sarah Jamie Lewis. \\"Token Based Services-Differences from Privacy Pass.\\"","sidebar":"tutorialSidebar"},"risk":{"id":"risk","title":"Risk Model","description":"Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ac9aaa3f.f662d91d.js b/build-staging/es/assets/js/ac9aaa3f.f662d91d.js new file mode 100644 index 00000000..acdfe807 --- /dev/null +++ b/build-staging/es/assets/js/ac9aaa3f.f662d91d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6801],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},b=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=s(n),b=o,m=p["".concat(l,".").concat(b)]||p[b]||d[b]||a;return n?r.createElement(m,c(c({ref:t},u),{},{components:n})):r.createElement(m,c({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=b;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,c[1]=i;for(var s=2;s<a;s++)c[s]=n[s];return r.createElement.apply(null,c)}return r.createElement.apply(null,n)}b.displayName="MDXCreateElement"},5514:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:8},c="Desbloquear un contacto",i={unversionedId:"chat/unblock-contact",id:"chat/unblock-contact",title:"Desbloquear un contacto",description:"1. Selecciona el contacto en tu lista de conversaci\xf3nes. Los contactos bloqueados se mueven al final de la lista.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/unblock-contact.md",sourceDirName:"chat",slug:"/chat/unblock-contact",permalink:"/es/docs/chat/unblock-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/unblock-contact.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"Bloquear un contacto",permalink:"/es/docs/chat/block-contact"},next:{title:"Removing a Conversation",permalink:"/es/docs/chat/delete-contact"}},l={},s=[],u={toc:s},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"desbloquear-un-contacto"},"Desbloquear un contacto"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Selecciona el contacto en tu lista de conversaci\xf3nes. Los contactos bloqueados se mueven al final de la lista."),(0,o.kt)("li",{parentName:"ol"},"Ve a la configuraci\xf3n de conversaci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo para bloquear contacto"),(0,o.kt)("li",{parentName:"ol"},"Mueve el interruptor para desbloquear contacto")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/af23c5f9.faebd2cb.js b/build-staging/es/assets/js/af23c5f9.faebd2cb.js new file mode 100644 index 00000000..e1242ec9 --- /dev/null +++ b/build-staging/es/assets/js/af23c5f9.faebd2cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3218],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){i(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,i=function(e,t){if(null==e)return{};var a,n,i={},r=Object.keys(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),h=p(a),m=i,d=h["".concat(s,".").concat(m)]||h[m]||u[m]||r;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:i,o[1]=l;for(var p=2;p<r;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},4958:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var n=a(7462),i=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"31 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/es/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/es/blog/cwtch-nightly-1-11"}},s={authorsImageUrls:[void 0]},p=[{value:"Update on the January Roadmap",id:"update-on-the-january-roadmap",level:2},{value:"A Timeline for Cwtch Stable",id:"a-timeline-for-cwtch-stable",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},h="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(h,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,i.kt)("strong",{parentName:"p"},"Beta")," to ",(0,i.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,i.kt)("p",null,"This post ",(0,i.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,i.kt)("p",null,(0,i.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,i.kt)("h2",{id:"update-on-the-january-roadmap"},"Update on the January Roadmap"),(0,i.kt)("p",null,"Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:"),(0,i.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"finalized a feature set that defines Cwtch Stable")," and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/security/intro"},"Security and Design Documents")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"Infrastructure and ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"Support")," \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"in addition to a new development blog. \u2705"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a ",(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"style guide for documentation"),", and \u2705"),(0,i.kt)("li",{parentName:"ul"},"have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"with at least one screenshot (where applicable). \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published: ",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"Interface Specification Document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Release Process Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-platform-support"},"Support Plan document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Packaging Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a document describing the ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"Reproducible Builds Process")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)")),(0,i.kt)("p",null,"While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings"},"Cwtch Autobindings")," with ",(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings-ii"},"compile-time optional experiments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-nightly-1-11"},"Cwtch 1.11")," - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.")),(0,i.kt)("h2",{id:"a-timeline-for-cwtch-stable"},"A Timeline for Cwtch Stable"),(0,i.kt)("p",null,"Now for the big news, we plan on releasing a candidate Cwtch Stable release during ",(0,i.kt)("strong",{parentName:"p"},"Summer 2023"),". Here is our plan for getting there:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document"),(0,i.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document"),(0,i.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots."))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries"),(0,i.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"An implementation of ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information"),(0,i.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist."),(0,i.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team"),(0,i.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable."),(0,i.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,i.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,i.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,i.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,i.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,i.kt)("h2",{id:"get-involved"},"Get Involved"),(0,i.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,i.kt)("p",null,"We also also updated our guides on ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,i.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,i.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/af2fa732.7fc763b4.js b/build-staging/es/assets/js/af2fa732.7fc763b4.js new file mode 100644 index 00000000..8d038add --- /dev/null +++ b/build-staging/es/assets/js/af2fa732.7fc763b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6753],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=o,f=u["".concat(c,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(f,a(a({ref:t},p),{},{components:r})):n.createElement(f,a({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var l=2;l<i;l++)a[l]=r[l];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},7245:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:2},a="Alojamiento de servidor",s={unversionedId:"settings/experiments/server-hosting",id:"settings/experiments/server-hosting",title:"Alojamiento de servidor",description:"El alojamiento del servidor es actualmente una caracter\xedstica experimental en Cwtch, no est\xe1 habilitado por defecto.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/server-hosting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/server-hosting",permalink:"/es/docs/settings/experiments/server-hosting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/server-hosting.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Groups Experiment",permalink:"/es/docs/settings/experiments/group-experiment"},next:{title:"Compartir Archivos",permalink:"/es/docs/settings/experiments/file-sharing"}},c={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"alojamiento-de-servidor"},"Alojamiento de servidor"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"El alojamiento del servidor es actualmente una caracter\xedstica experimental en Cwtch, no est\xe1 habilitado por defecto.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ir a Configuraci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Habilitar Experimentos"),(0,o.kt)("li",{parentName:"ol"},"Habilitar el experimento de Alojamiento de servidor"),(0,o.kt)("li",{parentName:"ol"},"Probablemente tambi\xe9n querr\xe1s activar el experimento de Grupos si quieres participar en un grupo alojado en tu servidor")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/af971761.397b2387.js b/build-staging/es/assets/js/af971761.397b2387.js new file mode 100644 index 00000000..5f937dfe --- /dev/null +++ b/build-staging/es/assets/js/af971761.397b2387.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7251],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),u=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=u(e.components);return r.createElement(l.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),s=u(n),f=o,m=s["".concat(l,".").concat(f)]||s[f]||d[f]||a;return n?r.createElement(m,c(c({ref:t},p),{},{components:n})):r.createElement(m,c({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[s]="string"==typeof e?e:o,c[1]=i;for(var u=2;u<a;u++)c[u]=n[u];return r.createElement.apply(null,c)}return r.createElement.apply(null,n)}f.displayName="MDXCreateElement"},1401:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:7},c="Bloquear un contacto",i={unversionedId:"chat/block-contact",id:"chat/block-contact",title:"Bloquear un contacto",description:"1. En una ventana de conversaci\xf3n",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/block-contact.md",sourceDirName:"chat",slug:"/chat/block-contact",permalink:"/es/docs/chat/block-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/block-contact.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Compartir un archivo",permalink:"/es/docs/chat/share-file"},next:{title:"Desbloquear un contacto",permalink:"/es/docs/chat/unblock-contact"}},l={},u=[],p={toc:u},s="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(s,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"bloquear-un-contacto"},"Bloquear un contacto"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"En una ventana de conversaci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Ir a la Configuraci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo hasta bloquear contacto"),(0,o.kt)("li",{parentName:"ol"},"Mueve el interruptor para bloquear un contacto")),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/b0367817.4d1f5666.js b/build-staging/es/assets/js/b0367817.4d1f5666.js new file mode 100644 index 00000000..3049a12e --- /dev/null +++ b/build-staging/es/assets/js/b0367817.4d1f5666.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8525],{429:s=>{s.exports=JSON.parse('{"title":"Platforms","slug":"/category/platforms","permalink":"/es/docs/category/platforms","navigation":{"previous":{"title":"Stickers","permalink":"/es/docs/contribute/stickers"},"next":{"title":"Running Cwtch on Tails","permalink":"/es/docs/platforms/tails"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/b0404c31.be62635c.js b/build-staging/es/assets/js/b0404c31.be62635c.js new file mode 100644 index 00000000..d356bb47 --- /dev/null +++ b/build-staging/es/assets/js/b0404c31.be62635c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7860],{3905:(e,t,a)=>{a.d(t,{Zo:()=>h,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){o(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,o=function(e,t){if(null==e)return{};var a,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},h=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(a),u=o,m=p["".concat(s,".").concat(u)]||p[u]||d[u]||i;return a?n.createElement(m,r(r({ref:t},h),{},{components:a})):n.createElement(m,r({ref:t},h))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=a.length,r=new Array(i);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var c=2;c<i;c++)r[c]=a[c];return n.createElement.apply(null,r)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},3478:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const i={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/es/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"6 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/es/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"Tenets of Cwtch Stable",id:"tenets-of-cwtch-stable",level:3},{value:"Known Problems",id:"known-problems",level:3},{value:"Plan of Action",id:"plan-of-action",level:3},{value:"Goals and Timelines",id:"goals-and-timelines",level:3},{value:"Help us get there!",id:"help-us-get-there",level:3}],h={toc:c},p="wrapper";function d(e){let{components:t,...i}=e;return(0,o.kt)(p,(0,n.Z)({},h,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,o.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,o.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h3",{id:"tenets-of-cwtch-stable"},"Tenets of Cwtch Stable"),(0,o.kt)("p",null,"It is important to state that Cwtch Stable ",(0,o.kt)("strong",{parentName:"p"},"does not mean an end to Cwtch development"),". Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Consistent Interface")," \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Universal Availability and Cohesive Support")," \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Reproducible Builds")," \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Proven Security")," \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.")),(0,o.kt)("h3",{id:"known-problems"},"Known Problems"),(0,o.kt)("p",null,"To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of a Stable API for future feature development")," \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Special functionality in libCwtch-go")," \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"libCwtch-rs partial support")," - we currently do not officially consider ",(0,o.kt)("a",{parentName:"li",href:"https://lib.rs/crates/libcwtch"},"libCwtch-rs")," when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Reproducible Pipelines")," - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of up to date, and translated, Security Documentation")," \u2013 the ",(0,o.kt)("a",{parentName:"li",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Cwtch security handbook")," is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"No Automated UI Tests")," \u2013 we put a lot of work into ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"building out a testing framework for the UI"),", but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Code Signing Provider")," \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Second-class Android Support")," - while we have put ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/27-android-improvements/"},"a lot of effort behind Android support")," across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Fuzzing")," \u2013 while ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Fuzzbot")," sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Formal Release Acceptance Process")," \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Inconsistent Cwtch Information Discovery")," \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Incomplete Documentation")," \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)")),(0,o.kt)("h3",{id:"plan-of-action"},"Plan of Action"),(0,o.kt)("p",null,"Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Interface Specification Documentation")," \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Release Process")," \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Support Document")," - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Packaging Document")," - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Reproducible Builds Document")," \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand the Cwtch Documentation Site")," \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand our Automated Testing to include UI and Fuzzing")," - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Re-evaluate all Issues across all Cwtch related repositories")," \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define a Stable Feature Set")," \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)")),(0,o.kt)("h3",{id:"goals-and-timelines"},"Goals and Timelines"),(0,o.kt)("p",null,"With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.")),(0,o.kt)("p",null,"As these documents are written, and these goals met we will be posting them here! Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, Cwtch development."),(0,o.kt)("h3",{id:"help-us-get-there"},"Help us get there!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/b125d866.164edb4b.js b/build-staging/es/assets/js/b125d866.164edb4b.js new file mode 100644 index 00000000..41a2f696 --- /dev/null +++ b/build-staging/es/assets/js/b125d866.164edb4b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8799],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function c(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),s=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),h=s(a),d=n,m=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return a?r.createElement(m,i(i({ref:t},p),{},{components:a})):r.createElement(m,i({ref:t},p))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var s=2;s<o;s++)i[s]=a[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}d.displayName="MDXCreateElement"},1595:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/es/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"30 de junio de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/es/blog/cwtch-nightly-1-12"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/b4165829.35928455.js b/build-staging/es/assets/js/b4165829.35928455.js new file mode 100644 index 00000000..52babd0d --- /dev/null +++ b/build-staging/es/assets/js/b4165829.35928455.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2033],{3905:(e,n,t)=>{t.d(n,{Zo:()=>l,kt:()=>m});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function c(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var s=r.createContext({}),p=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},l=function(e){var n=p(e.components);return r.createElement(s.Provider,{value:n},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=p(t),f=a,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||o;return t?r.createElement(m,c(c({ref:n},l),{},{components:t})):r.createElement(m,c({ref:n},l))}));function m(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,c=new Array(o);c[0]=f;var i={};for(var s in n)hasOwnProperty.call(n,s)&&(i[s]=n[s]);i.originalType=e,i[u]="string"==typeof e?e:a,c[1]=i;for(var p=2;p<o;p++)c[p]=t[p];return r.createElement.apply(null,c)}return r.createElement.apply(null,t)}f.displayName="MDXCreateElement"},1646:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=t(7462),a=(t(7294),t(3905));const o={sidebar_position:2},c="Aceptar/denegar nuevas conversaciones",i={unversionedId:"chat/accept-deny-new-conversation",id:"chat/accept-deny-new-conversation",title:"Aceptar/denegar nuevas conversaciones",description:"1. Ir a tu perfil",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/accept-deny-new-conversation.md",sourceDirName:"chat",slug:"/chat/accept-deny-new-conversation",permalink:"/es/docs/chat/accept-deny-new-conversation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/accept-deny-new-conversation.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Starting a New Conversation",permalink:"/es/docs/chat/add-contact"},next:{title:"Sharing Cwtch Addresses",permalink:"/es/docs/chat/share-address-with-friends"}},s={},p=[],l={toc:p},u="wrapper";function d(e){let{components:n,...t}=e;return(0,a.kt)(u,(0,r.Z)({},l,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"aceptardenegar-nuevas-conversaciones"},"Aceptar/denegar nuevas conversaciones"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Ir a tu perfil"),(0,a.kt)("li",{parentName:"ol"},"Si alguien te agreg\xf3 un nuevo nombre y dos opciones aparecer\xe1n",(0,a.kt)("ol",{parentName:"li"},(0,a.kt)("li",{parentName:"ol"},"Haz clic en el icono de coraz\xf3n para aceptar esta nueva conexi\xf3n"),(0,a.kt)("li",{parentName:"ol"},"Haz clic en el icono de la papelera para bloquear una nueva conexi\xf3n")))),(0,a.kt)("p",null,"Ve tambi\xe9n: ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/behaviour/block-unknown-connections"},"Configuraci\xf3n: Bloquear Conexiones Desconocidas")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/b4876842.3aede96b.js b/build-staging/es/assets/js/b4876842.3aede96b.js new file mode 100644 index 00000000..e683b2d8 --- /dev/null +++ b/build-staging/es/assets/js/b4876842.3aede96b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6021],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l<i;l++)o[l]=n[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},7665:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={sidebar_position:1},o="Running Cwtch on Tails",s={unversionedId:"platforms/tails",id:"platforms/tails",title:"Running Cwtch on Tails",description:"This functionality is currently only available in the Nightly Release builds of Cwtch.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/platforms/tails.md",sourceDirName:"platforms",slug:"/platforms/tails",permalink:"/es/docs/platforms/tails",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/platforms/tails.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Platforms",permalink:"/es/docs/category/platforms"}},c={},l=[{value:"Onion Grater Configuration",id:"onion-grater-configuration",level:2},{value:"Persistence",id:"persistence",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"running-cwtch-on-tails"},"Running Cwtch on Tails"),(0,a.kt)("admonition",{title:"Nightly Feature",type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"This functionality is currently ",(0,a.kt)("strong",{parentName:"p"},"only")," available in the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly Release")," builds of Cwtch."),(0,a.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,a.kt)("p",null,"The following steps require that Tails has been launched with an ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/first_steps/welcome_screen/administration_password/"},"Administration Password"),"."),(0,a.kt)("p",null,"Tails uses ",(0,a.kt)("a",{parentName:"p",href:"https://gitlab.tails.boum.org/tails/tails/-/blob/master/config/chroot_local-includes/usr/local/lib/onion-grater#L3"},"Onion Grater")," to guard access to the control port. We have packaged an oniongrater configuration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," and setup script (",(0,a.kt)("inlineCode",{parentName:"p"},"install-tails.sh"),") with Cwtch on Linux."),(0,a.kt)("p",null,"The tails-specific part of the script is reproduced below:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," # Tails needs to be have been setup up with an Administration account\n # \n # Make Auth Cookie Readable\n sudo chmod o+r /var/run/tor/control.authcookie\n # Copy Onion Grater Config\n sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml\n # Restart Onion Grater so the Config Takes effect\n sudo systemctl restart onion-grater.service\n")),(0,a.kt)("p",null,"When launching, Cwtch on Tails should be passed the ",(0,a.kt)("inlineCode",{parentName:"p"},"CWTCH_TAILS=true")," environment variable to automatically configure Cwtch for running in a Tails-like environment:"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch")),(0,a.kt)("admonition",{title:"Install Location",type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The above command, and the below onion grater configuration assume that Cwtch was installed in ",(0,a.kt)("inlineCode",{parentName:"p"},"~/.local/lib/cwtch/cwtch")," - if Cwtch was installed somewhere else (or if you are running directly from the download folder) then you will need to adjust the commands.")),(0,a.kt)("h2",{id:"onion-grater-configuration"},"Onion Grater Configuration"),(0,a.kt)("p",null,"The oniongrater configuration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," is reproduced below. As noted this configuration is can likely be restricted much further. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," ---\n # TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern\n\n - apparmor-profiles:\n - '/home/amnesia/.local/lib/cwtch/cwtch'\n users:\n\n - 'amnesia'\n commands:\n AUTHCHALLENGE:\n\n - 'SAFECOOKIE .*'\n SETEVENTS:\n\n - 'CIRC WARN ERR'\n - 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'\n GETINFO:\n\n - '.*'\n GETCONF:\n\n - 'DisableNetwork'\n SETCONF:\n\n - 'DisableNetwork.*'\n ADD_ONION:\n\n - '.*'\n DEL_ONION:\n\n - '.+'\n HSFETCH:\n\n - '.+'\n events:\n CIRC:\n suppress: true\n ORCONN:\n suppress: true\n INFO:\n suppress: true\n NOTICE:\n suppress: true\n WARN:\n suppress: true\n ERR:\n suppress: true\n HS_DESC:\n response:\n\n - pattern: '650 HS_DESC CREATED (\\S+) (\\S+) (\\S+) \\S+ (.+)'\n replacement: '650 HS_DESC CREATED {} {} {} redacted {}'\n\n - pattern: '650 HS_DESC UPLOAD (\\S+) (\\S+) .*'\n replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'\n\n - pattern: '650 HS_DESC UPLOADED (\\S+) (\\S+) .+'\n replacement: '650 HS_DESC UPLOADED {} {} redacted'\n\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH'\n\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'\n\n - pattern: '650 HS_DESC RECEIVED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'\n\n - pattern: '.*'\n replacement: ''\n HS_DESC_CONTENT:\n suppress: true\n")),(0,a.kt)("h2",{id:"persistence"},"Persistence"),(0,a.kt)("p",null,"By default, Cwtch creates ",(0,a.kt)("inlineCode",{parentName:"p"},"$HOME/.cwtch")," and saves all encrypted profiles and settings files there. In order to save any profiles/conversations in Cwtch on Tails you will have to backup this folder to a non-volatile home."),(0,a.kt)("p",null,"See the Tails documentation for setting up ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/persistent_storage/"},"persistent storage")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/b77581fc.36d30fdd.js b/build-staging/es/assets/js/b77581fc.36d30fdd.js new file mode 100644 index 00000000..cee96e55 --- /dev/null +++ b/build-staging/es/assets/js/b77581fc.36d30fdd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5004],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>m});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?a(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function l(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},a=Object.keys(e);for(n=0;n<a.length;n++)t=a[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)t=a[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=n.createContext({}),s=function(e){var r=n.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):o(o({},r),e)),t},c=function(e){var r=s(e.components);return n.createElement(p.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(t),d=i,m=u["".concat(p,".").concat(d)]||u[d]||f[d]||a;return t?n.createElement(m,o(o({ref:r},c),{},{components:t})):n.createElement(m,o({ref:r},c))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=d;var l={};for(var p in r)hasOwnProperty.call(r,p)&&(l[p]=r[p]);l.originalType=e,l[u]="string"==typeof e?e:i,o[1]=l;for(var s=2;s<a;s++)o[s]=t[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},9267:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>o,default:()=>f,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var n=t(7462),i=(t(7294),t(3905));const a={sidebar_position:6},o="Eliminar un perfil",l={unversionedId:"profiles/delete-profile",id:"profiles/delete-profile",title:"Eliminar un perfil",description:"Esta funci\xf3n resultar\xe1 en la eliminaci\xf3n irreversible de material clave. Esto no se puede deshacer.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/delete-profile.md",sourceDirName:"profiles",slug:"/profiles/delete-profile",permalink:"/es/docs/profiles/delete-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/delete-profile.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Desbloquear perfiles cifrados",permalink:"/es/docs/profiles/unlock-profile"},next:{title:"Copia de seguridad o Exportaci\xf3n de un perfil",permalink:"/es/docs/profiles/exporting-profile"}},p={},s=[],c={toc:s},u="wrapper";function f(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"eliminar-un-perfil"},"Eliminar un perfil"),(0,i.kt)("admonition",{type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"Esta funci\xf3n resultar\xe1 en la eliminaci\xf3n ",(0,i.kt)("strong",{parentName:"p"},"irreversible")," de material clave. Esto ",(0,i.kt)("strong",{parentName:"p"},"no se puede deshacer"),".")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Pulsa el l\xe1piz junto al perfil que quieres editar"),(0,i.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo hasta la parte inferior de la pantalla"),(0,i.kt)("li",{parentName:"ol"},"Pulsa eliminar"),(0,i.kt)("li",{parentName:"ol"},"Pulsa realmente eliminar perfil")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/bb45cad0.30e00de6.js b/build-staging/es/assets/js/bb45cad0.30e00de6.js new file mode 100644 index 00000000..39fec6e8 --- /dev/null +++ b/build-staging/es/assets/js/bb45cad0.30e00de6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[908],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>d});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),m=i,d=u["".concat(c,".").concat(m)]||u[m]||f[m]||o;return r?n.createElement(d,a(a({ref:t},l),{},{components:r})):n.createElement(d,a({ref:t},l))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var p=2;p<o;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8157:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:3},a="Compartir Archivos",s={unversionedId:"settings/experiments/file-sharing",id:"settings/experiments/file-sharing",title:"Compartir Archivos",description:'These setting enables Cwtch filesharing functionality. This reveals the "Share File" option in the conversation pane, and allows you to download files from conversations.',source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/file-sharing.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/file-sharing",permalink:"/es/docs/settings/experiments/file-sharing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/file-sharing.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Alojamiento de servidor",permalink:"/es/docs/settings/experiments/server-hosting"},next:{title:"Vista previa de im\xe1genes y fotos de perfil",permalink:"/es/docs/settings/experiments/image-previews-and-profile-pictures"}},c={},p=[],l={toc:p},u="wrapper";function f(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"compartir-archivos"},"Compartir Archivos"),(0,i.kt)("p",null,"These setting enables Cwtch ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/share-file"},"filesharing functionality"),'. This reveals the "Share File" option in the conversation pane, and allows you to download files from conversations.'),(0,i.kt)("p",null,"Optionally, you can enable ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," to download image files automatically, view image previews in the conversation window, and enable the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profile Pictures")," feature;"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/bcc84138.5bb1e05c.js b/build-staging/es/assets/js/bcc84138.5bb1e05c.js new file mode 100644 index 00000000..29a80d18 --- /dev/null +++ b/build-staging/es/assets/js/bcc84138.5bb1e05c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5103],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>g});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?l(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function p(t,e){if(null==t)return{};var a,n,r=function(t,e){if(null==t)return{};var a,n,r={},l=Object.keys(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),d=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},u=function(t){var e=d(t.components);return n.createElement(o.Provider,{value:e},t.children)},m="mdxType",s={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,u=p(t,["components","mdxType","originalType","parentName"]),m=d(a),c=r,g=m["".concat(o,".").concat(c)]||m[c]||s[c]||l;return a?n.createElement(g,i(i({ref:e},u),{},{components:a})):n.createElement(g,i({ref:e},u))}));function g(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=c;var p={};for(var o in e)hasOwnProperty.call(e,o)&&(p[o]=e[o]);p.originalType=t,p[m]="string"==typeof t?t:r,i[1]=p;for(var d=2;d<l;d++)i[d]=a[d];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},461:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var n=a(7462),r=(a(7294),a(3905));const l={},i="Supported Platforms",p={unversionedId:"getting-started/supported_platforms",id:"getting-started/supported_platforms",title:"Supported Platforms",description:"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/getting-started/supported_platforms.md",sourceDirName:"getting-started",slug:"/getting-started/supported_platforms",permalink:"/es/docs/getting-started/supported_platforms",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/getting-started/supported_platforms.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/es/docs/category/getting-started"},next:{title:"Profiles",permalink:"/es/docs/category/profiles"}},o={},d=[],u={toc:d},m="wrapper";function s(t){let{components:e,...a}=t;return(0,r.kt)(m,(0,n.Z)({},u,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"supported-platforms"},"Supported Platforms"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023)."),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. If you are interested in testing Cwtch on a specific platform, or want to volunteer to help us official support a platform not listed here, then check out ",(0,r.kt)("a",{parentName:"p",href:"/docs/category/contribute"},"Contibuting to Cwtch"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/bdf5d676.5ba7b55d.js b/build-staging/es/assets/js/bdf5d676.5ba7b55d.js new file mode 100644 index 00000000..2ed4d82a --- /dev/null +++ b/build-staging/es/assets/js/bdf5d676.5ba7b55d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5291],{3905:(e,t,a)=>{a.d(t,{Zo:()=>l,kt:()=>g});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function c(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},i=Object.keys(e);for(r=0;r<i.length;r++)a=i[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)a=i[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var s=r.createContext({}),p=function(e){var t=r.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(a),m=n,g=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return a?r.createElement(g,o(o({ref:t},l),{},{components:a})):r.createElement(g,o({ref:t},l))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=a.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:n,o[1]=c;for(var p=2;p<i;p++)o[p]=a[p];return r.createElement.apply(null,o)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},6426:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const i={sidebar_position:1},o="Cambiar idioma",c={unversionedId:"settings/appearance/change-language",id:"settings/appearance/change-language",title:"Cambiar idioma",description:"Gracias a la ayuda de voluntarios, la aplicaci\xf3n Cwtch ha sido traducida a muchos idiomas.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/change-language.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/change-language",permalink:"/es/docs/settings/appearance/change-language",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/change-language.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Appearance",permalink:"/es/docs/category/appearance"},next:{title:"Explicaci\xf3n de temas Claros/Oscuros",permalink:"/es/docs/settings/appearance/light-dark-mode"}},s={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...a}=e;return(0,n.kt)(u,(0,r.Z)({},l,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"cambiar-idioma"},"Cambiar idioma"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"Gracias a la ayuda de voluntarios"),", la aplicaci\xf3n Cwtch ha sido traducida a muchos idiomas."),(0,n.kt)("p",null,"Para cambiar el idioma de Cwtch:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Abrir configuraci\xf3n"),(0,n.kt)("li",{parentName:"ol"},'La opci\xf3n superior es "Idioma", puedes usar el men\xfa desplegable para seleccionar el idioma que deseas utilizar.')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/be9a5550.08f0d5b4.js b/build-staging/es/assets/js/be9a5550.08f0d5b4.js new file mode 100644 index 00000000..e4a954b8 --- /dev/null +++ b/build-staging/es/assets/js/be9a5550.08f0d5b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2279],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>f});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){a(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,a=function(e,r){if(null==e)return{};var t,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},v=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),v=a,f=u["".concat(c,".").concat(v)]||u[v]||d[v]||o;return t?n.createElement(f,i(i({ref:r},p),{},{components:t})):n.createElement(f,i({ref:r},p))}));function f(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var o=t.length,i=new Array(o);i[0]=v;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var l=2;l<o;l++)i[l]=t[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,t)}v.displayName="MDXCreateElement"},1091:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(7462),a=(t(7294),t(3905));const o={sidebar_position:4},i="Guardar el historial de conversaciones",s={unversionedId:"chat/save-conversation-history",id:"chat/save-conversation-history",title:"Guardar el historial de conversaciones",description:"Por defecto, por privacidad, Cwtch no conserva el historial de conversaciones entre sesiones.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/save-conversation-history.md",sourceDirName:"chat",slug:"/chat/save-conversation-history",permalink:"/es/docs/chat/save-conversation-history",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/save-conversation-history.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Sharing Cwtch Addresses",permalink:"/es/docs/chat/share-address-with-friends"},next:{title:"Formato de mensajes",permalink:"/es/docs/chat/message-formatting"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,a.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"guardar-el-historial-de-conversaciones"},"Guardar el historial de conversaciones"),(0,a.kt)("p",null,"Por defecto, por privacidad, Cwtch no conserva el historial de conversaciones entre sesiones."),(0,a.kt)("p",null,"Para habilitar el historial de una conversaci\xf3n espec\xedfica:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"En una ventana de conversaci\xf3n ve a Ajustes"),(0,a.kt)("li",{parentName:"ol"},"Ve a Guardar Historial"),(0,a.kt)("li",{parentName:"ol"},"Pulsa el men\xfa desplegable"),(0,a.kt)("li",{parentName:"ol"},"Elege Guardar el Historial"),(0,a.kt)("li",{parentName:"ol"},"Ahora tu historial se guardar\xe1")),(0,a.kt)("p",null,'El historial de conversaciones puede desactivarse en cualquier momento seleccionando "Borrar Historial" en el men\xfa desplegable.'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/bf059cf9.c718c160.js b/build-staging/es/assets/js/bf059cf9.c718c160.js new file mode 100644 index 00000000..f27de64f --- /dev/null +++ b/build-staging/es/assets/js/bf059cf9.c718c160.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5273],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>b});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,i,n=function(e,t){if(null==e)return{};var r,i,n={},a=Object.keys(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=i.createContext({}),s=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=s(e.components);return i.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=s(r),g=n,b=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return r?i.createElement(b,o(o({ref:t},p),{},{components:r})):i.createElement(b,o({ref:t},p))}));function b(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=g;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[d]="string"==typeof e?e:n,o[1]=c;for(var s=2;s<a;s++)o[s]=r[s];return i.createElement.apply(null,o)}return i.createElement.apply(null,r)}g.displayName="MDXCreateElement"},2626:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/es/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"10 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/es/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"repliqate",permalink:"/es/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/es/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/es/blog/cwtch-testing-i"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},d="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(d,(0,i.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(4756).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},4756:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c14f15fd.96c2246e.js b/build-staging/es/assets/js/c14f15fd.96c2246e.js new file mode 100644 index 00000000..af5cdeec --- /dev/null +++ b/build-staging/es/assets/js/c14f15fd.96c2246e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7649],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,f=u["".concat(s,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},3071:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:2},i="Core Concepts",c={unversionedId:"building-a-cwtch-app/core-concepts",id:"building-a-cwtch-app/core-concepts",title:"Core Concepts",description:"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.",source:"@site/developing/building-a-cwtch-app/core-concepts.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/core-concepts",permalink:"/es/developing/building-a-cwtch-app/core-concepts",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Getting Started",permalink:"/es/developing/building-a-cwtch-app/intro"},next:{title:"Building a Cwtch Echobot",permalink:"/es/developing/building-a-cwtch-app/building-an-echobot"}},s={},l=[{value:"Cwtch Home Directory",id:"cwtch-home-directory",level:2},{value:"Profiles",id:"profiles",level:2},{value:"The Event Bus",id:"the-event-bus",level:2},{value:"Settings",id:"settings",level:2},{value:"Experiments",id:"experiments",level:3}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"core-concepts"},"Core Concepts"),(0,a.kt)("p",null,"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently."),(0,a.kt)("h2",{id:"cwtch-home-directory"},"Cwtch Home Directory"),(0,a.kt)("p",null,"Often referred to as ",(0,a.kt)("inlineCode",{parentName:"p"},"$CWTCH_HOME"),", the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application."),(0,a.kt)("h2",{id:"profiles"},"Profiles"),(0,a.kt)("p",null,"Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations."),(0,a.kt)("h2",{id:"the-event-bus"},"The Event Bus"),(0,a.kt)("p",null,"Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"NewMessageFromPeer")," and setup an event handler to run code in response to such a message."),(0,a.kt)("p",null,"For an example see the Echo Bot tutorial."),(0,a.kt)("h2",{id:"settings"},"Settings"),(0,a.kt)("p",null,"Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration."),(0,a.kt)("h3",{id:"experiments"},"Experiments"),(0,a.kt)("p",null,"Certain Cwtch features are ",(0,a.kt)("a",{parentName:"p",href:"/docs/category/experiments"},"gated behind experiments"),". These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c21eb9f5.46800ab1.js b/build-staging/es/assets/js/c21eb9f5.46800ab1.js new file mode 100644 index 00000000..a6b5a776 --- /dev/null +++ b/build-staging/es/assets/js/c21eb9f5.46800ab1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5910],{748:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/repliqate","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c3ed911f.21534c5a.js b/build-staging/es/assets/js/c3ed911f.21534c5a.js new file mode 100644 index 00000000..e90eb60d --- /dev/null +++ b/build-staging/es/assets/js/c3ed911f.21534c5a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2091],{3905:(a,e,t)=>{t.d(e,{Zo:()=>N,kt:()=>h});var m=t(7294);function s(a,e,t){return e in a?Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[e]=t,a}function n(a,e){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var m=Object.getOwnPropertySymbols(a);e&&(m=m.filter((function(e){return Object.getOwnPropertyDescriptor(a,e).enumerable}))),t.push.apply(t,m)}return t}function p(a){for(var e=1;e<arguments.length;e++){var t=null!=arguments[e]?arguments[e]:{};e%2?n(Object(t),!0).forEach((function(e){s(a,e,t[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(t)):n(Object(t)).forEach((function(e){Object.defineProperty(a,e,Object.getOwnPropertyDescriptor(t,e))}))}return a}function r(a,e){if(null==a)return{};var t,m,s=function(a,e){if(null==a)return{};var t,m,s={},n=Object.keys(a);for(m=0;m<n.length;m++)t=n[m],e.indexOf(t)>=0||(s[t]=a[t]);return s}(a,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(a);for(m=0;m<n.length;m++)t=n[m],e.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(a,t)&&(s[t]=a[t])}return s}var i=m.createContext({}),l=function(a){var e=m.useContext(i),t=e;return a&&(t="function"==typeof a?a(e):p(p({},e),a)),t},N=function(a){var e=l(a.components);return m.createElement(i.Provider,{value:e},a.children)},o="mdxType",k={inlineCode:"code",wrapper:function(a){var e=a.children;return m.createElement(m.Fragment,{},e)}},c=m.forwardRef((function(a,e){var t=a.components,s=a.mdxType,n=a.originalType,i=a.parentName,N=r(a,["components","mdxType","originalType","parentName"]),o=l(t),c=s,h=o["".concat(i,".").concat(c)]||o[c]||k[c]||n;return t?m.createElement(h,p(p({ref:e},N),{},{components:t})):m.createElement(h,p({ref:e},N))}));function h(a,e){var t=arguments,s=e&&e.mdxType;if("string"==typeof a||s){var n=t.length,p=new Array(n);p[0]=c;var r={};for(var i in e)hasOwnProperty.call(e,i)&&(r[i]=e[i]);r.originalType=a,r[o]="string"==typeof a?a:s,p[1]=r;for(var l=2;l<n;l++)p[l]=t[l];return m.createElement.apply(null,p)}return m.createElement.apply(null,t)}c.displayName="MDXCreateElement"},4977:(a,e,t)=>{t.r(e),t.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>k,frontMatter:()=>n,metadata:()=>r,toc:()=>l});var m=t(7462),s=(t(7294),t(3905));const n={sidebar_position:2},p="Authentication Protocol",r={unversionedId:"components/tapir/authentication_protocol",id:"components/tapir/authentication_protocol",title:"Authentication Protocol",description:"Each peer, given an open connection $C$:",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/tapir/authentication_protocol.md",sourceDirName:"components/tapir",slug:"/components/tapir/authentication_protocol",permalink:"/es/security/components/tapir/authentication_protocol",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Packet Format",permalink:"/es/security/components/tapir/packet_format"},next:{title:"Cwtch",permalink:"/es/security/category/cwtch"}},i={},l=[{value:"Cryptographic Properties",id:"cryptographic-properties",level:3}],N={toc:l},o="wrapper";function k(a){let{components:e,...t}=a;return(0,s.kt)(o,(0,m.Z)({},N,t,{components:e,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"authentication-protocol"},"Authentication Protocol"),(0,s.kt)("p",null,"Each peer, given an open connection ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"C")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"C")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"))))),":"),(0,s.kt)("div",{className:"math math-display"},(0,s.kt)("span",{parentName:"div",className:"katex-display"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"p"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"h"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"m"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"r"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"P"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mi",{parentName:"msup"},"i")),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msup"},"P"),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow"},(0,s.kt)("mover",{parentName:"mo"},(0,s.kt)("mo",{parentName:"mover"},(0,s.kt)("mo",{parentName:"mo"},"=")),(0,s.kt)("mo",{parentName:"mover",stretchy:"false",lspace:"0em",rspace:"0em"},"?"))),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"L"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"e"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"I = \\mathrm{InitializeIdentity()} \\\\ I_e = \\mathrm{InitializeEphemeralIdentity()} \\\\ I,I_e \\rightarrow C \\\\ P,P_e \\leftarrow C \\\\ k = \\mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\\\ c = \\mathrm{E}(k, transcript.Commit()) \\\\ c \\rightarrow C \\\\ c_p \\leftarrow C\\\\ \\mathrm{D}(k, c_p) \\stackrel{?}{=} transcript.LatestCommit()")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeEphemeralIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.958em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P")),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8747em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"E"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},"))")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7167em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.4391em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"D"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},(0,s.kt)("span",{parentName:"span",className:"mop op-limits"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"1.153em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span"},(0,s.kt)("span",{parentName:"span",className:"mop"},"="))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.5669em",marginLeft:"0em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mclose mtight"},"?"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"L"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"a"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"es"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"tC"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")))))),(0,s.kt)("p",null,"The above represents a sketch protocol, in reality there are a few implementation details worth pointing out:"),(0,s.kt)("p",null,"Once derived from the key derivation function (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\mathrm{KDF}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")))))),") the key (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"k")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"k")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"))))),") is set ",(0,s.kt)("em",{parentName:"p"},"on")," the connection, meaning the authentication app doesn't do the encryption or decryption explicitly."),(0,s.kt)("p",null,"The concatenation of parts of the 3DH exchange is strictly ordered:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"DH of the Long term identity of the outbound connection by the ephemeral key of the inbound connection."),(0,s.kt)("li",{parentName:"ul"},"DH of the Long term identity of the inbound connection by the ephemeral key of the outbound connection."),(0,s.kt)("li",{parentName:"ul"},"DH of the two ephemeral identities of the inbound and outbound connections.")),(0,s.kt)("p",null,"This strict ordering ensures both sides of the connection derive the ",(0,s.kt)("em",{parentName:"p"},"same")," session key."),(0,s.kt)("h3",{id:"cryptographic-properties"},"Cryptographic Properties"),(0,s.kt)("p",null,"During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come from their peer (or at least, someone with possession of their peers secret key as it related to their onion address)."),(0,s.kt)("p",null,"Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and all encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant repudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied that a single message in the transcript must have originated from a peer, there is no way of linking any other message to the session."),(0,s.kt)("p",null,"Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the session key is made public it can be used to forge new messages in the transcript - and as such, any standalone transcript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation."))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c4f5d8e4.ea3b76f3.js b/build-staging/es/assets/js/c4f5d8e4.ea3b76f3.js new file mode 100644 index 00000000..a46a88c5 --- /dev/null +++ b/build-staging/es/assets/js/c4f5d8e4.ea3b76f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4195],{3261:(e,t,n)=>{n.r(t),n.d(t,{default:()=>m});var a=n(7294),l=n(6010),r=n(7961),o=n(9960),s=n(2263);const c={heroBanner:"heroBanner_qdFl",buttons:"buttons_AeoN",button:"button_JGCe"};var i=n(5999);const u=[{id:1,title:a.createElement(i.Z,null,"The Cwtch Handbook")},{id:2,title:a.createElement(i.Z,null,"Your Guide to setting up, and using, Surveillance Resistant Infrastructure")},{id:3,title:a.createElement(i.Z,null,"Get Started With Cwtch")}];function h(){const{siteConfig:e}=(0,s.Z)();return a.createElement("header",{className:(0,l.Z)("hero hero--primary",c.heroBanner)},a.createElement("div",{className:"container"},a.createElement("h1",{className:"hero__title"},u[0].title),a.createElement("p",{className:"hero__subtitle"},u[1].title),a.createElement("div",{className:c.buttons},a.createElement(o.Z,{className:"button button--secondary button--lg",to:"/docs/intro"},u[2].title))))}function m(){const{siteConfig:e}=(0,s.Z)();return a.createElement(r.Z,{title:`${e.title}`,description:"The Cwtch Handbook"},a.createElement(h,null),a.createElement("main",null))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c521ebb9.aec6b83a.js b/build-staging/es/assets/js/c521ebb9.aec6b83a.js new file mode 100644 index 00000000..3263b9f7 --- /dev/null +++ b/build-staging/es/assets/js/c521ebb9.aec6b83a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1084],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>y});var i=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,i,o=function(e,t){if(null==e)return{};var n,i,o={},r=Object.keys(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=i.createContext({}),l=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return i.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),h=o,y=u["".concat(s,".").concat(h)]||u[h]||m[h]||r;return n?i.createElement(y,a(a({ref:t},p),{},{components:n})):i.createElement(y,a({ref:t},p))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,a=new Array(r);a[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l<r;l++)a[l]=n[l];return i.createElement.apply(null,a)}return i.createElement.apply(null,n)}h.displayName="MDXCreateElement"},2575:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=n(7462),o=(n(7294),n(3905));const r={sidebar_position:1.5},a="Component Ecosystem Overview",c={unversionedId:"components/ecosystem-overview",id:"components/ecosystem-overview",title:"Component Ecosystem Overview",description:"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ecosystem-overview.md",sourceDirName:"components",slug:"/components/ecosystem-overview",permalink:"/es/security/components/ecosystem-overview",draft:!1,tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Cwtch Technical Basics",permalink:"/es/security/components/intro"},next:{title:"Connectivity & Tor",permalink:"/es/security/category/connectivity--tor"}},s={},l=[{value:"openprivacy/connectivity",id:"openprivacyconnectivity",level:2},{value:"cwtch.im/tapir",id:"cwtchimtapir",level:2},{value:"cwtch.im/cwtch",id:"cwtchimcwtch",level:2},{value:"cwtch.im/libcwtch-go",id:"cwtchimlibcwtch-go",level:2},{value:"cwtch-ui",id:"cwtch-ui",level:2},{value:"Auxiliary Components",id:"auxiliary-components",level:2},{value:"openprivacy/log",id:"openprivacylog",level:3}],p={toc:l},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"component-ecosystem-overview"},"Component Ecosystem Overview"),(0,o.kt)("p",null,"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem."),(0,o.kt)("h2",{id:"openprivacyconnectivity"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity")),(0,o.kt)("p",null,"Summary: A library providing an ACN (Anonymous Communication Network ) networking abstraction."),(0,o.kt)("p",null,"The goal of connectivity is to abstract away the underlying libraries/software needed to communicate with a specific ACN. Right now we only support Tor and so the job of connectivity is to:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Start and Stop the Tor Process"),(0,o.kt)("li",{parentName:"ul"},"Provide configuration to the Tor process"),(0,o.kt)("li",{parentName:"ul"},"Allow raw connections to endpoints via the Tor process (e.g. connect to onion services)"),(0,o.kt)("li",{parentName:"ul"},"Host endpoints via the Tor process (e.g. host onion services)"),(0,o.kt)("li",{parentName:"ul"},"Provide status updates about the underlying Tor process")),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/connectivity/intro"},"connectivity")),(0,o.kt)("h2",{id:"cwtchimtapir"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/tapir"},"cwtch.im/tapir")),(0,o.kt)("p",null,"Summary: Tapir is a small library for building p2p applications over anonymous communication systems."),(0,o.kt)("p",null,"The goal of tapir is to abstract away ",(0,o.kt)("strong",{parentName:"p"},"applications")," over a particular ACN. Tapir supports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Creating a cryptographic identity (including ephemeral identities)"),(0,o.kt)("li",{parentName:"ul"},"Maintaining a connection pool of inbound and outbound connections to services"),(0,o.kt)("li",{parentName:"ul"},"Handling various application-layers including cryptographic transcripts, ",(0,o.kt)("a",{parentName:"li",href:"/security/components/tapir/authentication_protocol"},"authentication and authorization protocols"),", and ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"token-based services via PrivacyPass"),",")),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/tapir/authentication_protocol"},"tapir")),(0,o.kt)("h2",{id:"cwtchimcwtch"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"cwtch.im/cwtch")),(0,o.kt)("p",null,"Summary: Cwtch is the main library for implementing the Cwtch protocol / system."),(0,o.kt)("p",null,"The goal of Cwtch is to provide implementations for cwtch-specific applications e.g. message sending, groups, and file sharing(implemented as Tapir applications), provide interfaces for managing and storing Cwtch profiles, provide an event bus for subsystem splutting and building plugins with new functionality, in addition to managing other core functionality."),(0,o.kt)("p",null,"The Cwtch library is also responsible for maintaining canonical model representations for wire formats and overlays."),(0,o.kt)("h2",{id:"cwtchimlibcwtch-go"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"cwtch.im/libcwtch-go")),(0,o.kt)("p",null,"Summary: libcwtch-go provides C (including Android) bindings for Cwtch for use in UI implementations."),(0,o.kt)("p",null,"The goal of libcwtch-go is to bridge the gap between the backend Cwtch library and any front end systems which may be written in a different language."),(0,o.kt)("p",null,"The API provided by libcwtch is much more restricted than the one provided by Cwtch directly, each libcwtch API typically packages up several calls to Cwtch."),(0,o.kt)("p",null,"libcwtch-go is also responsible for managing UI settings and experimental gating. It is also often used as a staging ground for experimental features and code that may eventually end up in Cwtch."),(0,o.kt)("h2",{id:"cwtch-ui"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui"},"cwtch-ui")),(0,o.kt)("p",null,"Summary: A flutter based UI for Cwtch."),(0,o.kt)("p",null,"Cwtch UI uses libcwtch-go to provide a complete UI for Cwtch, allowing people to create and manage profiles, add contacts and groups, message people, share files (coming soon) and more."),(0,o.kt)("p",null,"The UI is also responsible for managing localization and translations."),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"Cwtch UI")),(0,o.kt)("h2",{id:"auxiliary-components"},"Auxiliary Components"),(0,o.kt)("p",null,"Occasionally, Open Privacy will factor out parts of Cwtch into standalone libraries that are not Cwtch specific. These are briefly summarized here:"),(0,o.kt)("h3",{id:"openprivacylog"},(0,o.kt)("a",{parentName:"h3",href:"https://git.openprivacy.ca/openprivacy/log"},"openprivacy/log")),(0,o.kt)("p",null,"An Open Privacy specific logging framework that is used throughout Cwtch packages."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c567d895.92b6bd3f.js b/build-staging/es/assets/js/c567d895.92b6bd3f.js new file mode 100644 index 00000000..5cd0212d --- /dev/null +++ b/build-staging/es/assets/js/c567d895.92b6bd3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5986],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},i=Object.keys(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=o.createContext({}),c=function(e){var t=o.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(r),h=n,d=u["".concat(l,".").concat(h)]||u[h]||m[h]||i;return r?o.createElement(d,s(s({ref:t},p),{},{components:r})):o.createElement(d,s({ref:t},p))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,s=new Array(i);s[0]=h;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:n,s[1]=a;for(var c=2;c<i;c++)s[c]=r[c];return o.createElement.apply(null,s)}return o.createElement.apply(null,r)}h.displayName="MDXCreateElement"},8082:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var o=r(7462),n=(r(7294),r(3905));const i={sidebar_position:4},s="Groups",a={unversionedId:"components/cwtch/groups",id:"components/cwtch/groups",title:"Groups",description:"For the most part the Cwtch risk model for groups is split into two distinct profiles:",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/groups.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/groups",permalink:"/es/security/components/cwtch/groups",draft:!1,tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Key Bundles",permalink:"/es/security/components/cwtch/key_bundles"},next:{title:"Cwtch Server",permalink:"/es/security/components/cwtch/server"}},l={},c=[{value:"Risk Overview: Key Derivation",id:"risk-overview-key-derivation",level:2},{value:"Risk: Malicious Peer Leaks Group Key and/or Conversation",id:"risk-malicious-peer-leaks-group-key-andor-conversation",level:2},{value:"Risk: Active Attacks by Group Members",id:"risk-active-attacks-by-group-members",level:2},{value:"Mitigations:",id:"mitigations",level:3}],p={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,n.kt)(u,(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"groups"},"Groups"),(0,n.kt)("p",null,"For the most part the Cwtch risk model for groups is split into two distinct profiles:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Groups made up of mutually trusted participants where peers are assumed honest."),(0,n.kt)("li",{parentName:"ul"},"Groups consisting of strangers where peers are assumed to be potentially malicious.")),(0,n.kt)("p",null,"Most of the mitigations described in this section relate to the latter case, but naturally also impact the former. Even if assumed honest peers later turn malicious there are mechanisms that can detect such malice and prevent it from happening in the future."),(0,n.kt)("h2",{id:"risk-overview-key-derivation"},"Risk Overview: Key Derivation"),(0,n.kt)("p",null,"In the ideal case we would use a protocol like OTR, the limitations preventing us from doing so right now are:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Offline messages are not guaranteed to reach all peers, and as such any metadata relating to key material might get lost. We need a key derivation process which is robust to missing messages or incomplete broadcast.")),(0,n.kt)("h2",{id:"risk-malicious-peer-leaks-group-key-andor-conversation"},"Risk: Malicious Peer Leaks Group Key and/or Conversation"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Status: Partially Mitigated (but impossible to mitigate fully)")),(0,n.kt)("p",null,"Whether dealing with trusted smaller groups or partially-public larger groups there is ",(0,n.kt)("em",{parentName:"p"},"always")," the possibility that a malicious actor will leak group messages."),(0,n.kt)("p",null,"We plan to make it easy for peers to ",(0,n.kt)("a",{parentName:"p",href:"#fork"},"fork")," groups to mitigate the same key being used to encrypt lots of sensitive information and provide some level of forward secrecy for past group conversations."),(0,n.kt)("h2",{id:"risk-active-attacks-by-group-members"},"Risk: Active Attacks by Group Members"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")),(0,n.kt)("p",null,"Group members, who have access to the key material of the group, can conspire with a server or other group members to break transcript consistency."),(0,n.kt)("p",null,"While we cannot directly prevent censorship given this kind of active collusion, we have a number of mechanisms in place that should reveal the presence of censorship to honest members of the group."),(0,n.kt)("h3",{id:"mitigations"},"Mitigations:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Because each message is signed by the peers public key, it should not be possible (within the cryptographic assumptions of the underlying cryptography) for one group member to imitate another."),(0,n.kt)("li",{parentName:"ul"},"Each message contains a unique identifier derived from the contents and the previous message hash - making it impossible for collaborators to include messages from non-colluding members without revealing an implicit message chain (which if they were attempting to censor other messages would reveal such censorship)")),(0,n.kt)("p",null,"Finally: We are actively working on adding non-repudiation to Cwtch servers such that they themselves are restricted in what they can censor efficiently."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c5e058ac.ff52790d.js b/build-staging/es/assets/js/c5e058ac.ff52790d.js new file mode 100644 index 00000000..f1092416 --- /dev/null +++ b/build-staging/es/assets/js/c5e058ac.ff52790d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2017],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,f=u["".concat(c,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(f,o(o({ref:t},p),{},{components:r})):n.createElement(f,o({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l<i;l++)o[l]=r[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},1755:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const i={sidebar_position:4.5},o="Formato de mensajes",s={unversionedId:"chat/message-formatting",id:"chat/message-formatting",title:"Formato de mensajes",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/message-formatting.md",sourceDirName:"chat",slug:"/chat/message-formatting",permalink:"/es/docs/chat/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/message-formatting.md",tags:[],version:"current",sidebarPosition:4.5,frontMatter:{sidebar_position:4.5},sidebar:"tutorialSidebar",previous:{title:"Guardar el historial de conversaciones",permalink:"/es/docs/chat/save-conversation-history"},next:{title:"Accessing Conversation Settings",permalink:"/es/docs/chat/conversation-settings"}},c={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"formato-de-mensajes"},"Formato de mensajes"),(0,a.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/message-formatting"},"Experimento de Grupos")," activado."),(0,a.kt)("p",{parentName:"admonition"},"Opcionalmente, puedes habilitar ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/clickable-links"},"Enlaces Cliqueables")," para hacer URLs en mensajes cliqueables en Cwtch.")),(0,a.kt)("p",null,"Actualmente Cwtch soporta el siguiente marcado de formato para los mensajes:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"**negrita**")," que renderizar\xe1 ",(0,a.kt)("strong",{parentName:"li"},"negrita")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"*cursiva*")," que renderizar\xe1 ",(0,a.kt)("em",{parentName:"li"},"cursiva")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"c\xf3digo")," que renderizar\xe1 ",(0,a.kt)("inlineCode",{parentName:"li"},"c\xf3digo")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"^superscript^")," que renderizar\xe1 ",(0,a.kt)("sup",null,"super\xedndice")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"_subscript_")," que renderizar\xe1 ",(0,a.kt)("sub",null,"sub\xedndice")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"~~strikthroughh~~")," que renderizar\xe1 ",(0,a.kt)("del",null,"strikethrough"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c688cd93.780495d4.js b/build-staging/es/assets/js/c688cd93.780495d4.js new file mode 100644 index 00000000..162ed848 --- /dev/null +++ b/build-staging/es/assets/js/c688cd93.780495d4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7264],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),c=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=c(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(t),m=o,v=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=m;var s={};for(var l in r)hasOwnProperty.call(r,l)&&(s[l]=r[l]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var c=2;c<i;c++)a[c]=t[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},3042:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:4},a="C\xf3mo eliminar un servidor",s={unversionedId:"servers/delete-server",id:"servers/delete-server",title:"C\xf3mo eliminar un servidor",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/delete-server.md",sourceDirName:"servers",slug:"/servers/delete-server",permalink:"/es/docs/servers/delete-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/delete-server.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"C\xf3mo editar un servidor",permalink:"/es/docs/servers/edit-server"},next:{title:"C\xf3mo compartir tu Paquete de Claves del Servidor",permalink:"/es/docs/servers/share-key"}},l={},c=[],p={toc:c},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"c\xf3mo-eliminar-un-servidor"},"C\xf3mo eliminar un servidor"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Experimento de Grupos")," activado.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ve al icono del servidor"),(0,o.kt)("li",{parentName:"ol"},"Selecciona el servidor que quieres eliminar"),(0,o.kt)("li",{parentName:"ol"},"Pulsa el icono de l\xe1piz"),(0,o.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo e introduce tu contrase\xf1a"),(0,o.kt)("li",{parentName:"ol"},"Pulsa borrar"),(0,o.kt)("li",{parentName:"ol"},"Pulsar eliminar realmente"),(0,o.kt)("li",{parentName:"ol"},"Tu servidor ha sido eliminado")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Delete.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c747432f.6555923b.js b/build-staging/es/assets/js/c747432f.6555923b.js new file mode 100644 index 00000000..fe927f7d --- /dev/null +++ b/build-staging/es/assets/js/c747432f.6555923b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8835],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>u});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),s=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},m="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=s(n),d=a,u=m["".concat(c,".").concat(d)]||m[d]||g[d]||o;return n?i.createElement(u,r(r({ref:t},p),{},{components:n})):i.createElement(u,r({ref:t},p))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[m]="string"==typeof e?e:a,r[1]=l;for(var s=2;s<o;s++)r[s]=n[s];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}d.displayName="MDXCreateElement"},2090:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const o={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/es/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"3 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/es/blog/tags/bindings"},{label:"autobindings",permalink:"/es/blog/tags/autobindings"},{label:"libcwtch",permalink:"/es/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/es/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/es/blog/autobindings"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},m="wrapper";function g(e){let{components:t,...o}=e;return(0,a.kt)(m,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c94c4dfb.5e3bcaf2.js b/build-staging/es/assets/js/c94c4dfb.5e3bcaf2.js new file mode 100644 index 00000000..2d748b75 --- /dev/null +++ b/build-staging/es/assets/js/c94c4dfb.5e3bcaf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9146],{4469:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c953ad65.3094368f.js b/build-staging/es/assets/js/c953ad65.3094368f.js new file mode 100644 index 00000000..8fc0da51 --- /dev/null +++ b/build-staging/es/assets/js/c953ad65.3094368f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[413],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>d});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),m=i,d=u["".concat(c,".").concat(m)]||u[m]||f[m]||a;return r?n.createElement(d,o(o({ref:t},l),{},{components:r})):n.createElement(d,o({ref:t},l))}));function d(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,o[1]=s;for(var p=2;p<a;p++)o[p]=r[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1668:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),i=(r(7294),r(3905));const a={sidebar_position:4},o="Cambiar tu imagen de perfil",s={unversionedId:"profiles/change-profile-image",id:"profiles/change-profile-image",title:"Cambiar tu imagen de perfil",description:"Esta funci\xf3n requiere Experimentos habilitados y tanto Archivos Compartidos como Im\xe1genes previas de imagen y fotos activadas.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/change-profile-image.md",sourceDirName:"profiles",slug:"/profiles/change-profile-image",permalink:"/es/docs/profiles/change-profile-image",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-profile-image.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Cambiar tu contrase\xf1a",permalink:"/es/docs/profiles/change-password"},next:{title:"Desbloquear perfiles cifrados",permalink:"/es/docs/profiles/unlock-profile"}},c={},p=[],l={toc:p},u="wrapper";function f(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"cambiar-tu-imagen-de-perfil"},"Cambiar tu imagen de perfil"),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y tanto ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"Archivos Compartidos")," como ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Im\xe1genes previas de imagen y fotos")," activadas.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Pulsa el l\xe1piz junto al perfil que quieres editar"),(0,i.kt)("li",{parentName:"ol"},"Pulsa sobre el l\xe1piz rosa sobre tu foto de perfil"),(0,i.kt)("li",{parentName:"ol"},"Selecciona una imagen de tu dispositivo"),(0,i.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo y haz clic en guardar el perfil")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/c96c5262.c2f9d73d.js b/build-staging/es/assets/js/c96c5262.c2f9d73d.js new file mode 100644 index 00000000..f9214f4d --- /dev/null +++ b/build-staging/es/assets/js/c96c5262.c2f9d73d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3761],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=c(a),h=r,u=d["".concat(s,".").concat(h)]||d[h]||m[h]||i;return a?n.createElement(u,o(o({ref:t},p),{},{components:a})):n.createElement(u,o({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:r,o[1]=l;for(var c=2;c<i;c++)o[c]=a[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},5426:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/es/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"29 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"release",permalink:"/es/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/es/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/es/blog/cwtch-documentation"}},s={authorsImageUrls:[void 0]},c=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},d="wrapper";function m(e){let{components:t,...i}=e;return(0,r.kt)(d,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(5595).Z},(0,r.kt)("img",{src:a(9573).Z,width:"1341",height:"866"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.11")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Based on new Reproducible Cwtch Stable Autobuilds")," - this is the first release of cwtch based on ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings")," in addition to our new ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Two New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Slovak")," and ",(0,r.kt)("strong",{parentName:"li"},"Korean")))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"When preserving a message draft, quoted messages are now also saved"),(0,r.kt)("li",{parentName:"ul"},"Layout issues caused by pathological unicode are now prevented"),(0,r.kt)("li",{parentName:"ul"},"Improved performance of message row rendering"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Links in replies are now selectable"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Fixed error when highlighting certain URIs "),(0,r.kt)("li",{parentName:"ul"},"File Downloading: Fixes for file downloading and exporting on 32bit Android devices"),(0,r.kt)("li",{parentName:"ul"},"Server Hosting: Fixes for several layout issues"),(0,r.kt)("li",{parentName:"ul"},"Build pipeline now runs automated UI tests"),(0,r.kt)("li",{parentName:"ul"},"Fix issues caused by scrollbar controller overriding"),(0,r.kt)("li",{parentName:"ul"},"Initial support for the Blodeuwedd Assistant (currently compile-time disabled)"),(0,r.kt)("li",{parentName:"ul"},"Cwtch Library:",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"New Stable Cwtch Peer API")),(0,r.kt)("li",{parentName:"ul"},"Ported File Downloading and Image Previews experiments into Cwtch"))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.11 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"2023-03-16-15-07-v0.0.3-1-g50c853a"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}m.isMDXComponent=!0},5595:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},6094:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"},9573:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/cbbc0b0f.6e72d682.js b/build-staging/es/assets/js/cbbc0b0f.6e72d682.js new file mode 100644 index 00000000..d9e2f90c --- /dev/null +++ b/build-staging/es/assets/js/cbbc0b0f.6e72d682.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9334],{2445:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/developer-documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ccc49370.a9ca1f91.js b/build-staging/es/assets/js/ccc49370.a9ca1f91.js new file mode 100644 index 00000000..455c51ff --- /dev/null +++ b/build-staging/es/assets/js/ccc49370.a9ca1f91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6103],{5203:(e,t,n)=>{n.r(t),n.d(t,{default:()=>h});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),i=n(9460),c=n(9058),s=n(390),m=n(7462),d=n(5999),u=n(2244);function g(e){const{nextItem:t,prevItem:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,d.I)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"})},n&&a.createElement(u.Z,(0,m.Z)({},n,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post"},"Newer Post")})),t&&a.createElement(u.Z,(0,m.Z)({},t,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post"},"Older Post"),isNext:!0})))}function f(){const{assets:e,metadata:t}=(0,i.C)(),{title:n,description:l,date:r,tags:c,authors:s,frontMatter:m}=t,{keywords:d}=m,u=e.image??m.image;return a.createElement(o.d,{title:n,description:l,keywords:d,image:u},a.createElement("meta",{property:"og:type",content:"article"}),a.createElement("meta",{property:"article:published_time",content:r}),s.some((e=>e.url))&&a.createElement("meta",{property:"article:author",content:s.map((e=>e.url)).filter(Boolean).join(",")}),c.length>0&&a.createElement("meta",{property:"article:tag",content:c.map((e=>e.label)).join(",")}))}var v=n(9407);function p(e){let{sidebar:t,children:n}=e;const{metadata:l,toc:o}=(0,i.C)(),{nextItem:r,prevItem:m,frontMatter:d}=l,{hide_table_of_contents:u,toc_min_heading_level:f,toc_max_heading_level:p}=d;return a.createElement(c.Z,{sidebar:t,toc:!u&&o.length>0?a.createElement(v.Z,{toc:o,minHeadingLevel:f,maxHeadingLevel:p}):void 0},a.createElement(s.Z,null,n),(r||m)&&a.createElement(g,{nextItem:r,prevItem:m}))}function h(e){const t=e.content;return a.createElement(i.n,{content:e.content,isBlogPostPage:!0},a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.blogPages,r.k.page.blogPostPage)},a.createElement(f,null),a.createElement(p,{sidebar:e.sidebar},a.createElement(t,null))))}},9407:(e,t,n)=>{n.d(t,{Z:()=>m});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",s="table-of-contents__link--active";function m(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(i.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:s})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>f});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function s(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(c(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function m(){const e=(0,l.useRef)(0),{navbar:{hideOnScroll:t}}=(0,o.L)();return(0,l.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,l.useRef)(void 0),n=m();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function i(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),i=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=s(i,{anchorTopOffset:n.current}),m=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===m)}))}return document.addEventListener("scroll",i),document.addEventListener("resize",i),i(),()=>{document.removeEventListener("scroll",i),document.removeEventListener("resize",i)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const g=l.memo(u);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:s,minHeadingLevel:m,maxHeadingLevel:u,...f}=e;const v=(0,o.L)(),p=m??v.tableOfContents.minHeadingLevel,h=u??v.tableOfContents.maxHeadingLevel,b=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:p,maxHeadingLevel:h});return d((0,l.useMemo)((()=>{if(c&&s)return{linkClassName:c,linkActiveClassName:s,minHeadingLevel:p,maxHeadingLevel:h}}),[c,s,p,h])),l.createElement(g,(0,a.Z)({toc:b,className:n,linkClassName:c},f))}}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/cdd10d0d.46a676f4.js b/build-staging/es/assets/js/cdd10d0d.46a676f4.js new file mode 100644 index 00000000..d819f297 --- /dev/null +++ b/build-staging/es/assets/js/cdd10d0d.46a676f4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2182],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),l=u(r),m=o,f=l["".concat(p,".").concat(m)]||l[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},s),{},{components:r})):n.createElement(f,i({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[l]="string"==typeof e?e:o,i[1]=c;for(var u=2;u<a;u++)i[u]=r[u];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},2865:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>u});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:3},i="Crea un grupo nuevo",c={unversionedId:"groups/create-group",id:"groups/create-group",title:"Crea un grupo nuevo",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/create-group.md",sourceDirName:"groups",slug:"/groups/create-group",permalink:"/es/docs/groups/create-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/create-group.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Una Introducci\xf3n a los Grupos de Cwtch",permalink:"/es/docs/groups/introduction"},next:{title:"Enviar invitaciones a un Grupo",permalink:"/es/docs/groups/send-invite"}},p={},u=[],s={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"crea-un-grupo-nuevo"},"Crea un grupo nuevo"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"En el panel de contactos"),(0,o.kt)("li",{parentName:"ol"},"Pulse en el bot\xf3n de acci\xf3n +"),(0,o.kt)("li",{parentName:"ol"},"Pulsa en Crear Grupo"),(0,o.kt)("li",{parentName:"ol"},"Nombra tu grupo"),(0,o.kt)("li",{parentName:"ol"},"Pulsa en Crear Grupo")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Create.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ce68aa0f.f44e6112.js b/build-staging/es/assets/js/ce68aa0f.f44e6112.js new file mode 100644 index 00000000..11328d57 --- /dev/null +++ b/build-staging/es/assets/js/ce68aa0f.f44e6112.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9793],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>g});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?a(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function p(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)t=a[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)t=a[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=n.createContext({}),u=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},c=function(e){var r=u(e.components);return n.createElement(s.Provider,{value:r},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),l=u(t),m=o,g=l["".concat(s,".").concat(m)]||l[m]||d[m]||a;return t?n.createElement(g,i(i({ref:r},c),{},{components:t})):n.createElement(g,i({ref:r},c))}));function g(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=m;var p={};for(var s in r)hasOwnProperty.call(r,s)&&(p[s]=r[s]);p.originalType=e,p[l]="string"==typeof e?e:o,i[1]=p;for(var u=2;u<a;u++)i[u]=t[u];return n.createElement.apply(null,i)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},9481:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>u});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:7},i="Editar Nombre de un Grupo",p={unversionedId:"groups/edit-group-name",id:"groups/edit-group-name",title:"Editar Nombre de un Grupo",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/edit-group-name.md",sourceDirName:"groups",slug:"/groups/edit-group-name",permalink:"/es/docs/groups/edit-group-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/edit-group-name.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"C\xf3mo abandonar un grupo",permalink:"/es/docs/groups/leave-group"},next:{title:"Administrar servidores",permalink:"/es/docs/groups/manage-known-servers"}},s={},u=[],c={toc:u},l="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(l,(0,n.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"editar-nombre-de-un-grupo"},"Editar Nombre de un Grupo"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,o.kt)("p",null,"Los nombres de grupo son privados para ti, no ser\xe1n compartidos, es tu nombre local para el grupo."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"En el panel de chat ir a la configuraci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Cambia el nombre del grupo"),(0,o.kt)("li",{parentName:"ol"},"Pulsa el bot\xf3n guardar"),(0,o.kt)("li",{parentName:"ol"},"Ahora tu grupo tiene un nuevo nombre")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/group_edit.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/cf7ec223.3b65b550.js b/build-staging/es/assets/js/cf7ec223.3b65b550.js new file mode 100644 index 00000000..dfac5771 --- /dev/null +++ b/build-staging/es/assets/js/cf7ec223.3b65b550.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8566],{8145:e=>{e.exports=JSON.parse('{"title":"Cwtch","slug":"/category/cwtch","permalink":"/es/security/category/cwtch","navigation":{"previous":{"title":"Authentication Protocol","permalink":"/es/security/components/tapir/authentication_protocol"},"next":{"title":"Message Formats","permalink":"/es/security/components/cwtch/message_formats"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d3029be3.03b2d6c0.js b/build-staging/es/assets/js/d3029be3.03b2d6c0.js new file mode 100644 index 00000000..c1bfcf40 --- /dev/null +++ b/build-staging/es/assets/js/d3029be3.03b2d6c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6520],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>y});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(r),m=i,y=p["".concat(l,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(y,a(a({ref:t},u),{},{components:r})):n.createElement(y,a({ref:t},u))}));function y(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:i,a[1]=s;for(var c=2;c<o;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},9837:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={},a="Deployment",s={unversionedId:"deployment",id:"deployment",title:"Deployment",description:"Risk: Binaries are replaced on the website with malicious ones",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/deployment.md",sourceDirName:".",slug:"/deployment",permalink:"/es/security/deployment",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Message Overlays",permalink:"/es/security/components/ui/overlays"},next:{title:"Development",permalink:"/es/security/development"}},l={},c=[{value:"Risk: Binaries are replaced on the website with malicious ones",id:"risk-binaries-are-replaced-on-the-website-with-malicious-ones",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deployment"},"Deployment"),(0,i.kt)("h2",{id:"risk-binaries-are-replaced-on-the-website-with-malicious-ones"},"Risk: Binaries are replaced on the website with malicious ones"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Partially-mitigated")),(0,i.kt)("p",null,"While this process is now mostly automated, should this automation ever be compromised then there is nothing in our current process that would detect this."),(0,i.kt)("p",null,"We need:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Reproducible Builds - we currently use public docker containers for all builds which should allow anyone to compare distributed builds with ones built from source."),(0,i.kt)("li",{parentName:"ul"},"Signed Releases - Open Privacy does not yet maintain a public record of staff public keys. This is likely a necessity for signing released builds and creating an audit chain backed by the organization. This process must be manual by definition.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d5055ac4.95953496.js b/build-staging/es/assets/js/d5055ac4.95953496.js new file mode 100644 index 00000000..f7f474b8 --- /dev/null +++ b/build-staging/es/assets/js/d5055ac4.95953496.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8609],{3429:s=>{s.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/es/blog/tags/cwtch-stable","allTagsPath":"/es/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d5f314f9.1dc05f26.js b/build-staging/es/assets/js/d5f314f9.1dc05f26.js new file mode 100644 index 00000000..02f13a12 --- /dev/null +++ b/build-staging/es/assets/js/d5f314f9.1dc05f26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5869],{9317:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-developer"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d6981a76.e0b288aa.js b/build-staging/es/assets/js/d6981a76.e0b288aa.js new file mode 100644 index 00000000..19921fd9 --- /dev/null +++ b/build-staging/es/assets/js/d6981a76.e0b288aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5761],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),s=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=s(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:o,i[1]=p;for(var s=2;s<a;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8400:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:6},i="C\xf3mo abandonar un grupo",p={unversionedId:"groups/leave-group",id:"groups/leave-group",title:"C\xf3mo abandonar un grupo",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/leave-group.md",sourceDirName:"groups",slug:"/groups/leave-group",permalink:"/es/docs/groups/leave-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/leave-group.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Aceptar una invitaci\xf3n de grupo",permalink:"/es/docs/groups/accept-group-invite"},next:{title:"Editar Nombre de un Grupo",permalink:"/es/docs/groups/edit-group-name"}},c={},s=[],u={toc:s},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"c\xf3mo-abandonar-un-grupo"},"C\xf3mo abandonar un grupo"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,o.kt)("p",null,":::advertencia"),(0,o.kt)("p",null,"Esta funci\xf3n resultar\xe1 en la eliminaci\xf3n ",(0,o.kt)("strong",{parentName:"p"},"irreversible")," de material clave. Esto ",(0,o.kt)("strong",{parentName:"p"},"no se puede deshacer"),"."),(0,o.kt)("p",null,":::"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"En el panel de chat ir a la configuraci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo en el panel de ajustes"),(0,o.kt)("li",{parentName:"ol"},"Pulsa abandonar la conversaci\xf3n"),(0,o.kt)("li",{parentName:"ol"},"Confirma que quieres salir")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Leave.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d6f4db7a.1b6b2690.js b/build-staging/es/assets/js/d6f4db7a.1b6b2690.js new file mode 100644 index 00000000..c5c0b8ef --- /dev/null +++ b/build-staging/es/assets/js/d6f4db7a.1b6b2690.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5401],{1765:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/nightly","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d7127c3b.2158e7fc.js b/build-staging/es/assets/js/d7127c3b.2158e7fc.js new file mode 100644 index 00000000..c15ee3e3 --- /dev/null +++ b/build-staging/es/assets/js/d7127c3b.2158e7fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9958],{4839:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/support","page":1,"postsPerPage":10,"totalPages":1,"totalCount":3,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d7b9dd5a.939a5305.js b/build-staging/es/assets/js/d7b9dd5a.939a5305.js new file mode 100644 index 00000000..e2b14f9e --- /dev/null +++ b/build-staging/es/assets/js/d7b9dd5a.939a5305.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[799],{7884:s=>{s.exports=JSON.parse('{"label":"cwtch","permalink":"/es/blog/tags/cwtch","allTagsPath":"/es/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/d7c28e69.1cda3189.js b/build-staging/es/assets/js/d7c28e69.1cda3189.js new file mode 100644 index 00000000..1b178c06 --- /dev/null +++ b/build-staging/es/assets/js/d7c28e69.1cda3189.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1601],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=o,v=d["".concat(c,".").concat(m)]||d[m]||u[m]||i;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[d]="string"==typeof e?e:o,a[1]=s;for(var l=2;l<i;l++)a[l]=t[l];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},6560:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:3},a="C\xf3mo editar un servidor",s={unversionedId:"servers/edit-server",id:"servers/edit-server",title:"C\xf3mo editar un servidor",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/edit-server.md",sourceDirName:"servers",slug:"/servers/edit-server",permalink:"/es/docs/servers/edit-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/edit-server.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"C\xf3mo crear un servidor",permalink:"/es/docs/servers/create-server"},next:{title:"C\xf3mo eliminar un servidor",permalink:"/es/docs/servers/delete-server"}},c={},l=[],p={toc:l},d="wrapper";function u(e){let{components:r,...t}=e;return(0,o.kt)(d,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"c\xf3mo-editar-un-servidor"},"C\xf3mo editar un servidor"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Experimento de Grupos")," activado.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ve al icono del servidor"),(0,o.kt)("li",{parentName:"ol"},"Selecciona el servidor que quieres editar"),(0,o.kt)("li",{parentName:"ol"},"Pulsa el icono de l\xe1piz"),(0,o.kt)("li",{parentName:"ol"},"Cambia la descripci\xf3n/ o activa o desactiva el servidor"),(0,o.kt)("li",{parentName:"ol"},"Haz clic en guardar el servidor")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/server_edit.mp4"}))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/da0de98b.5e492249.js b/build-staging/es/assets/js/da0de98b.5e492249.js new file mode 100644 index 00000000..2ae85ef2 --- /dev/null +++ b/build-staging/es/assets/js/da0de98b.5e492249.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6774],{8514:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/testing","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/daa83a73.e70fcb06.js b/build-staging/es/assets/js/daa83a73.e70fcb06.js new file mode 100644 index 00000000..3e7b1867 --- /dev/null +++ b/build-staging/es/assets/js/daa83a73.e70fcb06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5532],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>b});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(r),f=i,b=p["".concat(s,".").concat(f)]||p[f]||d[f]||o;return r?n.createElement(b,a(a({ref:t},l),{},{components:r})):n.createElement(b,a({ref:t},l))}));function b(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:i,a[1]=c;for(var u=2;u<o;u++)a[u]=r[u];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},8177:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:10},a="Stickers",c={unversionedId:"contribute/stickers",id:"contribute/stickers",title:"Stickers",description:"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email erinn@openprivacy.ca with details and an address for us to mail stickers to.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/stickers.md",sourceDirName:"contribute",slug:"/contribute/stickers",permalink:"/es/docs/contribute/stickers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/stickers.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Documentation Style Guide",permalink:"/es/docs/contribute/documentation"},next:{title:"Platforms",permalink:"/es/docs/category/platforms"}},s={},u=[],l={toc:u},p="wrapper";function d(e){let{components:t,...o}=e;return(0,i.kt)(p,(0,n.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"stickers"},"Stickers"),(0,i.kt)("p",null,"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email ",(0,i.kt)("a",{parentName:"p",href:"mailto:erinn@openprivacy.ca"},"erinn@openprivacy.ca")," with details and an address for us to mail stickers to."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:r(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},4515:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/dbc23903.2a3fcb44.js b/build-staging/es/assets/js/dbc23903.2a3fcb44.js new file mode 100644 index 00000000..30c75a2a --- /dev/null +++ b/build-staging/es/assets/js/dbc23903.2a3fcb44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[411],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function p(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=n.createContext({}),c=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},s=function(e){var r=c(e.components);return n.createElement(l.Provider,{value:r},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),f=c(t),d=o,m=f["".concat(l,".").concat(d)]||f[d]||u[d]||i;return t?n.createElement(m,a(a({ref:r},s),{},{components:t})):n.createElement(m,a({ref:r},s))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=d;var p={};for(var l in r)hasOwnProperty.call(r,l)&&(p[l]=r[l]);p.originalType=e,p[f]="string"==typeof e?e:o,a[1]=p;for(var c=2;c<i;c++)a[c]=t[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},1593:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:10},a="Copia de seguridad o Exportaci\xf3n de un perfil",p={unversionedId:"profiles/exporting-profile",id:"profiles/exporting-profile",title:"Copia de seguridad o Exportaci\xf3n de un perfil",description:"En la pantalla de administraci\xf3n de perfiles:",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/exporting-profile.md",sourceDirName:"profiles",slug:"/profiles/exporting-profile",permalink:"/es/docs/profiles/exporting-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/exporting-profile.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Eliminar un perfil",permalink:"/es/docs/profiles/delete-profile"},next:{title:"Importar un perfil",permalink:"/es/docs/profiles/importing-a-profile"}},l={},c=[],s={toc:c},f="wrapper";function u(e){let{components:r,...t}=e;return(0,o.kt)(f,(0,n.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"copia-de-seguridad-o-exportaci\xf3n-de-un-perfil"},"Copia de seguridad o Exportaci\xf3n de un perfil"),(0,o.kt)("p",null,"En la pantalla de administraci\xf3n de perfiles:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Pulsa el l\xe1piz junto al perfil que quieres editar"),(0,o.kt)("li",{parentName:"ol"},"Despl\xe1zate hacia abajo hasta la parte inferior de la pantalla"),(0,o.kt)("li",{parentName:"ol"},'Selecciona "Exportar perfil"'),(0,o.kt)("li",{parentName:"ol"},"Elige una ubicaci\xf3n y un nombre de archivo"),(0,o.kt)("li",{parentName:"ol"},"Confirma")),(0,o.kt)("p",null,"Una vez confirmado, Cwtch har\xe1 una copia del perfil en la ubicaci\xf3n dada. Este archivo est\xe1 cifrado al mismo nivel que el perfil. Consulta ",(0,o.kt)("a",{parentName:"p",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"Una nota sobre Perfiles protegidos con contrase\xf1a (cifrados)")," para obtener m\xe1s informaci\xf3n sobre perfiles cifrados."),(0,o.kt)("p",null,"Este archivo puede ser ",(0,o.kt)("a",{parentName:"p",href:"/docs/profiles/importing-a-profile"},"importado")," en otra instancia de Cwtch en cualquier dispositivo."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/dbda29f5.f937dc7d.js b/build-staging/es/assets/js/dbda29f5.f937dc7d.js new file mode 100644 index 00000000..ddf7df95 --- /dev/null +++ b/build-staging/es/assets/js/dbda29f5.f937dc7d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1434],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>d});var a=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function r(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function s(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?r(Object(n),!0).forEach((function(e){i(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function o(t,e){if(null==t)return{};var n,a,i=function(t,e){if(null==t)return{};var n,a,i={},r=Object.keys(t);for(a=0;a<r.length;a++)n=r[a],e.indexOf(n)>=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(a=0;a<r.length;a++)n=r[a],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var l=a.createContext({}),c=function(t){var e=a.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):s(s({},e),t)),n},p=function(t){var e=c(t.components);return a.createElement(l.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},b=a.forwardRef((function(t,e){var n=t.components,i=t.mdxType,r=t.originalType,l=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),u=c(n),b=i,d=u["".concat(l,".").concat(b)]||u[b]||f[b]||r;return n?a.createElement(d,s(s({ref:e},p),{},{components:n})):a.createElement(d,s({ref:e},p))}));function d(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var r=n.length,s=new Array(r);s[0]=b;var o={};for(var l in e)hasOwnProperty.call(e,l)&&(o[l]=e[l]);o.originalType=t,o[u]="string"==typeof t?t:i,s[1]=o;for(var c=2;c<r;c++)s[c]=n[c];return a.createElement.apply(null,s)}return a.createElement.apply(null,n)}b.displayName="MDXCreateElement"},9102:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>s,default:()=>f,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var a=n(7462),i=(n(7294),n(3905));const r={sidebar_position:14},s="Setting Availability Status",o={unversionedId:"profiles/availability-status",id:"profiles/availability-status",title:"Setting Availability Status",description:"This functionality is currently only available in the Nightly Release builds of Cwtch.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/availability-status.md",sourceDirName:"profiles",slug:"/profiles/availability-status",permalink:"/es/docs/profiles/availability-status",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/availability-status.md",tags:[],version:"current",sidebarPosition:14,frontMatter:{sidebar_position:14},sidebar:"tutorialSidebar",previous:{title:"Importar un perfil",permalink:"/es/docs/profiles/importing-a-profile"},next:{title:"Setting Profile Attributes",permalink:"/es/docs/profiles/profile-info"}},l={},c=[],p={toc:c},u="wrapper";function f(t){let{components:e,...r}=t;return(0,i.kt)(u,(0,a.Z)({},p,r,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-availability-status"},"Setting Availability Status"),(0,i.kt)("admonition",{title:"Nightly Feature",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This functionality is currently ",(0,i.kt)("strong",{parentName:"p"},"only")," available in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly Release")," builds of Cwtch."),(0,i.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,i.kt)("p",null,"On the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/category/conversations"},"conversations pane")," click the Status icon next to your profile picture."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(1476).Z},(0,i.kt)("img",{src:n(3163).Z,width:"444",height:"252"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"A drop-down menu will appear with various options e.g. Available, Away, and Busy"),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(8791).Z},(0,i.kt)("img",{src:n(3891).Z,width:"443",height:"242"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"When you select Away or Busy as a status the border of your profile picture will change to reflect the status"),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(4940).Z},(0,i.kt)("img",{src:n(1859).Z,width:"442",height:"233"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Contacts will see this change reflected in their conversations pane."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(8868).Z},(0,i.kt)("img",{src:n(6792).Z,width:"443",height:"223"}))),(0,i.kt)("figcaption",null)))}f.isMDXComponent=!0},8868:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},4940:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},8791:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},1476:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"},6792:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},1859:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3891:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},3163:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/dc4e6075.f26fb504.js b/build-staging/es/assets/js/dc4e6075.f26fb504.js new file mode 100644 index 00000000..64dc1425 --- /dev/null +++ b/build-staging/es/assets/js/dc4e6075.f26fb504.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2023],{9818:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/de3e8d19.f15dbe35.js b/build-staging/es/assets/js/de3e8d19.f15dbe35.js new file mode 100644 index 00000000..d8b5a3a4 --- /dev/null +++ b/build-staging/es/assets/js/de3e8d19.f15dbe35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3570],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},s=Object.keys(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,p=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=c(n),g=a,m=u["".concat(p,".").concat(g)]||u[g]||d[g]||s;return n?r.createElement(m,o(o({ref:t},l),{},{components:n})):r.createElement(m,o({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=g;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[u]="string"==typeof e?e:a,o[1]=i;for(var c=2;c<s;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}g.displayName="MDXCreateElement"},3229:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const s={sidebar_position:2},o="Message Formats",i={unversionedId:"components/cwtch/message_formats",id:"components/cwtch/message_formats",title:"Message Formats",description:"Peer to Peer Messages",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/message_formats.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/message_formats",permalink:"/es/security/components/cwtch/message_formats",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch",permalink:"/es/security/category/cwtch"},next:{title:"Key Bundles",permalink:"/es/security/components/cwtch/key_bundles"}},p={},c=[{value:"Peer to Peer Messages",id:"peer-to-peer-messages",level:2},{value:"Context Identifiers",id:"context-identifiers",level:3},{value:"Plaintext / Decrypted Group Messages",id:"plaintext--decrypted-group-messages",level:2},{value:"Encrypted Group Messages",id:"encrypted-group-messages",level:2}],l={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"message-formats"},"Message Formats"),(0,a.kt)("h2",{id:"peer-to-peer-messages"},"Peer to Peer Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"PeerMessage {\n ID string // A unique Message ID (primarily used for acknowledgments)\n Context string // A unique context identifier i.e. im.cwtch.chat\n Data []byte // The context-dependent serialized data packet.\n}\n")),(0,a.kt)("h3",{id:"context-identifiers"},"Context Identifiers"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.raw")," - Data contains a plain text chat message (see: ",(0,a.kt)("a",{parentName:"p",href:"/es/security/components/ui/overlays"},"overlays")," for more information)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.acknowledgement")," - Data is empty and ID references a previously sent message")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.getVal")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.retVal")," - Used for requesting / returning specific information about a peer. Data contains a serialized ",(0,a.kt)("inlineCode",{parentName:"p"},"peerGetVal")," structure and ",(0,a.kt)("inlineCode",{parentName:"p"},"peerRetVal")," respectively."),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre"}," peerGetVal struct {\n Scope string\n Path string\n }\n\n type peerRetVal struct {\n Val string // Serialized path-dependent value\n Exists bool\n }\n")))),(0,a.kt)("h2",{id:"plaintext--decrypted-group-messages"},"Plaintext / Decrypted Group Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'type DecryptedGroupMessage struct {\n Text string // plaintext of the message\n Onion string // The Cwtch address of the sender\n Timestamp uint64 // A user specified timestamp\n // NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages\n // We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.\n // respect particular group constitutions) can be built on top of group messages, but the underlying groups are\n // now agnostic to those models.\n SignedGroupID []byte \n PreviousMessageSig []byte // A reference to a previous message\n Padding []byte // random bytes of length = 1800 - len(Text)\n}\n')),(0,a.kt)("p",null,"DecryptedGroupMessage contains random padding to a fixed size that is equal to the length of all fixed length fields + 1800. This ensures that all encrypted group messages are equal length."),(0,a.kt)("h2",{id:"encrypted-group-messages"},"Encrypted Group Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server\ntype EncryptedGroupMessage struct {\n Ciphertext []byte\n Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key\n}\n")),(0,a.kt)("p",null,"Calculating the signature requires knowing the groupID of the message, the server the group is associated with and the decrypted group message (and thus, the Group Key). It is (ed25519) signed by the sender of the message, and can be verified using their public Cwtch address key."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e0693172.f99cafb0.js b/build-staging/es/assets/js/e0693172.f99cafb0.js new file mode 100644 index 00000000..a72355de --- /dev/null +++ b/build-staging/es/assets/js/e0693172.f99cafb0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2722],{1006:e=>{e.exports=JSON.parse('{"label":"reproducible-builds","permalink":"/es/blog/tags/reproducible-builds","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e20a62ae.f642dad7.js b/build-staging/es/assets/js/e20a62ae.f642dad7.js new file mode 100644 index 00000000..83027e98 --- /dev/null +++ b/build-staging/es/assets/js/e20a62ae.f642dad7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2815],{3905:(e,r,t)=>{t.d(r,{Zo:()=>l,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},l=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||i;return t?n.createElement(v,a(a({ref:r},l),{},{components:t})):n.createElement(v,a({ref:r},l))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p<i;p++)a[p]=t[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},8202:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:2},a="C\xf3mo crear un servidor",s={unversionedId:"servers/create-server",id:"servers/create-server",title:"C\xf3mo crear un servidor",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/create-server.md",sourceDirName:"servers",slug:"/servers/create-server",permalink:"/es/docs/servers/create-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/create-server.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Introducci\xf3n a Servidores",permalink:"/es/docs/servers/introduction"},next:{title:"C\xf3mo editar un servidor",permalink:"/es/docs/servers/edit-server"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},l,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"c\xf3mo-crear-un-servidor"},"C\xf3mo crear un servidor"),(0,o.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Experimento de Grupos")," activado.")),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Ve al icono del servidor"),(0,o.kt)("li",{parentName:"ol"},"Pulsa el bot\xf3n + para crear un nuevo servidor"),(0,o.kt)("li",{parentName:"ol"},"Elige un nombre para tu servidor"),(0,o.kt)("li",{parentName:"ol"},"Selecciona una contrase\xf1a para tu servidor"),(0,o.kt)("li",{parentName:"ol"},'Haz clic en "A\xf1adir servidor"')),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_New.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e2f5db39.9ecf00b5.js b/build-staging/es/assets/js/e2f5db39.9ecf00b5.js new file mode 100644 index 00000000..5df9119f --- /dev/null +++ b/build-staging/es/assets/js/e2f5db39.9ecf00b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6164],{732:e=>{e.exports=JSON.parse('{"title":"Cwtch Components","slug":"/category/cwtch-components","permalink":"/es/security/category/cwtch-components","navigation":{"previous":{"title":"Risk Model","permalink":"/es/security/risk"},"next":{"title":"Cwtch Technical Basics","permalink":"/es/security/components/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e48e682c.0cff7e1b.js b/build-staging/es/assets/js/e48e682c.0cff7e1b.js new file mode 100644 index 00000000..a5520a7d --- /dev/null +++ b/build-staging/es/assets/js/e48e682c.0cff7e1b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[322],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){a(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function c(e,r){if(null==e)return{};var t,n,a=function(e,r){if(null==e)return{};var t,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var s=n.createContext({}),l=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(s.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(t),d=a,m=u["".concat(s,".").concat(d)]||u[d]||f[d]||o;return t?n.createElement(m,i(i({ref:r},p),{},{components:t})):n.createElement(m,i({ref:r},p))}));function m(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var o=t.length,i=new Array(o);i[0]=d;var c={};for(var s in r)hasOwnProperty.call(r,s)&&(c[s]=r[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=t[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},8021:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=t(7462),a=(t(7294),t(3905));const o={sidebar_position:3},i="Cambiar tu contrase\xf1a",c={unversionedId:"profiles/change-password",id:"profiles/change-password",title:"Cambiar tu contrase\xf1a",description:"1. Pulsa el l\xe1piz junto al perfil que quieres editar",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/change-password.md",sourceDirName:"profiles",slug:"/profiles/change-password",permalink:"/es/docs/profiles/change-password",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-password.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Cambiar tu nombre para mostrar",permalink:"/es/docs/profiles/change-name"},next:{title:"Cambiar tu imagen de perfil",permalink:"/es/docs/profiles/change-profile-image"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:r,...t}=e;return(0,a.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"cambiar-tu-contrase\xf1a"},"Cambiar tu contrase\xf1a"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Pulsa el l\xe1piz junto al perfil que quieres editar"),(0,a.kt)("li",{parentName:"ol"},"Ve a la contrase\xf1a actual e introduce tu contrase\xf1a actual"),(0,a.kt)("li",{parentName:"ol"},"Ve a la nueva contrase\xf1a e introduce tu nueva contrase\xf1a"),(0,a.kt)("li",{parentName:"ol"},"Re introduce tu contrase\xf1a"),(0,a.kt)("li",{parentName:"ol"},"Haz clic en Guardar perfil")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e490445a.86813d8a.js b/build-staging/es/assets/js/e490445a.86813d8a.js new file mode 100644 index 00000000..8f001ee2 --- /dev/null +++ b/build-staging/es/assets/js/e490445a.86813d8a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9765],{1917:e=>{e.exports=JSON.parse('{"title":"Apariencia","slug":"/category/appearance","permalink":"/es/docs/category/appearance","navigation":{"previous":{"title":"Una Introducci\xf3n a la configuraci\xf3n de Cwtch","permalink":"/es/docs/settings/introduction"},"next":{"title":"Cambiar idioma","permalink":"/es/docs/settings/appearance/change-language"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e5c4909f.9242e056.js b/build-staging/es/assets/js/e5c4909f.9242e056.js new file mode 100644 index 00000000..1e851c77 --- /dev/null +++ b/build-staging/es/assets/js/e5c4909f.9242e056.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3077],{2046:a=>{a.exports=JSON.parse('{"label":"api","permalink":"/es/blog/tags/api","allTagsPath":"/es/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/e88d32a9.ff20b8ba.js b/build-staging/es/assets/js/e88d32a9.ff20b8ba.js new file mode 100644 index 00000000..e319e33e --- /dev/null +++ b/build-staging/es/assets/js/e88d32a9.ff20b8ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6585],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ea60411e.d7f9429e.js b/build-staging/es/assets/js/ea60411e.d7f9429e.js new file mode 100644 index 00000000..6e7ab714 --- /dev/null +++ b/build-staging/es/assets/js/ea60411e.d7f9429e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3405],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function a(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?a(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function l(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)t=a[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)t=a[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=n.createContext({}),c=function(e){var r=n.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=c(e.components);return n.createElement(s.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},f=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(t),f=o,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||a;return t?n.createElement(m,i(i({ref:r},p),{},{components:t})):n.createElement(m,i({ref:r},p))}));function m(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=f;var l={};for(var s in r)hasOwnProperty.call(r,s)&&(l[s]=r[s]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var c=2;c<a;c++)i[c]=t[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,t)}f.displayName="MDXCreateElement"},4528:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=t(7462),o=(t(7294),t(3905));const a={sidebar_position:1.5},i="Crear un nuevo perfil",l={unversionedId:"profiles/create-a-profile",id:"profiles/create-a-profile",title:"Crear un nuevo perfil",description:'1. Pulsa el bot\xf3n + en la esquina inferior derecha y selecciona "Nuevo perfil"',source:"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/create-a-profile.md",sourceDirName:"profiles",slug:"/profiles/create-a-profile",permalink:"/es/docs/profiles/create-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/create-a-profile.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Una Introducci\xf3n a los Perfiles de Cwtch",permalink:"/es/docs/profiles/introduction"},next:{title:"Cambiar tu nombre para mostrar",permalink:"/es/docs/profiles/change-name"}},s={},c=[{value:"Una nota sobre los perfiles protegidos por contrase\xf1a (cifrado)",id:"una-nota-sobre-los-perfiles-protegidos-por-contrase\xf1a-cifrado",level:2}],p={toc:c},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"crear-un-nuevo-perfil"},"Crear un nuevo perfil"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Pulsa el bot\xf3n ",(0,o.kt)("inlineCode",{parentName:"li"},"+"),' en la esquina inferior derecha y selecciona "Nuevo perfil"'),(0,o.kt)("li",{parentName:"ol"},"Elije un nombre para mostrar"),(0,o.kt)("li",{parentName:"ol"},"Selecciona si deseas proteger este perfil de forma local con cifrado fuerte:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Contrase\xf1a: tu cuenta est\xe1 protegida de otras personas que pueden usar este dispositivo"),(0,o.kt)("li",{parentName:"ul"},"Sin contrase\xf1a: cualquiera que tenga acceso a este dispositivo puede acceder a este perfil"))),(0,o.kt)("li",{parentName:"ol"},"Introduce tu contrase\xf1a y vuelve a introducirla"),(0,o.kt)("li",{parentName:"ol"},"Haz clic en a\xf1adir un nuevo perfil")),(0,o.kt)("h2",{id:"una-nota-sobre-los-perfiles-protegidos-por-contrase\xf1a-cifrado"},"Una nota sobre los perfiles protegidos por contrase\xf1a (cifrado)"),(0,o.kt)("p",null,"Los perfiles se almacenan localmente en el disco y se cifran usando una clave derivada de la contrase\xf1a conocida por el usuario (a trav\xe9s de pbkdf2)."),(0,o.kt)("p",null,"Note that, once encrypted and stored on disk, the only way to recover a profile is by rederiving the key from the password - as such it isn't possible to provide a full list of profiles a user might have access to until they enter a password."),(0,o.kt)("p",null,"Consultar: ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Manual de seguridad de Cwtch.: Encriptaci\xf3n del perfil & Almacenamiento")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ead134b2.400c7729.js b/build-staging/es/assets/js/ead134b2.400c7729.js new file mode 100644 index 00000000..87a9323a --- /dev/null +++ b/build-staging/es/assets/js/ead134b2.400c7729.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8002],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},s=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),u=p(n),f=a,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||o;return n?r.createElement(m,c(c({ref:t},s),{},{components:n})):r.createElement(m,c({ref:t},s))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,c=new Array(o);c[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:a,c[1]=i;for(var p=2;p<o;p++)c[p]=n[p];return r.createElement.apply(null,c)}return r.createElement.apply(null,n)}f.displayName="MDXCreateElement"},9651:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1.5},c="Starting a New Conversation",i={unversionedId:"chat/add-contact",id:"chat/add-contact",title:"Starting a New Conversation",description:"1. Selecciona un perfil",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/add-contact.md",sourceDirName:"chat",slug:"/chat/add-contact",permalink:"/es/docs/chat/add-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/add-contact.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Una Introducci\xf3n al Chat P2P de Cwtch",permalink:"/es/docs/chat/introduction"},next:{title:"Aceptar/denegar nuevas conversaciones",permalink:"/es/docs/chat/accept-deny-new-conversation"}},l={},p=[],s={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"starting-a-new-conversation"},"Starting a New Conversation"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Selecciona un perfil"),(0,a.kt)("li",{parentName:"ol"},"Haz clic en el bot\xf3n A\xf1adir"),(0,a.kt)("li",{parentName:"ol"},"Selecciona 'Agregar contacto'"),(0,a.kt)("li",{parentName:"ol"},"Pega una direcci\xf3n de Cwtch"),(0,a.kt)("li",{parentName:"ol"},"El contacto se a\xf1adir\xe1 a tu lista de contactos")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ebdc3447.279c0f2a.js b/build-staging/es/assets/js/ebdc3447.279c0f2a.js new file mode 100644 index 00000000..2aa72e51 --- /dev/null +++ b/build-staging/es/assets/js/ebdc3447.279c0f2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[283],{3905:(e,a,n)=>{n.d(a,{Zo:()=>u,kt:()=>v});var r=n(7294);function o(e,a,n){return a in e?Object.defineProperty(e,a,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[a]=n,e}function t(e,a){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);a&&(r=r.filter((function(a){return Object.getOwnPropertyDescriptor(e,a).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var a=1;a<arguments.length;a++){var n=null!=arguments[a]?arguments[a]:{};a%2?t(Object(n),!0).forEach((function(a){o(e,a,n[a])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):t(Object(n)).forEach((function(a){Object.defineProperty(e,a,Object.getOwnPropertyDescriptor(n,a))}))}return e}function s(e,a){if(null==e)return{};var n,r,o=function(e,a){if(null==e)return{};var n,r,o={},t=Object.keys(e);for(r=0;r<t.length;r++)n=t[r],a.indexOf(n)>=0||(o[n]=e[n]);return o}(e,a);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);for(r=0;r<t.length;r++)n=t[r],a.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var a=r.useContext(c),n=a;return e&&(n="function"==typeof e?e(a):i(i({},a),e)),n},u=function(e){var a=l(e.components);return r.createElement(c.Provider,{value:a},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var a=e.children;return r.createElement(r.Fragment,{},a)}},m=r.forwardRef((function(e,a){var n=e.components,o=e.mdxType,t=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=o,v=d["".concat(c,".").concat(m)]||d[m]||p[m]||t;return n?r.createElement(v,i(i({ref:a},u),{},{components:n})):r.createElement(v,i({ref:a},u))}));function v(e,a){var n=arguments,o=a&&a.mdxType;if("string"==typeof e||o){var t=n.length,i=new Array(t);i[0]=m;var s={};for(var c in a)hasOwnProperty.call(a,c)&&(s[c]=a[c]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var l=2;l<t;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},7736:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>t,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const t={sidebar_position:6},i="Compartir un archivo",s={unversionedId:"chat/share-file",id:"chat/share-file",title:"Compartir un archivo",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/share-file.md",sourceDirName:"chat",slug:"/chat/share-file",permalink:"/es/docs/chat/share-file",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-file.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Contestar a un mensaje",permalink:"/es/docs/chat/reply-to-message"},next:{title:"Bloquear un contacto",permalink:"/es/docs/chat/block-contact"}},c={},l=[{value:"\xbfC\xf3mo funciona compartir archivos con grupos? \xbfMis archivos se almacenan en alg\xfan servidor?",id:"c\xf3mo-funciona-compartir-archivos-con-grupos-mis-archivos-se-almacenan-en-alg\xfan-servidor",level:2},{value:"\xbfSignifica esto que tengo que estar en linea para enviar un archivo?",id:"significa-esto-que-tengo-que-estar-en-linea-para-enviar-un-archivo",level:2},{value:"\xbfPor qu\xe9 aparecen contactos nuevos en mi lista?",id:"por-qu\xe9-aparecen-contactos-nuevos-en-mi-lista",level:2},{value:"\xbfQu\xe9 es "SHA512"?",id:"qu\xe9-es-sha512",level:2},{value:"\xbfHay un l\xedmite de tama\xf1o de archivo?",id:"hay-un-l\xedmite-de-tama\xf1o-de-archivo",level:2},{value:"\xbfQu\xe9 son los archivos .manifest?",id:"qu\xe9-son-los-archivos-manifest",level:2},{value:"\xbfQu\xe9 pasa con los metadatos de archivos?",id:"qu\xe9-pasa-con-los-metadatos-de-archivos",level:2},{value:"\xbfPuedo descargar archivos autom\xe1ticamente?",id:"puedo-descargar-archivos-autom\xe1ticamente",level:2}],u={toc:l},d="wrapper";function p(e){let{components:a,...n}=e;return(0,o.kt)(d,(0,r.Z)({},u,n,{components:a,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"compartir-un-archivo"},"Compartir un archivo"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"Experimento de Grupos")," activado."),(0,o.kt)("p",{parentName:"admonition"},"Optionally, you can enable ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," to see display shared image previews in the conversation window.")),(0,o.kt)("p",null,"En una conversaci\xf3n,"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Haz clic en el icono de adjuntar archivo"),(0,o.kt)("li",{parentName:"ol"},"Encuentra el archivo que quieres enviar"),(0,o.kt)("li",{parentName:"ol"},"Confirma que quieres enviarlo")),(0,o.kt)("h2",{id:"c\xf3mo-funciona-compartir-archivos-con-grupos-mis-archivos-se-almacenan-en-alg\xfan-servidor"},"\xbfC\xf3mo funciona compartir archivos con grupos? \xbfMis archivos se almacenan en alg\xfan servidor?"),(0,o.kt)("p",null,"Los archivos se env\xedan a trav\xe9s de conexiones Cwtch Onion a Onion directamente de la persona que ofrece el archivo a la persona que lo recibe. La oferta inicial de enviar un archivo se publica como un mensaje est\xe1ndar de Cwtch de conversaci\xf3n/superposici\xf3n. Para grupos, esto significa que la oferta inicial (que contiene el nombre del archivo, el tama\xf1o, el hash y un nonce) se publica en el servidor de grupos, pero entonces cada destinatario se conecta a usted individualmente para recibir el contenido real del archivo."),(0,o.kt)("h2",{id:"significa-esto-que-tengo-que-estar-en-linea-para-enviar-un-archivo"},"\xbfSignifica esto que tengo que estar en linea para enviar un archivo?"),(0,o.kt)("p",null,'S\xed. Si la persona que ofrece el archivo se desconecta, tendr\xe1s que esperar a que se conecte para reanudar la transferencia de archivos. El protocolo subyacente divide los archivos en fragmentos individuales y verificables, para que en una versi\xf3n futura puedas "rehost" un archivo publicado en un grupo, e incluso descargar desde m\xfaltiples hosts a la vez (como bittorrent).'),(0,o.kt)("h2",{id:"por-qu\xe9-aparecen-contactos-nuevos-en-mi-lista"},"\xbfPor qu\xe9 aparecen contactos nuevos en mi lista?"),(0,o.kt)("p",null,"Esto se debe a la forma en que Cwtch maneja actualmente conexiones desde direcciones desconocidas. Puesto que publicar un archivo en un grupo resulta en que los miembros del grupo se conecten directamente contigo, algunos de esos miembros pueden no estar en tu lista de contactos y por lo tanto su conexi\xf3n de descarga contigo aparecer\xe1 en tu lista como una solicitud de contacto."),(0,o.kt)("h2",{id:"qu\xe9-es-sha512"},'\xbfQu\xe9 es "SHA512"?'),(0,o.kt)("p",null,"SHA512 es una ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Cryptographic_hash_function"},"Funci\xf3n hash criptogr\xe1fica")," que puede utilizarse para verificar que el archivo que descargaste es una copia correcta del archivo que se ofreci\xf3. Cwtch realiza esta verificaci\xf3n por ti autom\xe1ticamente, \xa1pero eres bienvenido a probarlo t\xfa mismo! Ten en cuenta que incluimos una nonce aleatoria con invitacions de archivos, as\xed que un contacto no puede pedirte cualquier hash aleatorio que tengas o archivos de conversaciones de las que no formen parte."),(0,o.kt)("h2",{id:"hay-un-l\xedmite-de-tama\xf1o-de-archivo"},"\xbfHay un l\xedmite de tama\xf1o de archivo?"),(0,o.kt)("p",null,"El l\xedmite actual es de 10 gigabytes por archivo."),(0,o.kt)("h2",{id:"qu\xe9-son-los-archivos-manifest"},"\xbfQu\xe9 son los archivos .manifest?"),(0,o.kt)("p",null,"Los archivos .manifest se utilizan al descargar el archivo para verificar que los fragmentos individuales se reciben correctamente, y reanudar transferencias interrumpidas. Tambi\xe9n contienen la informaci\xf3n de la oferta original de archivos. Puedes borrarlos sin problemas una vez que la descarga haya finalizado. En Android, los manifiestos se almacenan en la cach\xe9 de la aplicaci\xf3n, y se pueden borrar a trav\xe9s de la configuraci\xf3n del sistema."),(0,o.kt)("h2",{id:"qu\xe9-pasa-con-los-metadatos-de-archivos"},"\xbfQu\xe9 pasa con los metadatos de archivos?"),(0,o.kt)("p",null,"Enviamos el nombre del archivo como sugerencia y le ayudamos a distinguirlo de otras invitaciones de archivos. El camino completo se despoja antes de enviar el archivo. Debes tener cuidado con los metadatos ocultos que pueden almacenarse en el archivo en s\xed, que var\xeda dependiendo del formato del archivo. Por ejemplo, las im\xe1genes pueden contener informaci\xf3n sobre geolocalizaci\xf3n e informaci\xf3n sobre la c\xe1mara que las tom\xf3. Los archivos PDF son notorios por contener informaci\xf3n oculta como el nombre del autor o la m\xe1quina en la que fueron creados. En general, s\xf3lo deber\xedas enviar y recibir archivos de personas en las que conf\xedes."),(0,o.kt)("h2",{id:"puedo-descargar-archivos-autom\xe1ticamente"},"\xbfPuedo descargar archivos autom\xe1ticamente?"),(0,o.kt)("p",null,"If the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures experiment")," is enabled then Cwtch will automatically download images from accepted conversations"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ee1e10c4.8e8a516f.js b/build-staging/es/assets/js/ee1e10c4.8e8a516f.js new file mode 100644 index 00000000..d7a3f346 --- /dev/null +++ b/build-staging/es/assets/js/ee1e10c4.8e8a516f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7372],{6658:s=>{s.exports=JSON.parse('{"label":"libcwtch","permalink":"/es/blog/tags/libcwtch","allTagsPath":"/es/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/ef78badf.c85ba6c9.js b/build-staging/es/assets/js/ef78badf.c85ba6c9.js new file mode 100644 index 00000000..c67a4dd0 --- /dev/null +++ b/build-staging/es/assets/js/ef78badf.c85ba6c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8922],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var a=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,a,o=function(e,t){if(null==e)return{};var r,a,o={},n=Object.keys(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=a.createContext({}),p=function(e){var t=a.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=p(e.components);return a.createElement(i.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,o=e.mdxType,n=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(r),h=o,f=u["".concat(i,".").concat(h)]||u[h]||m[h]||n;return r?a.createElement(f,l(l({ref:t},c),{},{components:r})):a.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=r.length,l=new Array(n);l[0]=h;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[u]="string"==typeof e?e:o,l[1]=s;for(var p=2;p<n;p++)l[p]=r[p];return a.createElement.apply(null,l)}return a.createElement.apply(null,r)}h.displayName="MDXCreateElement"},5481:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>m,frontMatter:()=>n,metadata:()=>s,toc:()=>p});var a=r(7462),o=(r(7294),r(3905));const n={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,s={permalink:"/es/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"27 de enero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"support",permalink:"/es/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/es/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/es/blog/cwtch-bindings-reproducible"}},i={authorsImageUrls:[void 0]},p=[],c={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"One of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,o.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,o.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,o.kt)("p",null,"The questions we aim to answer in this post are: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,o.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,o.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,o.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,o.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(6149).Z,width:"1005",height:"481"})))}m.isMDXComponent=!0},6149:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f041e880.fe38fdf2.js b/build-staging/es/assets/js/f041e880.fe38fdf2.js new file mode 100644 index 00000000..b793eb7c --- /dev/null +++ b/build-staging/es/assets/js/f041e880.fe38fdf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5226],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=n,d=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return a?r.createElement(d,i(i({ref:t},p),{},{components:a})):r.createElement(d,i({ref:t},p))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s<o;s++)i[s]=a[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},3291:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/es/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"31 de marzo de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"planning",permalink:"/es/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/es/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/es/blog/cwtch-nightly-1-11"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f384c30f.e1b97bdd.js b/build-staging/es/assets/js/f384c30f.e1b97bdd.js new file mode 100644 index 00000000..1da30e51 --- /dev/null +++ b/build-staging/es/assets/js/f384c30f.e1b97bdd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5760],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>v});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),l=p(n),m=i,v=l["".concat(s,".").concat(m)]||l[m]||d[m]||o;return n?r.createElement(v,a(a({ref:t},u),{},{components:n})):r.createElement(v,a({ref:t},u))}));function v(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[l]="string"==typeof e?e:i,a[1]=c;for(var p=2;p<o;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3627:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:4},a="Enviar invitaciones a un Grupo",c={unversionedId:"groups/send-invite",id:"groups/send-invite",title:"Enviar invitaciones a un Grupo",description:"Esta funci\xf3n requiere Experimentos habilitados y el Experimento de Grupos activado.",source:"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/send-invite.md",sourceDirName:"groups",slug:"/groups/send-invite",permalink:"/es/docs/groups/send-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/send-invite.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Crea un grupo nuevo",permalink:"/es/docs/groups/create-group"},next:{title:"Aceptar una invitaci\xf3n de grupo",permalink:"/es/docs/groups/accept-group-invite"}},s={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(l,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"enviar-invitaciones-a-un-grupo"},"Enviar invitaciones a un Grupo"),(0,i.kt)("admonition",{title:"Experimentos Requeridos",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Esta funci\xf3n requiere ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experimentos habilitados")," y el ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Experimento de Grupos")," activado.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Ir a un chat con un amigo"),(0,i.kt)("li",{parentName:"ol"},"Pulsa en el icono de invitaci\xf3n"),(0,i.kt)("li",{parentName:"ol"},"Selecciona el grupo al que deseas invitar a tu amigo"),(0,i.kt)("li",{parentName:"ol"},"Pulsa Invitar"),(0,i.kt)("li",{parentName:"ol"},"Has enviado una invitaci\xf3n")),(0,i.kt)("div",null,(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Group_Invite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f53ef702.216ea841.js b/build-staging/es/assets/js/f53ef702.216ea841.js new file mode 100644 index 00000000..ae06bb9c --- /dev/null +++ b/build-staging/es/assets/js/f53ef702.216ea841.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6017],{153:e=>{e.exports=JSON.parse('{"title":"Servers","slug":"/category/servers","permalink":"/es/docs/category/servers","navigation":{"previous":{"title":"Administrar servidores","permalink":"/es/docs/groups/manage-known-servers"},"next":{"title":"Introducci\xf3n a Servidores","permalink":"/es/docs/servers/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f63f85fb.5b2f2150.js b/build-staging/es/assets/js/f63f85fb.5b2f2150.js new file mode 100644 index 00000000..32670b47 --- /dev/null +++ b/build-staging/es/assets/js/f63f85fb.5b2f2150.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8537],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(r),m=o,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return r?n.createElement(h,s(s({ref:t},p),{},{components:r})):n.createElement(h,s({ref:t},p))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:o,s[1]=a;for(var c=2;c<i;c++)s[c]=r[c];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},7101:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={},s="Development",a={unversionedId:"development",id:"development",title:"Development",description:"The main process to counter malicious actors in development of Cwtch is the openness of the process.",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/development.md",sourceDirName:".",slug:"/development",permalink:"/es/security/development",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Deployment",permalink:"/es/security/deployment"},next:{title:"References",permalink:"/es/security/references"}},l={},c=[{value:"Risk: Developer Directly Pushes Malicious Code",id:"risk-developer-directly-pushes-malicious-code",level:3},{value:"Risk: Code Regressions",id:"risk-code-regressions",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"development"},"Development"),(0,o.kt)("p",null,"The main process to counter malicious actors in development of Cwtch is the openness of the process."),(0,o.kt)("p",null,"To enhance this openness, automated builds, testing and packaging are defined as part of the repositories - improving te robustness of the code base at every stage."),(0,o.kt)("p",null,(0,o.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/1.png",alt:null})),(0,o.kt)("p",null,"While individual tests aren't perfect, and all processes have gaps, we should be committed to make it as easy as possible to contribute to Cwtch while also building pipelines and processes that catch errors (unintential or malicious) as soon as possible."),(0,o.kt)("h3",{id:"risk-developer-directly-pushes-malicious-code"},"Risk: Developer Directly Pushes Malicious Code"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Mitigated")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"trunk")," is currently locked and only 3 Open Privacy staff members have permission to override it, in addition the responsibility of monitoring changes."),(0,o.kt)("p",null,"Further every new pull request and merge triggered automated builds & tests which trigger emails and audit logs."),(0,o.kt)("p",null,"The code is also open source and inspectable by anyone."),(0,o.kt)("h3",{id:"risk-code-regressions"},"Risk: Code Regressions"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (See individual project entries in this handbook for more information)"),(0,o.kt)("p",null,"Our automated pipelines have the ability to catch regressions when that behaviour is detectable."),(0,o.kt)("p",null,"The greatest challenge is in defining how such regressions are detected for the ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," - where behaviour isn't as strictly defined as it is for the individual libraries."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f6d09a50.114ee1a4.js b/build-staging/es/assets/js/f6d09a50.114ee1a4.js new file mode 100644 index 00000000..69b3c331 --- /dev/null +++ b/build-staging/es/assets/js/f6d09a50.114ee1a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8962],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=o,f=p["".concat(c,".").concat(h)]||p[h]||u[h]||a;return n?r.createElement(f,i(i({ref:t},d),{},{components:n})):r.createElement(f,i({ref:t},d))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l<a;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},4497:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={},i="Android Service",s={unversionedId:"components/ui/android",id:"components/ui/android",title:"Android Service",description:"Adapted from Integrating FFI processes with Android services",source:"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/android.md",sourceDirName:"components/ui",slug:"/components/ui/android",permalink:"/es/security/components/ui/android",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cwtch UI",permalink:"/es/security/category/cwtch-ui"},next:{title:"Image Previews",permalink:"/es/security/components/ui/image_previews"}},c={},l=[],d={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"android-service"},"Android Service"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/11-android-ffi-service-integration/"},"Adapted from: Discreet Log #11: Integrating FFI processes with Android services")),(0,o.kt)("p",null,"In addition to needing to make plain ol\u2019 method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isn\u2019t really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service."),(0,o.kt)("p",null,"The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, it\u2019s not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service."),(0,o.kt)("p",null,"If you\u2019d like to follow along, our WorkManager specifications are created in the handleCwtch() method of ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt"},"MainActivity.kt"),", and the workers themselves are defined in ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt"},"FlwtchWorker.kt"),"."),(0,o.kt)("p",null,"Our plain ol\u2019 method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback."),(0,o.kt)("p",null,"One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, it\u2019s easy for it to yield and resume as necessary while waiting for events to be generated. Cwtch\u2019s goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately."),(0,o.kt)("p",null,"FlwtchWorker\u2019s eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isn\u2019t running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontend\u2019s Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary."),(0,o.kt)("p",null,"Messages and other permanent state are stored on disk by the service, so the frontend doesn\u2019t need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state."),(0,o.kt)("p",null,"Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isn\u2019t the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'private fun getNativeLibDir(): String {\n val ainfo = this.applicationContext.packageManager.getApplicationInfo(\n "im.cwtch.flwtch", // Must be app name\n PackageManager.GET_SHARED_LIBRARY_FILES)\n return ainfo.nativeLibraryDir\n}\n')),(0,o.kt)("p",null,"\u2026then, whenever the app is launched, we cancel any jobs that aren\u2019t tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f76a3b8e.c0899ada.js b/build-staging/es/assets/js/f76a3b8e.c0899ada.js new file mode 100644 index 00000000..6a483915 --- /dev/null +++ b/build-staging/es/assets/js/f76a3b8e.c0899ada.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2184],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},g="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),g=l(n),m=a,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[g]="string"==typeof e?e:a,o[1]=c;for(var l=2;l<i;l++)o[l]=n[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3103:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/es/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"17 de febrero de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"support",permalink:"/es/blog/tags/support"},{label:"testing",permalink:"/es/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/es/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/es/blog/cwtch-android-reproducibility"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},g="wrapper";function u(e){let{components:t,...i}=e;return(0,a.kt)(g,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,a.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(6097).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},6097:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/f928e8d9.80bb4b49.js b/build-staging/es/assets/js/f928e8d9.80bb4b49.js new file mode 100644 index 00000000..52b28fe6 --- /dev/null +++ b/build-staging/es/assets/js/f928e8d9.80bb4b49.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8786],{7160:e=>{e.exports=JSON.parse('{"pluginId":"docs-developer","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Introduction to Cwtch Development","href":"/es/developing/intro","docId":"intro"},{"type":"link","label":"Release and Packaging Process","href":"/es/developing/release","docId":"release"},{"type":"category","label":"Building a Cwtch App","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/es/developing/building-a-cwtch-app/intro","docId":"building-a-cwtch-app/intro"},{"type":"link","label":"Core Concepts","href":"/es/developing/building-a-cwtch-app/core-concepts","docId":"building-a-cwtch-app/core-concepts"},{"type":"link","label":"Building a Cwtch Echobot","href":"/es/developing/building-a-cwtch-app/building-an-echobot","docId":"building-a-cwtch-app/building-an-echobot"}],"href":"/es/developing/category/building-a-cwtch-app"}]},"docs":{"building-a-cwtch-app/building-an-echobot":{"id":"building-a-cwtch-app/building-an-echobot","title":"Building a Cwtch Echobot","description":"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/core-concepts":{"id":"building-a-cwtch-app/core-concepts","title":"Core Concepts","description":"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/intro":{"id":"building-a-cwtch-app/intro","title":"Getting Started","description":"Choosing A Cwtch Library","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Introduction to Cwtch Development","description":"- Core Concepts","sidebar":"tutorialSidebar"},"release":{"id":"release","title":"Release and Packaging Process","description":"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/fb3c1916.872615eb.js b/build-staging/es/assets/js/fb3c1916.872615eb.js new file mode 100644 index 00000000..057c3b11 --- /dev/null +++ b/build-staging/es/assets/js/fb3c1916.872615eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[276],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),s=p(r),f=o,b=s["".concat(l,".").concat(f)]||s[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},8886:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},a="Introduction to Cwtch Development",c={unversionedId:"intro",id:"intro",title:"Introduction to Cwtch Development",description:"- Core Concepts",source:"@site/developing/intro.md",sourceDirName:".",slug:"/intro",permalink:"/es/developing/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Release and Packaging Process",permalink:"/es/developing/release"}},l={},p=[{value:"Contributing to Cwtch Core",id:"contributing-to-cwtch-core",level:2},{value:"Building Cwtch Bots",id:"building-cwtch-bots",level:2}],u={toc:p},s="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introduction-to-cwtch-development"},"Introduction to Cwtch Development"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/core-concepts"},"Core Concepts")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/intro"},"Security Handbook"))),(0,o.kt)("h2",{id:"contributing-to-cwtch-core"},"Contributing to Cwtch Core"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/release"},"Release and Packaging Process"))),(0,o.kt)("h2",{id:"building-cwtch-bots"},"Building Cwtch Bots"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"Choosing a Library")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/building-an-echobot"},"Echobot Tutorial"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/fcdd064d.8c75555c.js b/build-staging/es/assets/js/fcdd064d.8c75555c.js new file mode 100644 index 00000000..a9e22950 --- /dev/null +++ b/build-staging/es/assets/js/fcdd064d.8c75555c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8543],{3905:(e,r,a)=>{a.d(r,{Zo:()=>d,kt:()=>f});var o=a(7294);function n(e,r,a){return r in e?Object.defineProperty(e,r,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[r]=a,e}function t(e,r){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),a.push.apply(a,o)}return a}function i(e){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?t(Object(a),!0).forEach((function(r){n(e,r,a[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(a,r))}))}return e}function c(e,r){if(null==e)return{};var a,o,n=function(e,r){if(null==e)return{};var a,o,n={},t=Object.keys(e);for(o=0;o<t.length;o++)a=t[o],r.indexOf(a)>=0||(n[a]=e[a]);return n}(e,r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);for(o=0;o<t.length;o++)a=t[o],r.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var s=o.createContext({}),l=function(e){var r=o.useContext(s),a=r;return e&&(a="function"==typeof e?e(r):i(i({},r),e)),a},d=function(e){var r=l(e.components);return o.createElement(s.Provider,{value:r},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},m=o.forwardRef((function(e,r){var a=e.components,n=e.mdxType,t=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),p=l(a),m=n,f=p["".concat(s,".").concat(m)]||p[m]||u[m]||t;return a?o.createElement(f,i(i({ref:r},d),{},{components:a})):o.createElement(f,i({ref:r},d))}));function f(e,r){var a=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var t=a.length,i=new Array(t);i[0]=m;var c={};for(var s in r)hasOwnProperty.call(r,s)&&(c[s]=r[s]);c.originalType=e,c[p]="string"==typeof e?e:n,i[1]=c;for(var l=2;l<t;l++)i[l]=a[l];return o.createElement.apply(null,i)}return o.createElement.apply(null,a)}m.displayName="MDXCreateElement"},4753:(e,r,a)=>{a.r(r),a.d(r,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var o=a(7462),n=(a(7294),a(3905));const t={sidebar_position:5},i="Tor",c={unversionedId:"tor",id:"tor",title:"Tor",description:'Cwtch utiliza Tor para proporcionar enrutamiento y conexiones. Usar servicios ocultos de Tor para albergar perfiles y conexiones "ef\xedmeras" proporciona fuertes garant\xedas de anonimato a los usuarios de Cwtch a la hora de hacer conexiones.',source:"@site/i18n/es/docusaurus-plugin-content-docs/current/tor.md",sourceDirName:".",slug:"/tor",permalink:"/es/docs/tor",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/tor.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"QR Codes",permalink:"/es/docs/settings/experiments/qrcodes"},next:{title:"Contribute",permalink:"/es/docs/category/contribute"}},s={},l=[{value:"Panel de Tor",id:"panel-de-tor",level:2},{value:"Reiniciar Tor",id:"reiniciar-tor",level:3},{value:"Consenso de Cach\xe9 de Tor",id:"consenso-de-cach\xe9-de-tor",level:3},{value:"Configuraci\xf3n avanzada de Tor",id:"configuraci\xf3n-avanzada-de-tor",level:3}],d={toc:l},p="wrapper";function u(e){let{components:r,...t}=e;return(0,n.kt)(p,(0,o.Z)({},d,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"tor"},"Tor"),(0,n.kt)("p",null,"Cwtch utiliza ",(0,n.kt)("a",{parentName:"p",href:"https://www.torproject.org/"},"Tor"),' para proporcionar enrutamiento y conexiones. Usar servicios ocultos de Tor para albergar perfiles y conexiones "ef\xedmeras" proporciona fuertes garant\xedas de anonimato a los usuarios de Cwtch a la hora de hacer conexiones.'),(0,n.kt)("h2",{id:"panel-de-tor"},"Panel de Tor"),(0,n.kt)("p",null,"Dado que estamos a\xf1adiendo una capa de red adicional a Cwtch, proporcionamos un panel para ver el estado de la red Tor y hacer cambios. Para acceder a \xe9l"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Desde el panel de lista de perfiles, haz clic en el icono de Tor ",(0,n.kt)("img",{alt:"icono de tor",src:a(4525).Z,width:"32",height:"32"})),(0,n.kt)("li",{parentName:"ol"},"Ver el estado de la red tor")),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre"},"Estado de Tor: en l\xednea\nVersi\xf3n Tor: 0.4.6.9\n")),(0,n.kt)("h3",{id:"reiniciar-tor"},"Reiniciar Tor"),(0,n.kt)("p",null,"La red Tor puede ocasionalmente tener conexiones obsoletas que no son detectadas inmediatamente por Tor o por Cwtch (siempre estamos intentando mejorar esto). A veces un usuario puede encontrar contactos o grupos que aparecen fuera de l\xednea que deber\xedan estar en l\xednea. Si quieres reiniciar todas las conexiones de red en Cwtch, proporcionamos un mecanismo para reiniciar tor desde el app. El bot\xf3n ",(0,n.kt)("strong",{parentName:"p"},"Reiniciar")," reiniciar\xe1 Tor desde la aplicaci\xf3n de Cwtch."),(0,n.kt)("h3",{id:"consenso-de-cach\xe9-de-tor"},"Consenso de Cach\xe9 de Tor"),(0,n.kt)("p",null,"Por defecto iniciamos un proceso nuevo de Tor cada vez que arranca la aplicaci\xf3n, y requiere descargar un estado de red de Tor antes de poder comenzar. Este proceso no es instant\xe1neo. Si quieres acelerar el arranque de Cwtch, puedes habilitar Cach\xe9 de Conflictos de Tor para acelerar futuros arranques. Si te encuentras con un problema de arranque en el que los datos son obsoletos o corruptos y el reporte de Cwtch no puede arrancar Tor, desactiva esta funci\xf3n y ",(0,n.kt)("strong",{parentName:"p"},"reinicia tor")," de nuevo, y deber\xeda funcionar."),(0,n.kt)("h3",{id:"configuraci\xf3n-avanzada-de-tor"},"Configuraci\xf3n avanzada de Tor"),(0,n.kt)("p",null,"Ofrecemos la posibilidad de proporcionar avanzadamente la opci\xf3n de configuraci\xf3n de Tor en esta secci\xf3n permiti\xe9ndote"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Especificar un puerto SOCKS personalizado para conectarse a una conexi\xf3n Tor existente"),(0,n.kt)("li",{parentName:"ul"},"Especifique un puerto de control personalizado para conectarse a una conexi\xf3n Tor existente"),(0,n.kt)("li",{parentName:"ul"},"y especificar opciones adicionales introduciendo opciones ",(0,n.kt)("inlineCode",{parentName:"li"},"torrc")," personalizadas")))}u.isMDXComponent=!0},4525:(e,r,a)=>{a.d(r,{Z:()=>o});const o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAATrwAAE68BY+aOwwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMUSURBVFiFvZZPiNVVFMc/Z546zkwzOikaxlSSFRklQVBQCEWmmRK1CYIWLabIReC6TdCiVtamlaUlQbhrkfTPiMxF0KoyhtISyjBpgkZszJnGT4vfefXT3u817zfvzYHHvffc8873+zv33HsO9EDUsfna9vUAfBcwlPMrFoWAukQN9WXgNNBQ9wPX/99/l3SDAHArsAMYBG4HXge2R8SXXfJfLeom9Xn1jHpY/UPd3HPgEoED6kn1N3VGfWAxwZeqU/4rzywaeBLYXALfV8dHrSRUHwRWAnek6gfg2Tq+6l7DCWAjcBz4DtgbEedq+qon6ls53p1HUCvzF/IQrcixcdm69wTU9aXlZI671UYr+66KujMfnKvUAXVY/SmP4aB6Za+AV6hvqq8l6Op8B1aqT5au46S6S41ugm9Uj6hbSroNOV6bhehzL5V3uxINdYv6abnGq2vV0Zzfk9Vwm/+Vr9SRhYDfpH7W/JL80lXq8lw3Mg+25t5UCxLvLITAh+rVOe9TB0t7oV6nrlMfyXw42oKA5aO7XCqvoboV+CIifs6EWhoR0yWTbRTNxwhwGHgIOFbhbnfHBICdQDN8/RFxIYkNqePAidQNAOeAMeD3Cl/3qcOdEtgETKj/2KjXAE8BByLieKq/pmi9+oDzFb76qWjP2hFoANNAIyL+zGN4HHilFI1RigjMAWeBdk3o2lbKduX4PEXJnQZmgXuBgxFhgq8GbgHOpJ854IY2/iZbKdtF4FvgLuBi3uWxiDhZ2n8UOAKsAn6haEarCtIscKJTAoeA8YiYocj0IXWotP9jRmMQWAasS7tW8lFETHVK4H3gRos6PwN8DzwGoC6jyHwSdD3wK3Bzha89VSCVBCJiDngaeBsYBk4BO9SRjMpoicAwRTIOtHD1RkR83DGBJHEUeA54jyLMe4E9FnV/TdMM2A7c2cLFofyIaox2m01R7wdeBT4AvgFuoziSCeAJ4GGKXGjKX8CLwAsRMTsfjPmQWK6Oq59k0bmgzuXPHI+pL3lpx9RWajUNaj9F1jfr/VngdJ3O+G/ZO0GaKrbieAAAAABJRU5ErkJggg=="}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/fd27e325.93065cb0.js b/build-staging/es/assets/js/fd27e325.93065cb0.js new file mode 100644 index 00000000..c6d34e00 --- /dev/null +++ b/build-staging/es/assets/js/fd27e325.93065cb0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1199],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=r,d=u["".concat(s,".").concat(m)]||u[m]||h[m]||i;return n?o.createElement(d,c(c({ref:t},p),{},{components:n})):o.createElement(d,c({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,c=new Array(i);c[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:r,c[1]=a;for(var l=2;l<i;l++)c[l]=n[l];return o.createElement.apply(null,c)}return o.createElement.apply(null,n)}m.displayName="MDXCreateElement"},9327:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:3},c="Building a Cwtch Echobot",a={unversionedId:"building-a-cwtch-app/building-an-echobot",id:"building-a-cwtch-app/building-an-echobot",title:"Building a Cwtch Echobot",description:"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.",source:"@site/developing/building-a-cwtch-app/building-an-echobot.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/building-an-echobot",permalink:"/es/developing/building-a-cwtch-app/building-an-echobot",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Core Concepts",permalink:"/es/developing/building-a-cwtch-app/core-concepts"}},s={},l=[{value:"Using CwtchBot (Go)",id:"using-cwtchbot-go",level:2},{value:"Using Imp (Rust)",id:"using-imp-rust",level:2}],p={toc:l},u="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"building-a-cwtch-echobot"},"Building a Cwtch Echobot"),(0,r.kt)("p",null,"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent."),(0,r.kt)("p",null,"For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or\nframework."),(0,r.kt)("h2",{id:"using-cwtchbot-go"},"Using CwtchBot (Go)"),(0,r.kt)("admonition",{title:"CwtchBot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the CwtchBot framework.")),(0,r.kt)("p",null,"Start by creating a new Go project, and a file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.go"),". In the ",(0,r.kt)("inlineCode",{parentName:"p"},"main")," function:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "cwtch.im/cwtch/event"\n "cwtch.im/cwtch/model"\n "cwtch.im/cwtch/model/attr"\n "cwtch.im/cwtch/model/constants"\n "fmt"\n "git.openprivacy.ca/sarah/cwtchbot"\n _ "github.com/mutecomm/go-sqlcipher/v4"\n "os/user"\n "path"\n)\n\nfunc main() {\n user, _ := user.Current()\n cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")\n cwtchbot.Launch()\n\n // Set Some Profile Information\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")\n\n fmt.Printf("echobot address: %v\\n", cwtchbot.Peer.GetOnion())\n\n for {\n message := cwtchbot.Queue.Next()\n cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])\n switch message.EventType {\n case event.NewMessageFromPeer:\n msg := cwtchbot.UnpackMessage(message.Data[event.Data])\n fmt.Printf("Message: %v\\n", msg)\n reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n case event.ContactCreated:\n fmt.Printf("Auto approving stranger %v %v\\n", cid, message.Data[event.RemotePeer])\n // accept the stranger as a new contact\n cwtchbot.Peer.AcceptConversation(cid.ID)\n // Send Hello...\n reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n }\n }\n}\n')),(0,r.kt)("h2",{id:"using-imp-rust"},"Using Imp (Rust)"),(0,r.kt)("admonition",{title:"Imp (Rust) Bot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'use std::borrow::BorrowMut;\nuse std::thread;\nuse chrono::{DateTime, FixedOffset};\nuse libcwtch;\nuse libcwtch::CwtchLib;\nuse libcwtch::structs::*;\nuse libcwtch::event::*;\nuse cwtch_imp::imp;\nuse cwtch_imp::behaviour::*;\nuse cwtch_imp::imp::Imp;\n\nconst BOT_HOME: &str = "~/.cwtch/bots/echobot";\nconst BOT_NAME: &str = "echobot";\n\nstruct Echobot {}\n\nfn main() {\n let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();\n let event_loop_handle = thread::spawn(move || {\n let mut echobot = Echobot {};\n let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());\n bot.event_loop::<Echobot>(echobot.borrow_mut());\n });\n event_loop_handle.join().expect("Error running event loop");\n}\n\nimpl imp::EventHandler for Echobot {\n fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {\n let response = Message {\n o: MessageType::TextMessage,\n d: message.d,\n };\n cwtch.send_message(&profile.profile_id, conversation_id, &response);\n }\n\n fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {\n match event {\n Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {\n println!(\n "\\n***** {} at {} *****\\n",\n name, profile_id.as_str()\n );\n }\n _ => (),\n };\n }\n}\n')))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/fd33d4dc.75f47db3.js b/build-staging/es/assets/js/fd33d4dc.75f47db3.js new file mode 100644 index 00000000..8cf4488f --- /dev/null +++ b/build-staging/es/assets/js/fd33d4dc.75f47db3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1787],{7010:e=>{e.exports=JSON.parse('{"permalink":"/es/blog/tags/cwtch/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/es/blog/tags/cwtch","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/fdfd1857.63bd4b8c.js b/build-staging/es/assets/js/fdfd1857.63bd4b8c.js new file mode 100644 index 00000000..3edb568e --- /dev/null +++ b/build-staging/es/assets/js/fdfd1857.63bd4b8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1570],{9547:t=>{t.exports=JSON.parse('{"title":"Getting started","slug":"/category/getting-started","permalink":"/es/docs/category/getting-started","navigation":{"previous":{"title":"\xbfQu\xe9 es Cwtch?","permalink":"/es/docs/intro"},"next":{"title":"Supported Platforms","permalink":"/es/docs/getting-started/supported_platforms"}}}')}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/fe1dd7ae.c18024ee.js b/build-staging/es/assets/js/fe1dd7ae.c18024ee.js new file mode 100644 index 00000000..a75eb7ea --- /dev/null +++ b/build-staging/es/assets/js/fe1dd7ae.c18024ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1979],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>u});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,a,n=function(e,t){if(null==e)return{};var r,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(r),m=n,u=h["".concat(l,".").concat(m)]||h[m]||g[m]||o;return r?a.createElement(u,i(i({ref:t},s),{},{components:r})):a.createElement(u,i({ref:t},s))}));function u(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=r[p];return a.createElement.apply(null,i)}return a.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1501:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/es/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"7 de junio de 2023",tags:[{label:"cwtch",permalink:"/es/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/es/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/es/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/es/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/es/blog/cwtch-developer-documentation"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function g(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(9964).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},9964:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"}}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/main.7630ede2.js b/build-staging/es/assets/js/main.7630ede2.js new file mode 100644 index 00000000..48c60534 --- /dev/null +++ b/build-staging/es/assets/js/main.7630ede2.js @@ -0,0 +1,2 @@ +/*! For license information please see main.7630ede2.js.LICENSE.txt */ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),s=n(6887);const l={"00242891":[()=>n.e(4667).then(n.t.bind(n,1369,19)),"~blog/default/es-blog-tags-cwtch-stable-page-2-300-list.json",1369],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"02d640a3":[()=>n.e(3066).then(n.t.bind(n,3156,19)),"~docs/default/category-esdocs-tutorialsidebar-category-contribuye-f7f.json",3156],"03aa1116":[()=>n.e(9587).then(n.t.bind(n,1472,19)),"~blog/default/es-blog-tags-cwtch-stable-ad5-list.json",1472],"049fd9f7":[()=>n.e(426).then(n.bind(n,1576)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/group-experiment.md",1576],"05def798":[()=>n.e(8798).then(n.bind(n,966)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/ui-columns.md",966],"062eafd9":[()=>n.e(984).then(n.t.bind(n,2700,19)),"~blog/default/es-blog-tags-autobindings-049-list.json",2700],"06622c1f":[()=>n.e(4811).then(n.bind(n,6476)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/change-name.md",6476],"09ee442d":[()=>n.e(1319).then(n.bind(n,6886)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/intro.md",6886],"0aa99d8f":[()=>n.e(3633).then(n.bind(n,1991)),"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/introduction.md",1991],"0c1afdee":[()=>n.e(6060).then(n.t.bind(n,5356,19)),"~blog/default/es-blog-tags-support-7f0.json",5356],"0c1d60b0":[()=>n.e(4174).then(n.bind(n,3514)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/server.md",3514],"0d64c1d9":[()=>n.e(8710).then(n.bind(n,9133)),"@site/blog/2023-01-20-reproducible-builds-bindings.md",9133],"0e00d73c":[()=>n.e(836).then(n.bind(n,6384)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/unlock-profile.md",6384],"0e5857d6":[()=>n.e(5889).then(n.bind(n,1422)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/image-previews-and-profile-pictures.md",1422],"114c7a7e":[()=>n.e(2524).then(n.bind(n,5469)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/streamer-mode.md",5469],"141cdfa9":[()=>n.e(7293).then(n.bind(n,677)),"@site/blog/2023-04-06-availability-and-profile-attributes.md?truncated=true",677],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],"15cce247":[()=>n.e(4318).then(n.t.bind(n,188,19)),"~docs/default/category-esdocs-tutorialsidebar-category-groups-d71.json",188],17896441:[()=>Promise.all([n.e(532),n.e(9785),n.e(7918)]).then(n.bind(n,5154)),"@theme/DocItem",5154],"1a25c548":[()=>n.e(5732).then(n.bind(n,1202)),"@site/blog/2023-01-06-path-to-cwtch-stable.md?truncated=true",1202],"1af3d897":[()=>n.e(1443).then(n.t.bind(n,400,19)),"~blog/default/es-blog-tags-testing-182.json",400],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1c2b746e":[()=>n.e(1539).then(n.bind(n,2465)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/delete-contact.md",2465],"1c48b4d1":[()=>n.e(8664).then(n.bind(n,4195)),"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/developing.md",4195],"1cd6f7c0":[()=>n.e(2995).then(n.t.bind(n,6448,19)),"~blog/default/es-blog-tags-cwtch-dfb-list.json",6448],"1e810a61":[()=>n.e(4533).then(n.t.bind(n,1888,19)),"~blog/default/es-blog-tags-release-5a4-list.json",1888],"1ebd8798":[()=>n.e(4788).then(n.bind(n,5558)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md?truncated=true",5558],"1f18ed69":[()=>n.e(8261).then(n.t.bind(n,420,19)),"~blog/default/es-blog-tags-libcwtch-52a-list.json",420],"1f984337":[()=>n.e(3769).then(n.t.bind(n,295,19)),"~blog/default/es-blog-tags-bindings-e6c.json",295],"21b6537d":[()=>n.e(2806).then(n.bind(n,4750)),"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/share-key.md",4750],"23c99aae":[()=>n.e(8639).then(n.t.bind(n,867,19)),"~blog/default/es-blog-tags-planning-e48.json",867],"24c23e10":[()=>n.e(3346).then(n.bind(n,8716)),"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/documentation.md",8716],"25b9f0e4":[()=>n.e(6649).then(n.bind(n,2243)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/accept-group-invite.md",2243],"26a00d26":[()=>n.e(6719).then(n.t.bind(n,9922,19)),"~blog/default/es-blog-page-2-325.json",9922],"270b2a86":[()=>n.e(355).then(n.bind(n,7990)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/share-address-with-friends.md",7990],"2928a17c":[()=>n.e(2054).then(n.bind(n,6244)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/introduction.md",6244],"2d2c7491":[()=>n.e(3455).then(n.bind(n,6316)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/tapir/packet_format.md",6316],"302af923":[()=>n.e(1664).then(n.t.bind(n,5960,19)),"~blog/default/es-blog-tags-bindings-e6c-list.json",5960],"31631b3e":[()=>n.e(5170).then(n.bind(n,6335)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/connectivity/intro.md",6335],"33c3c542":[()=>n.e(4733).then(n.t.bind(n,4382,19)),"~docs/default/category-esdocs-tutorialsidebar-category-configuracion-b0f.json",4382],"34545dcf":[()=>n.e(8667).then(n.bind(n,2837)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/clickable-links.md",2837],"359fb69f":[()=>n.e(4685).then(n.bind(n,4706)),"@site/i18n/es/docusaurus-plugin-content-docs/current/intro.md",4706],"3a042459":[()=>n.e(2516).then(n.t.bind(n,7132,19)),"~blog/default/es-blog-tags-cwtch-stable-ad5.json",7132],"3a109bd3":[()=>n.e(7782).then(n.bind(n,877)),"@site/blog/2023-03-10-cwtch-documentation.md?truncated=true",877],"3ace3922":[()=>n.e(8974).then(n.t.bind(n,5670,19)),"~blog/default/es-blog-tags-reproducible-builds-96c-list.json",5670],"3ca9f026":[()=>n.e(8177).then(n.bind(n,808)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/overlays.md",808],"3cd9b44e":[()=>n.e(8186).then(n.t.bind(n,2332,19)),"~docs/docs-security/category-essecurity-tutorialsidebar-category-connectivity-tor-a8d.json",2332],"3db42865":[()=>n.e(7139).then(n.t.bind(n,3769,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"3ec42fa4":[()=>n.e(5583).then(n.bind(n,2947)),"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/testing.md",2947],"404e0e09":[()=>n.e(5703).then(n.bind(n,6569)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/introduction.md",6569],"43449e47":[()=>n.e(153).then(n.t.bind(n,4936,19)),"~docs/docs-developer/category-esdeveloping-tutorialsidebar-category-building-a-cwtch-app-02b.json",4936],"43b107c1":[()=>n.e(9200).then(n.bind(n,1168)),"@site/blog/2023-02-03-cwtch-testing-i.md",1168],"474a1a11":[()=>n.e(1825).then(n.t.bind(n,7240,19)),"~blog/default/es-blog-tags-api-987-list.json",7240],"4a6801a7":[()=>n.e(4697).then(n.t.bind(n,5367,19)),"~docs/docs-security/category-essecurity-tutorialsidebar-category-tapir-032.json",5367],"4aa555c3":[()=>n.e(7797).then(n.bind(n,3449)),"@site/blog/2023-06-16-cwtch-1.12.md?truncated=true",3449],"4d27f429":[()=>n.e(788).then(n.bind(n,7362)),"@site/blog/2023-01-20-reproducible-builds-bindings.md?truncated=true",7362],"4d4c5a31":[()=>n.e(6588).then(n.bind(n,5850)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/profile-info.md",5850],"4df29f52":[()=>n.e(4273).then(n.t.bind(n,6693,19)),"~blog/default/es-blog-tags-security-handbook-129-list.json",6693],"4f68bcc6":[()=>n.e(3516).then(n.t.bind(n,4289,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-security/plugin-route-context-module-100.json",4289],"511b7c07":[()=>n.e(724).then(n.bind(n,3483)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/intro.md",3483],"5181f1e2":[()=>n.e(26).then(n.bind(n,9418)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/key_bundles.md",9418],52564945:[()=>n.e(3787).then(n.bind(n,8897)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/importing-a-profile.md",8897],"53cc4802":[()=>n.e(7594).then(n.bind(n,3109)),"@site/blog/2023-02-03-cwtch-testing-i.md?truncated=true",3109],"54611c16":[()=>n.e(8031).then(n.bind(n,6613)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/behaviour/notification-content.md",6613],"559441ca":[()=>n.e(2682).then(n.bind(n,1407)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/introduction.md",1407],"5beee875":[()=>n.e(9444).then(n.bind(n,2724)),"@site/blog/2023-06-07-new-nightly.md",2724],"5ca95110":[()=>n.e(1121).then(n.t.bind(n,4680,19)),"~blog/default/es-blog-tags-developer-documentation-c83.json",4680],"5cb298ca":[()=>n.e(2909).then(n.bind(n,4673)),"@site/blog/2023-04-28-developer-docs.md?truncated=true",4673],"5dc151e9":[()=>n.e(923).then(n.bind(n,2320)),"@site/developing/release.md",2320],"5e5faacc":[()=>n.e(8192).then(n.bind(n,9655)),"@site/blog/2023-01-27-platform-support.md",9655],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"5ec66a01":[()=>n.e(3441).then(n.bind(n,666)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/behaviour/block-unknown-connections.md",666],"5f8a68fd":[()=>n.e(4138).then(n.t.bind(n,2595,19)),"~docs/default/category-esdocs-tutorialsidebar-category-conversations-b1c.json",2595],"60846aee":[()=>n.e(3337).then(n.bind(n,4557)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/image_previews.md",4557],61794344:[()=>n.e(6232).then(n.bind(n,4669)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",4669],"618f3057":[()=>n.e(433).then(n.bind(n,6901)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/message-formatting.md",6901],"6275ceb4":[()=>n.e(6555).then(n.bind(n,248)),"@site/blog/2023-03-10-cwtch-documentation.md",248],"64fc8eaf":[()=>n.e(2858).then(n.t.bind(n,3367,19)),"~blog/default/es-blog-tags-nightly-304.json",3367],"652ba846":[()=>n.e(4679).then(n.bind(n,8378)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/conversation-settings.md",8378],"66cb26f4":[()=>n.e(9453).then(n.bind(n,7447)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/input.md",7447],"6875c492":[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"6a78f460":[()=>n.e(439).then(n.bind(n,2982)),"@site/blog/2023-04-06-availability-and-profile-attributes.md",2982],"6ae2b8f9":[()=>n.e(3957).then(n.bind(n,2670)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/manage-known-servers.md",2670],"6bdc8c14":[()=>n.e(3775).then(n.bind(n,4155)),"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/translate.md",4155],"6d68d408":[()=>n.e(8330).then(n.bind(n,960)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/reply-to-message.md",960],"70a92a1e":[()=>n.e(7519).then(n.t.bind(n,8904,19)),"~blog/default/es-blog-tags-repliqate-b6c.json",8904],"72315c3e":[()=>n.e(5566).then(n.t.bind(n,7813,19)),"~blog/default/es-blog-tags-documentation-5f3.json",7813],"72ed38d2":[()=>n.e(9858).then(n.t.bind(n,2747,19)),"~docs/docs-security/category-essecurity-tutorialsidebar-category-cwtch-ui-96a.json",2747],"7a3564c1":[()=>n.e(9930).then(n.bind(n,7622)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/behaviour/notification-policy.md",7622],"7a4d337c":[()=>n.e(4170).then(n.t.bind(n,7500,19)),"~blog/default/es-blog-tags-autobindings-049.json",7500],"7ae36327":[()=>n.e(1949).then(n.bind(n,1496)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/light-dark-mode.md",1496],"7d7ca3f1":[()=>n.e(4398).then(n.bind(n,4158)),"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/unlock-server.md",4158],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],"81d88b95":[()=>n.e(490).then(n.bind(n,1276)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/introduction.md",1276],"824a28c6":[()=>n.e(5905).then(n.bind(n,9347)),"@site/developing/building-a-cwtch-app/intro.md",9347],86813741:[()=>n.e(6679).then(n.t.bind(n,2750,19)),"~blog/default/es-blog-tags-cwtch-page-2-6a4.json",2750],"86aebd6f":[()=>n.e(9599).then(n.t.bind(n,1754,19)),"~blog/default/es-blog-tags-security-handbook-129.json",1754],"89f86a37":[()=>n.e(9759).then(n.bind(n,9366)),"@site/blog/2023-03-29-cwtch-1.11.md?truncated=true",9366],"8a73259a":[()=>n.e(6162).then(n.t.bind(n,5046,19)),"~docs/default/category-esdocs-tutorialsidebar-category-comportamiento-86b.json",5046],"8df6de9b":[()=>n.e(9954).then(n.t.bind(n,3222,19)),"~blog/default/es-blog-tags-tags-cef.json",3222],"8eaa4178":[()=>n.e(6179).then(n.t.bind(n,1915,19)),"~docs/default/category-esdocs-tutorialsidebar-category-perfiles-f98.json",1915],"8fd5e00a":[()=>n.e(568).then(n.t.bind(n,4510,19)),"~blog/default/es-blog-047.json",4510],"8fe7a387":[()=>n.e(5233).then(n.bind(n,9667)),"@site/blog/2023-03-03-autobindings-optional-experiments.md",9667],91341964:[()=>n.e(3214).then(n.bind(n,3915)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/references.md",3915],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],94594657:[()=>n.e(5467).then(n.bind(n,897)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/qrcodes.md",897],"9479ba79":[()=>n.e(6433).then(n.bind(n,6320)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/risk.md",6320],"95c68178":[()=>n.e(6205).then(n.t.bind(n,3264,19)),"~blog/default/es-blog-archive-4d8.json",3264],"95f63404":[()=>n.e(7075).then(n.t.bind(n,1632,19)),"~docs/default/category-esdocs-tutorialsidebar-category-experiments-0d8.json",1632],"9af9bb9d":[()=>n.e(5841).then(n.t.bind(n,2707,19)),"~blog/default/es-blog-tags-release-5a4.json",2707],"9b12a270":[()=>n.e(9249).then(n.bind(n,9816)),"@site/blog/2023-02-10-android-reproducibility.md",9816],"9dd8190d":[()=>n.e(2688).then(n.bind(n,7561)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",7561],"9e2a7473":[()=>n.e(1258).then(n.bind(n,8725)),"@site/blog/2023-01-13-cwtch-stable-api-design.md",8725],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],"9ef77088":[()=>n.e(5602).then(n.t.bind(n,3308,19)),"~blog/default/es-blog-tags-planning-e48-list.json",3308],"9f1c7621":[()=>n.e(1312).then(n.bind(n,4387)),"@site/blog/2023-02-17-cwtch-testing-ii.md",4387],a02b4022:[()=>n.e(3492).then(n.bind(n,4889)),"@site/blog/2023-06-16-cwtch-1.12.md",4889],a65a3c47:[()=>n.e(7591).then(n.bind(n,5432)),"@site/blog/2023-04-28-developer-docs.md",5432],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(3089)]).then(n.bind(n,46)),"@theme/BlogListPage",46],a79c88c2:[()=>n.e(9976).then(n.bind(n,8553)),"@site/blog/2023-01-13-cwtch-stable-api-design.md?truncated=true",8553],a8c7fdc6:[()=>n.e(1602).then(n.t.bind(n,6454,19)),"~docs/docs-security/version-current-metadata-prop-751.json",6454],ac9aaa3f:[()=>n.e(6801).then(n.bind(n,5514)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/unblock-contact.md",5514],af23c5f9:[()=>n.e(3218).then(n.bind(n,4958)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",4958],af2fa732:[()=>n.e(6753).then(n.bind(n,7245)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/server-hosting.md",7245],af971761:[()=>n.e(7251).then(n.bind(n,1401)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/block-contact.md",1401],b0367817:[()=>n.e(8525).then(n.t.bind(n,429,19)),"~docs/default/category-esdocs-tutorialsidebar-category-platforms-44b.json",429],b0404c31:[()=>n.e(7860).then(n.bind(n,3478)),"@site/blog/2023-01-06-path-to-cwtch-stable.md",3478],b125d866:[()=>n.e(8799).then(n.bind(n,1595)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md?truncated=true",1595],b4165829:[()=>n.e(2033).then(n.bind(n,1646)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/accept-deny-new-conversation.md",1646],b4876842:[()=>n.e(6021).then(n.bind(n,7665)),"@site/i18n/es/docusaurus-plugin-content-docs/current/platforms/tails.md",7665],b77581fc:[()=>n.e(5004).then(n.bind(n,9267)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/delete-profile.md",9267],bb45cad0:[()=>n.e(908).then(n.bind(n,8157)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/experiments/file-sharing.md",8157],bcc84138:[()=>n.e(5103).then(n.bind(n,461)),"@site/i18n/es/docusaurus-plugin-content-docs/current/getting-started/supported_platforms.md",461],bdf5d676:[()=>n.e(5291).then(n.bind(n,6426)),"@site/i18n/es/docusaurus-plugin-content-docs/current/settings/appearance/change-language.md",6426],be9a5550:[()=>n.e(2279).then(n.bind(n,1091)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/save-conversation-history.md",1091],bf059cf9:[()=>n.e(5273).then(n.bind(n,2626)),"@site/blog/2023-02-10-android-reproducibility.md?truncated=true",2626],c14f15fd:[()=>n.e(7649).then(n.bind(n,3071)),"@site/developing/building-a-cwtch-app/core-concepts.md",3071],c21eb9f5:[()=>n.e(5910).then(n.t.bind(n,748,19)),"~blog/default/es-blog-tags-repliqate-b6c-list.json",748],c3ed911f:[()=>n.e(2091).then(n.bind(n,4977)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/tapir/authentication_protocol.md",4977],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,3261)),"@site/src/pages/index.js",3261],c521ebb9:[()=>n.e(1084).then(n.bind(n,2575)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ecosystem-overview.md",2575],c567d895:[()=>n.e(5986).then(n.bind(n,8082)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/groups.md",8082],c5e058ac:[()=>n.e(2017).then(n.bind(n,1755)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/message-formatting.md",1755],c688cd93:[()=>n.e(7264).then(n.bind(n,3042)),"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/delete-server.md",3042],c747432f:[()=>n.e(8835).then(n.bind(n,2090)),"@site/blog/2023-03-03-autobindings-optional-experiments.md?truncated=true",2090],c94c4dfb:[()=>n.e(9146).then(n.t.bind(n,4469,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],c953ad65:[()=>n.e(413).then(n.bind(n,1668)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/change-profile-image.md",1668],c96c5262:[()=>n.e(3761).then(n.bind(n,5426)),"@site/blog/2023-03-29-cwtch-1.11.md",5426],cbbc0b0f:[()=>n.e(9334).then(n.t.bind(n,2445,19)),"~blog/default/es-blog-tags-developer-documentation-c83-list.json",2445],ccc49370:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],cdd10d0d:[()=>n.e(2182).then(n.bind(n,2865)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/create-group.md",2865],ce68aa0f:[()=>n.e(9793).then(n.bind(n,9481)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/edit-group-name.md",9481],cf7ec223:[()=>n.e(8566).then(n.t.bind(n,8145,19)),"~docs/docs-security/category-essecurity-tutorialsidebar-category-cwtch-c97.json",8145],d3029be3:[()=>n.e(6520).then(n.bind(n,9837)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/deployment.md",9837],d5055ac4:[()=>n.e(8609).then(n.t.bind(n,3429,19)),"~blog/default/es-blog-tags-cwtch-stable-page-2-300.json",3429],d5f314f9:[()=>n.e(5869).then(n.t.bind(n,9317,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-developer/plugin-route-context-module-100.json",9317],d6981a76:[()=>n.e(5761).then(n.bind(n,8400)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/leave-group.md",8400],d6f4db7a:[()=>n.e(5401).then(n.t.bind(n,1765,19)),"~blog/default/es-blog-tags-nightly-304-list.json",1765],d7127c3b:[()=>n.e(9958).then(n.t.bind(n,4839,19)),"~blog/default/es-blog-tags-support-7f0-list.json",4839],d7b9dd5a:[()=>n.e(799).then(n.t.bind(n,7884,19)),"~blog/default/es-blog-tags-cwtch-dfb.json",7884],d7c28e69:[()=>n.e(1601).then(n.bind(n,6560)),"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/edit-server.md",6560],da0de98b:[()=>n.e(6774).then(n.t.bind(n,8514,19)),"~blog/default/es-blog-tags-testing-182-list.json",8514],daa83a73:[()=>n.e(5532).then(n.bind(n,8177)),"@site/i18n/es/docusaurus-plugin-content-docs/current/contribute/stickers.md",8177],dbc23903:[()=>n.e(411).then(n.bind(n,1593)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/exporting-profile.md",1593],dbda29f5:[()=>n.e(1434).then(n.bind(n,9102)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/availability-status.md",9102],dc4e6075:[()=>n.e(2023).then(n.t.bind(n,9818,19)),"~blog/default/es-blog-tags-documentation-5f3-list.json",9818],de3e8d19:[()=>n.e(3570).then(n.bind(n,3229)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/message_formats.md",3229],e0693172:[()=>n.e(2722).then(n.t.bind(n,1006,19)),"~blog/default/es-blog-tags-reproducible-builds-96c.json",1006],e20a62ae:[()=>n.e(2815).then(n.bind(n,8202)),"@site/i18n/es/docusaurus-plugin-content-docs/current/servers/create-server.md",8202],e2f5db39:[()=>n.e(6164).then(n.t.bind(n,732,19)),"~docs/docs-security/category-essecurity-tutorialsidebar-category-cwtch-components-69a.json",732],e48e682c:[()=>n.e(322).then(n.bind(n,8021)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/change-password.md",8021],e490445a:[()=>n.e(9765).then(n.t.bind(n,1917,19)),"~docs/default/category-esdocs-tutorialsidebar-category-apariencia-040.json",1917],e5c4909f:[()=>n.e(3077).then(n.t.bind(n,2046,19)),"~blog/default/es-blog-tags-api-987.json",2046],e88d32a9:[()=>n.e(6585).then(n.t.bind(n,5745,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],ea60411e:[()=>n.e(3405).then(n.bind(n,4528)),"@site/i18n/es/docusaurus-plugin-content-docs/current/profiles/create-a-profile.md",4528],ead134b2:[()=>n.e(8002).then(n.bind(n,9651)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/add-contact.md",9651],ebdc3447:[()=>n.e(283).then(n.bind(n,7736)),"@site/i18n/es/docusaurus-plugin-content-docs/current/chat/share-file.md",7736],ee1e10c4:[()=>n.e(7372).then(n.t.bind(n,6658,19)),"~blog/default/es-blog-tags-libcwtch-52a.json",6658],ef78badf:[()=>n.e(8922).then(n.bind(n,5481)),"@site/blog/2023-01-27-platform-support.md?truncated=true",5481],f041e880:[()=>n.e(5226).then(n.bind(n,3291)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md?truncated=true",3291],f384c30f:[()=>n.e(5760).then(n.bind(n,3627)),"@site/i18n/es/docusaurus-plugin-content-docs/current/groups/send-invite.md",3627],f53ef702:[()=>n.e(6017).then(n.t.bind(n,153,19)),"~docs/default/category-esdocs-tutorialsidebar-category-servers-853.json",153],f63f85fb:[()=>n.e(8537).then(n.bind(n,7101)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/development.md",7101],f6d09a50:[()=>n.e(8962).then(n.bind(n,4497)),"@site/i18n/es/docusaurus-plugin-content-docs-docs-security/current/components/ui/android.md",4497],f76a3b8e:[()=>n.e(2184).then(n.bind(n,3103)),"@site/blog/2023-02-17-cwtch-testing-ii.md?truncated=true",3103],f928e8d9:[()=>n.e(8786).then(n.t.bind(n,7160,19)),"~docs/docs-developer/version-current-metadata-prop-751.json",7160],fb3c1916:[()=>n.e(276).then(n.bind(n,8886)),"@site/developing/intro.md",8886],fcdd064d:[()=>n.e(8543).then(n.bind(n,4753)),"@site/i18n/es/docusaurus-plugin-content-docs/current/tor.md",4753],fd27e325:[()=>n.e(1199).then(n.bind(n,9327)),"@site/developing/building-a-cwtch-app/building-an-echobot.md",9327],fd33d4dc:[()=>n.e(1787).then(n.t.bind(n,7010,19)),"~blog/default/es-blog-tags-cwtch-page-2-6a4-list.json",7010],fdfd1857:[()=>n.e(1570).then(n.t.bind(n,9547,19)),"~docs/default/category-esdocs-tutorialsidebar-category-getting-started-e97.json",9547],fe1dd7ae:[()=>n.e(1979).then(n.bind(n,1501)),"@site/blog/2023-06-07-new-nightly.md?truncated=true",1501]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=s[`${e}-${t}`],p={},f=[],m=[],g=(0,u.Z)(o);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=l[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const s=n.split(".");s.slice(0,-1).forEach((e=>{o=o[e]})),o[s[s.length-1]]=a}));const s=i.__comp;delete i.__comp;const l=i.__context;return delete i.__context,r.createElement(d.z,{value:l},r.createElement(s,(0,a.Z)({},i,n)))}})}const f=[{path:"/es/blog",component:p("/es/blog","b72"),exact:!0},{path:"/es/blog/archive",component:p("/es/blog/archive","29b"),exact:!0},{path:"/es/blog/autobindings",component:p("/es/blog/autobindings","5ab"),exact:!0},{path:"/es/blog/autobindings-ii",component:p("/es/blog/autobindings-ii","b84"),exact:!0},{path:"/es/blog/availability-status-profile-attributes",component:p("/es/blog/availability-status-profile-attributes","688"),exact:!0},{path:"/es/blog/cwtch-android-reproducibility",component:p("/es/blog/cwtch-android-reproducibility","aa8"),exact:!0},{path:"/es/blog/cwtch-bindings-reproducible",component:p("/es/blog/cwtch-bindings-reproducible","d63"),exact:!0},{path:"/es/blog/cwtch-developer-documentation",component:p("/es/blog/cwtch-developer-documentation","0f0"),exact:!0},{path:"/es/blog/cwtch-documentation",component:p("/es/blog/cwtch-documentation","1b6"),exact:!0},{path:"/es/blog/cwtch-nightly-1-11",component:p("/es/blog/cwtch-nightly-1-11","597"),exact:!0},{path:"/es/blog/cwtch-nightly-1-12",component:p("/es/blog/cwtch-nightly-1-12","f37"),exact:!0},{path:"/es/blog/cwtch-nightly-v.11-74",component:p("/es/blog/cwtch-nightly-v.11-74","302"),exact:!0},{path:"/es/blog/cwtch-platform-support",component:p("/es/blog/cwtch-platform-support","a5e"),exact:!0},{path:"/es/blog/cwtch-stable-api-design",component:p("/es/blog/cwtch-stable-api-design","98d"),exact:!0},{path:"/es/blog/cwtch-stable-roadmap-update",component:p("/es/blog/cwtch-stable-roadmap-update","d51"),exact:!0},{path:"/es/blog/cwtch-stable-roadmap-update-june",component:p("/es/blog/cwtch-stable-roadmap-update-june","296"),exact:!0},{path:"/es/blog/cwtch-testing-i",component:p("/es/blog/cwtch-testing-i","e6c"),exact:!0},{path:"/es/blog/cwtch-testing-ii",component:p("/es/blog/cwtch-testing-ii","c00"),exact:!0},{path:"/es/blog/page/2",component:p("/es/blog/page/2","f76"),exact:!0},{path:"/es/blog/path-to-cwtch-stable",component:p("/es/blog/path-to-cwtch-stable","1d4"),exact:!0},{path:"/es/blog/tags",component:p("/es/blog/tags","699"),exact:!0},{path:"/es/blog/tags/api",component:p("/es/blog/tags/api","dad"),exact:!0},{path:"/es/blog/tags/autobindings",component:p("/es/blog/tags/autobindings","144"),exact:!0},{path:"/es/blog/tags/bindings",component:p("/es/blog/tags/bindings","b13"),exact:!0},{path:"/es/blog/tags/cwtch",component:p("/es/blog/tags/cwtch","976"),exact:!0},{path:"/es/blog/tags/cwtch-stable",component:p("/es/blog/tags/cwtch-stable","78e"),exact:!0},{path:"/es/blog/tags/cwtch-stable/page/2",component:p("/es/blog/tags/cwtch-stable/page/2","1c3"),exact:!0},{path:"/es/blog/tags/cwtch/page/2",component:p("/es/blog/tags/cwtch/page/2","9ce"),exact:!0},{path:"/es/blog/tags/developer-documentation",component:p("/es/blog/tags/developer-documentation","b2d"),exact:!0},{path:"/es/blog/tags/documentation",component:p("/es/blog/tags/documentation","6fa"),exact:!0},{path:"/es/blog/tags/libcwtch",component:p("/es/blog/tags/libcwtch","b51"),exact:!0},{path:"/es/blog/tags/nightly",component:p("/es/blog/tags/nightly","da6"),exact:!0},{path:"/es/blog/tags/planning",component:p("/es/blog/tags/planning","249"),exact:!0},{path:"/es/blog/tags/release",component:p("/es/blog/tags/release","caf"),exact:!0},{path:"/es/blog/tags/repliqate",component:p("/es/blog/tags/repliqate","f55"),exact:!0},{path:"/es/blog/tags/reproducible-builds",component:p("/es/blog/tags/reproducible-builds","d6a"),exact:!0},{path:"/es/blog/tags/security-handbook",component:p("/es/blog/tags/security-handbook","612"),exact:!0},{path:"/es/blog/tags/support",component:p("/es/blog/tags/support","ee7"),exact:!0},{path:"/es/blog/tags/testing",component:p("/es/blog/tags/testing","712"),exact:!0},{path:"/es/developing",component:p("/es/developing","041"),routes:[{path:"/es/developing/building-a-cwtch-app/building-an-echobot",component:p("/es/developing/building-a-cwtch-app/building-an-echobot","87f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/developing/building-a-cwtch-app/core-concepts",component:p("/es/developing/building-a-cwtch-app/core-concepts","e3b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/developing/building-a-cwtch-app/intro",component:p("/es/developing/building-a-cwtch-app/intro","b7a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/developing/category/building-a-cwtch-app",component:p("/es/developing/category/building-a-cwtch-app","8e8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/developing/intro",component:p("/es/developing/intro","25a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/developing/release",component:p("/es/developing/release","493"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/es/docs",component:p("/es/docs","9d0"),routes:[{path:"/es/docs/category/appearance",component:p("/es/docs/category/appearance","cb7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/behaviour",component:p("/es/docs/category/behaviour","9a3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/contribute",component:p("/es/docs/category/contribute","533"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/conversations",component:p("/es/docs/category/conversations","68a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/experiments",component:p("/es/docs/category/experiments","ca0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/getting-started",component:p("/es/docs/category/getting-started","0e6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/groups",component:p("/es/docs/category/groups","b91"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/platforms",component:p("/es/docs/category/platforms","0b6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/profiles",component:p("/es/docs/category/profiles","992"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/servers",component:p("/es/docs/category/servers","8a4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/category/settings",component:p("/es/docs/category/settings","784"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/accept-deny-new-conversation",component:p("/es/docs/chat/accept-deny-new-conversation","845"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/add-contact",component:p("/es/docs/chat/add-contact","bc2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/block-contact",component:p("/es/docs/chat/block-contact","838"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/conversation-settings",component:p("/es/docs/chat/conversation-settings","549"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/delete-contact",component:p("/es/docs/chat/delete-contact","303"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/introduction",component:p("/es/docs/chat/introduction","49e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/message-formatting",component:p("/es/docs/chat/message-formatting","759"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/reply-to-message",component:p("/es/docs/chat/reply-to-message","129"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/save-conversation-history",component:p("/es/docs/chat/save-conversation-history","7fa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/share-address-with-friends",component:p("/es/docs/chat/share-address-with-friends","123"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/share-file",component:p("/es/docs/chat/share-file","ac5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/chat/unblock-contact",component:p("/es/docs/chat/unblock-contact","3cc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/contribute/developing",component:p("/es/docs/contribute/developing","c8d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/contribute/documentation",component:p("/es/docs/contribute/documentation","c96"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/contribute/stickers",component:p("/es/docs/contribute/stickers","6ac"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/contribute/testing",component:p("/es/docs/contribute/testing","e1b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/contribute/translate",component:p("/es/docs/contribute/translate","733"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/getting-started/supported_platforms",component:p("/es/docs/getting-started/supported_platforms","108"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/accept-group-invite",component:p("/es/docs/groups/accept-group-invite","477"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/create-group",component:p("/es/docs/groups/create-group","026"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/edit-group-name",component:p("/es/docs/groups/edit-group-name","9a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/introduction",component:p("/es/docs/groups/introduction","260"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/leave-group",component:p("/es/docs/groups/leave-group","a8e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/manage-known-servers",component:p("/es/docs/groups/manage-known-servers","065"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/groups/send-invite",component:p("/es/docs/groups/send-invite","a91"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/intro",component:p("/es/docs/intro","98b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/platforms/tails",component:p("/es/docs/platforms/tails","3ca"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/availability-status",component:p("/es/docs/profiles/availability-status","c52"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/change-name",component:p("/es/docs/profiles/change-name","11d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/change-password",component:p("/es/docs/profiles/change-password","53d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/change-profile-image",component:p("/es/docs/profiles/change-profile-image","9c9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/create-a-profile",component:p("/es/docs/profiles/create-a-profile","e83"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/delete-profile",component:p("/es/docs/profiles/delete-profile","edf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/exporting-profile",component:p("/es/docs/profiles/exporting-profile","ce5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/importing-a-profile",component:p("/es/docs/profiles/importing-a-profile","f0e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/introduction",component:p("/es/docs/profiles/introduction","8da"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/profile-info",component:p("/es/docs/profiles/profile-info","99b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/profiles/unlock-profile",component:p("/es/docs/profiles/unlock-profile","283"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/servers/create-server",component:p("/es/docs/servers/create-server","aaf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/servers/delete-server",component:p("/es/docs/servers/delete-server","b73"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/servers/edit-server",component:p("/es/docs/servers/edit-server","69e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/servers/introduction",component:p("/es/docs/servers/introduction","668"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/servers/share-key",component:p("/es/docs/servers/share-key","351"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/servers/unlock-server",component:p("/es/docs/servers/unlock-server","1ee"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/appearance/change-language",component:p("/es/docs/settings/appearance/change-language","646"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/appearance/light-dark-mode",component:p("/es/docs/settings/appearance/light-dark-mode","e9c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/appearance/streamer-mode",component:p("/es/docs/settings/appearance/streamer-mode","ac2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/appearance/ui-columns",component:p("/es/docs/settings/appearance/ui-columns","2ba"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/behaviour/block-unknown-connections",component:p("/es/docs/settings/behaviour/block-unknown-connections","8d8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/behaviour/notification-content",component:p("/es/docs/settings/behaviour/notification-content","ad2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/behaviour/notification-policy",component:p("/es/docs/settings/behaviour/notification-policy","e34"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/clickable-links",component:p("/es/docs/settings/experiments/clickable-links","39b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/file-sharing",component:p("/es/docs/settings/experiments/file-sharing","fec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/group-experiment",component:p("/es/docs/settings/experiments/group-experiment","c4f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/image-previews-and-profile-pictures",component:p("/es/docs/settings/experiments/image-previews-and-profile-pictures","aa0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/message-formatting",component:p("/es/docs/settings/experiments/message-formatting","8fb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/qrcodes",component:p("/es/docs/settings/experiments/qrcodes","652"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/experiments/server-hosting",component:p("/es/docs/settings/experiments/server-hosting","7d6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/settings/introduction",component:p("/es/docs/settings/introduction","bb6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/docs/tor",component:p("/es/docs/tor","463"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/es/security",component:p("/es/security","204"),routes:[{path:"/es/security/category/connectivity--tor",component:p("/es/security/category/connectivity--tor","c78"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/category/cwtch",component:p("/es/security/category/cwtch","4bb"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/category/cwtch-components",component:p("/es/security/category/cwtch-components","915"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/category/cwtch-ui",component:p("/es/security/category/cwtch-ui","87f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/category/tapir",component:p("/es/security/category/tapir","1e5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/connectivity/intro",component:p("/es/security/components/connectivity/intro","78d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/cwtch/groups",component:p("/es/security/components/cwtch/groups","988"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/cwtch/key_bundles",component:p("/es/security/components/cwtch/key_bundles","123"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/cwtch/message_formats",component:p("/es/security/components/cwtch/message_formats","9ff"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/cwtch/server",component:p("/es/security/components/cwtch/server","bb3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/ecosystem-overview",component:p("/es/security/components/ecosystem-overview","4dd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/intro",component:p("/es/security/components/intro","627"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/tapir/authentication_protocol",component:p("/es/security/components/tapir/authentication_protocol","fd8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/tapir/packet_format",component:p("/es/security/components/tapir/packet_format","be9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/ui/android",component:p("/es/security/components/ui/android","33f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/ui/image_previews",component:p("/es/security/components/ui/image_previews","7b3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/ui/input",component:p("/es/security/components/ui/input","204"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/components/ui/overlays",component:p("/es/security/components/ui/overlays","fc0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/deployment",component:p("/es/security/deployment","9f5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/development",component:p("/es/security/development","48b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/intro",component:p("/es/security/intro","927"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/references",component:p("/es/security/references","8d7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/es/security/risk",component:p("/es/security/risk","a35"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/es/",component:p("/es/","926"),exact:!0},{path:"*",component:p("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),s=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),g=n(2263),h=n(4996),b=n(6668),v=n(1944),y=n(4711),w=n(9727),k=n(3320),S=n(197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),a=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,u.TH)();return e+(0,h.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function x(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(_,null),r.createElement(E,null),r.createElement(S.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),A=n(8940);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const a=l.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const R=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),P("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function N(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),N(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(R,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const I=O,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",j="__docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${j}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n var suggestionContainer = document.getElementById('${j}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function z(){const{siteConfig:{baseUrl:e}}=(0,g.Z)();return(0,r.useLayoutEffect)((()=>{window[F]=!1}),[]),r.createElement(r.Fragment,null,!s.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:D}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(z,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,g.Z)(),i=(0,h.Z)(e),{htmlLang:s,direction:l}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:s,dir:l}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var q=n(4763);function G(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(q.Z,null,r.createElement(A.M,null,r.createElement(L.t,null,r.createElement(p,null,r.createElement($,null),r.createElement(x,null),r.createElement(U,null),r.createElement(I,{location:T(t)},e)))))}var H=n(6887);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var V=n(9670);const W=new Set,Y=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!K()&&!Y.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(H).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!Y.has(e))(e)&&(Y.add(e),N(e))},X=Object.freeze(Q);if(s.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;N(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(G,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"docs-developer":{"path":"/es/developing","versions":[{"name":"current","label":"Next","isLast":true,"path":"/es/developing","mainDocId":"intro","docs":[{"id":"building-a-cwtch-app/building-an-echobot","path":"/es/developing/building-a-cwtch-app/building-an-echobot","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/core-concepts","path":"/es/developing/building-a-cwtch-app/core-concepts","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/intro","path":"/es/developing/building-a-cwtch-app/intro","sidebar":"tutorialSidebar"},{"id":"intro","path":"/es/developing/intro","sidebar":"tutorialSidebar"},{"id":"release","path":"/es/developing/release","sidebar":"tutorialSidebar"},{"id":"/category/building-a-cwtch-app","path":"/es/developing/category/building-a-cwtch-app","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/es/developing/intro","label":"intro"}}}}],"breadcrumbs":true},"default":{"path":"/es/docs","versions":[{"name":"current","label":"Siguiente","isLast":true,"path":"/es/docs","mainDocId":"intro","docs":[{"id":"chat/accept-deny-new-conversation","path":"/es/docs/chat/accept-deny-new-conversation","sidebar":"tutorialSidebar"},{"id":"chat/add-contact","path":"/es/docs/chat/add-contact","sidebar":"tutorialSidebar"},{"id":"chat/block-contact","path":"/es/docs/chat/block-contact","sidebar":"tutorialSidebar"},{"id":"chat/conversation-settings","path":"/es/docs/chat/conversation-settings","sidebar":"tutorialSidebar"},{"id":"chat/delete-contact","path":"/es/docs/chat/delete-contact","sidebar":"tutorialSidebar"},{"id":"chat/introduction","path":"/es/docs/chat/introduction","sidebar":"tutorialSidebar"},{"id":"chat/message-formatting","path":"/es/docs/chat/message-formatting","sidebar":"tutorialSidebar"},{"id":"chat/reply-to-message","path":"/es/docs/chat/reply-to-message","sidebar":"tutorialSidebar"},{"id":"chat/save-conversation-history","path":"/es/docs/chat/save-conversation-history","sidebar":"tutorialSidebar"},{"id":"chat/share-address-with-friends","path":"/es/docs/chat/share-address-with-friends","sidebar":"tutorialSidebar"},{"id":"chat/share-file","path":"/es/docs/chat/share-file","sidebar":"tutorialSidebar"},{"id":"chat/unblock-contact","path":"/es/docs/chat/unblock-contact","sidebar":"tutorialSidebar"},{"id":"contribute/developing","path":"/es/docs/contribute/developing","sidebar":"tutorialSidebar"},{"id":"contribute/documentation","path":"/es/docs/contribute/documentation","sidebar":"tutorialSidebar"},{"id":"contribute/stickers","path":"/es/docs/contribute/stickers","sidebar":"tutorialSidebar"},{"id":"contribute/testing","path":"/es/docs/contribute/testing","sidebar":"tutorialSidebar"},{"id":"contribute/translate","path":"/es/docs/contribute/translate","sidebar":"tutorialSidebar"},{"id":"getting-started/supported_platforms","path":"/es/docs/getting-started/supported_platforms","sidebar":"tutorialSidebar"},{"id":"groups/accept-group-invite","path":"/es/docs/groups/accept-group-invite","sidebar":"tutorialSidebar"},{"id":"groups/create-group","path":"/es/docs/groups/create-group","sidebar":"tutorialSidebar"},{"id":"groups/edit-group-name","path":"/es/docs/groups/edit-group-name","sidebar":"tutorialSidebar"},{"id":"groups/introduction","path":"/es/docs/groups/introduction","sidebar":"tutorialSidebar"},{"id":"groups/leave-group","path":"/es/docs/groups/leave-group","sidebar":"tutorialSidebar"},{"id":"groups/manage-known-servers","path":"/es/docs/groups/manage-known-servers","sidebar":"tutorialSidebar"},{"id":"groups/send-invite","path":"/es/docs/groups/send-invite","sidebar":"tutorialSidebar"},{"id":"intro","path":"/es/docs/intro","sidebar":"tutorialSidebar"},{"id":"platforms/tails","path":"/es/docs/platforms/tails","sidebar":"tutorialSidebar"},{"id":"profiles/availability-status","path":"/es/docs/profiles/availability-status","sidebar":"tutorialSidebar"},{"id":"profiles/change-name","path":"/es/docs/profiles/change-name","sidebar":"tutorialSidebar"},{"id":"profiles/change-password","path":"/es/docs/profiles/change-password","sidebar":"tutorialSidebar"},{"id":"profiles/change-profile-image","path":"/es/docs/profiles/change-profile-image","sidebar":"tutorialSidebar"},{"id":"profiles/create-a-profile","path":"/es/docs/profiles/create-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/delete-profile","path":"/es/docs/profiles/delete-profile","sidebar":"tutorialSidebar"},{"id":"profiles/exporting-profile","path":"/es/docs/profiles/exporting-profile","sidebar":"tutorialSidebar"},{"id":"profiles/importing-a-profile","path":"/es/docs/profiles/importing-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/introduction","path":"/es/docs/profiles/introduction","sidebar":"tutorialSidebar"},{"id":"profiles/profile-info","path":"/es/docs/profiles/profile-info","sidebar":"tutorialSidebar"},{"id":"profiles/unlock-profile","path":"/es/docs/profiles/unlock-profile","sidebar":"tutorialSidebar"},{"id":"servers/create-server","path":"/es/docs/servers/create-server","sidebar":"tutorialSidebar"},{"id":"servers/delete-server","path":"/es/docs/servers/delete-server","sidebar":"tutorialSidebar"},{"id":"servers/edit-server","path":"/es/docs/servers/edit-server","sidebar":"tutorialSidebar"},{"id":"servers/introduction","path":"/es/docs/servers/introduction","sidebar":"tutorialSidebar"},{"id":"servers/share-key","path":"/es/docs/servers/share-key","sidebar":"tutorialSidebar"},{"id":"servers/unlock-server","path":"/es/docs/servers/unlock-server","sidebar":"tutorialSidebar"},{"id":"settings/appearance/change-language","path":"/es/docs/settings/appearance/change-language","sidebar":"tutorialSidebar"},{"id":"settings/appearance/light-dark-mode","path":"/es/docs/settings/appearance/light-dark-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/streamer-mode","path":"/es/docs/settings/appearance/streamer-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/ui-columns","path":"/es/docs/settings/appearance/ui-columns","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/block-unknown-connections","path":"/es/docs/settings/behaviour/block-unknown-connections","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-content","path":"/es/docs/settings/behaviour/notification-content","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-policy","path":"/es/docs/settings/behaviour/notification-policy","sidebar":"tutorialSidebar"},{"id":"settings/experiments/clickable-links","path":"/es/docs/settings/experiments/clickable-links","sidebar":"tutorialSidebar"},{"id":"settings/experiments/file-sharing","path":"/es/docs/settings/experiments/file-sharing","sidebar":"tutorialSidebar"},{"id":"settings/experiments/group-experiment","path":"/es/docs/settings/experiments/group-experiment","sidebar":"tutorialSidebar"},{"id":"settings/experiments/image-previews-and-profile-pictures","path":"/es/docs/settings/experiments/image-previews-and-profile-pictures","sidebar":"tutorialSidebar"},{"id":"settings/experiments/message-formatting","path":"/es/docs/settings/experiments/message-formatting","sidebar":"tutorialSidebar"},{"id":"settings/experiments/qrcodes","path":"/es/docs/settings/experiments/qrcodes","sidebar":"tutorialSidebar"},{"id":"settings/experiments/server-hosting","path":"/es/docs/settings/experiments/server-hosting","sidebar":"tutorialSidebar"},{"id":"settings/introduction","path":"/es/docs/settings/introduction","sidebar":"tutorialSidebar"},{"id":"tor","path":"/es/docs/tor","sidebar":"tutorialSidebar"},{"id":"/category/getting-started","path":"/es/docs/category/getting-started","sidebar":"tutorialSidebar"},{"id":"/category/profiles","path":"/es/docs/category/profiles","sidebar":"tutorialSidebar"},{"id":"/category/conversations","path":"/es/docs/category/conversations","sidebar":"tutorialSidebar"},{"id":"/category/groups","path":"/es/docs/category/groups","sidebar":"tutorialSidebar"},{"id":"/category/servers","path":"/es/docs/category/servers","sidebar":"tutorialSidebar"},{"id":"/category/settings","path":"/es/docs/category/settings","sidebar":"tutorialSidebar"},{"id":"/category/appearance","path":"/es/docs/category/appearance","sidebar":"tutorialSidebar"},{"id":"/category/behaviour","path":"/es/docs/category/behaviour","sidebar":"tutorialSidebar"},{"id":"/category/experiments","path":"/es/docs/category/experiments","sidebar":"tutorialSidebar"},{"id":"/category/contribute","path":"/es/docs/category/contribute","sidebar":"tutorialSidebar"},{"id":"/category/platforms","path":"/es/docs/category/platforms","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/es/docs/intro","label":"intro"}}}}],"breadcrumbs":true},"docs-security":{"path":"/es/security","versions":[{"name":"current","label":"Next","isLast":true,"path":"/es/security","mainDocId":"intro","docs":[{"id":"components/connectivity/intro","path":"/es/security/components/connectivity/intro","sidebar":"tutorialSidebar"},{"id":"components/cwtch/groups","path":"/es/security/components/cwtch/groups","sidebar":"tutorialSidebar"},{"id":"components/cwtch/key_bundles","path":"/es/security/components/cwtch/key_bundles","sidebar":"tutorialSidebar"},{"id":"components/cwtch/message_formats","path":"/es/security/components/cwtch/message_formats","sidebar":"tutorialSidebar"},{"id":"components/cwtch/server","path":"/es/security/components/cwtch/server","sidebar":"tutorialSidebar"},{"id":"components/ecosystem-overview","path":"/es/security/components/ecosystem-overview","sidebar":"tutorialSidebar"},{"id":"components/intro","path":"/es/security/components/intro","sidebar":"tutorialSidebar"},{"id":"components/tapir/authentication_protocol","path":"/es/security/components/tapir/authentication_protocol","sidebar":"tutorialSidebar"},{"id":"components/tapir/packet_format","path":"/es/security/components/tapir/packet_format","sidebar":"tutorialSidebar"},{"id":"components/ui/android","path":"/es/security/components/ui/android","sidebar":"tutorialSidebar"},{"id":"components/ui/image_previews","path":"/es/security/components/ui/image_previews","sidebar":"tutorialSidebar"},{"id":"components/ui/input","path":"/es/security/components/ui/input","sidebar":"tutorialSidebar"},{"id":"components/ui/overlays","path":"/es/security/components/ui/overlays","sidebar":"tutorialSidebar"},{"id":"deployment","path":"/es/security/deployment","sidebar":"tutorialSidebar"},{"id":"development","path":"/es/security/development","sidebar":"tutorialSidebar"},{"id":"intro","path":"/es/security/intro","sidebar":"tutorialSidebar"},{"id":"references","path":"/es/security/references","sidebar":"tutorialSidebar"},{"id":"risk","path":"/es/security/risk","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-components","path":"/es/security/category/cwtch-components","sidebar":"tutorialSidebar"},{"id":"/category/connectivity--tor","path":"/es/security/category/connectivity--tor","sidebar":"tutorialSidebar"},{"id":"/category/tapir","path":"/es/security/category/tapir","sidebar":"tutorialSidebar"},{"id":"/category/cwtch","path":"/es/security/category/cwtch","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-ui","path":"/es/security/category/cwtch-ui","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/es/security/intro","label":"intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en","es","de","it"],"path":"i18n","currentLocale":"es","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"},"es":{"label":"Espa\xf1ol","direction":"ltr","htmlLang":"es","calendar":"gregory","path":"es"},"de":{"label":"Deutsch","direction":"ltr","htmlLang":"de","calendar":"gregory","path":"de"},"it":{"label":"Italiano","direction":"ltr","htmlLang":"it","calendar":"gregory","path":"it"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"}}}'),c={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(412),o=n(5742),i=n(8780),s=n(7961);function l(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(p,{fallback:()=>r.createElement(l,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(s.Z,null,r.createElement(l,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),s=n(2263),l=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,s.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,a.useContext)(u),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const _=p||f;const x=(0,l.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(L=C,b&&(e=>e.startsWith("/"))(L)?k(L):L):void 0;var L;T&&x&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const A=(0,a.useRef)(!1),P=n?o.OL:o.rU,R=c.Z.canUseIntersectionObserver,N=(0,a.useRef)(),O=()=>{A.current||null==T||(window.docusaurus.preload(T),A.current=!0)};(0,a.useEffect)((()=>(!R&&x&&null!=T&&window.docusaurus.prefetch(T),()=>{R&&N.current&&N.current.disconnect()})),[N,T,R,x]);const I=T?.startsWith("#")??!1,D=!T||!x||I;return D||h||S.collectLink(T),D?a.createElement("a",(0,r.Z)({ref:E,href:T},_&&!x&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(P,(0,r.Z)({},v,{onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,R&&e&&x&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T},n&&{isActive:g,activeClassName:m}))}const f=a.forwardRef(p)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>s});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const s=i({message:t,id:n});return r.createElement(r.Fragment,null,a(s,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>g,gA:()=>p,_r:()=>u,Jo:()=>h,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=function(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return s(t)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return l(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7961:(e,t,n)=>{"use strict";n.d(t,{Z:()=>dt});var r=n(7294),a=n(6010),o=n(4763),i=n(1944),s=n(7462),l=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,l.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??m,{containerRef:n,onClick:a}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,s.Z)({},e,{href:`#${d}`,onClick:a}),t))}var h=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(g,{className:v.skipToContent})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...l}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E={closeButton:"closeButton_CVFx"};function _(e){return r.createElement("button",(0,s.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",E.closeButton,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const x={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,s.Z)({},e,{className:(0,a.Z)(x.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(_,{onClick:n,className:T.announcementBarClose}))}var A=n(2961),P=n(2466);var R=n(902),N=n(3102);const O=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,N.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,R.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(O.Provider,{value:n},t)}function D(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(O);if(!e)throw new R.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:D(o)})),[a,o,t])}function j(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var F=n(2949),B=n(2389);function z(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const s=(0,B.Z)(),l=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!s&&$.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!s,title:l,"aria-label":l,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const G=r.memo(q),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,F.I)();return a?null:r.createElement(G,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return r.createElement(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,A.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(Y,null))}var Q=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:l,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,X.Z)(a),f=(0,X.Z)(t),m=(0,X.Z)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,J.Z)(o),h=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,i,g&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(Q.Z,(0,s.Z)({href:u?m:o},d,h)):r.createElement(Q.Z,(0,s.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},d,h))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,s.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,s.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,s.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),se=n(8596),le=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...l}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,s.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:l.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),l.children??l.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(_e,(0,s.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(ne,(0,s.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(_e,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var fe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ge="iconLanguage_nlXk";var he=n(1875);const be={searchBox:"searchBox_ZlJk"};function ve(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,be.searchBox)},t)}var ye=n(143),we=n(2802);var ke=n(373);const Se=e=>e.docs.find((t=>t.id===e.mainDocId));const Ee={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,le.Z)(),p=(0,fe.l)(),{search:f,hash:m}=(0,l.TH)(),g=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(pe,(0,s.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:ge}),h),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(ve,{className:n},r.createElement(he.Z,null))},dropdown:pe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const s=i?"li":"div";return r.createElement(s,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),l=(0,we.vY)(t,a);return null===l?null:r.createElement(oe,(0,s.Z)({exact:!0},o,{isActive:()=>i?.path===l.path||!!i?.sidebar&&i.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),l=(0,we.oz)(t,a).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,s.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,we.lO)(a)[0],l=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,s.Z)({},o,{label:l,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:p}=(0,l.TH)(),f=(0,ye.Iw)(n),m=(0,ye.gB)(n),{savePreferredVersionName:g}=(0,ke.J)(n),h=[...o,...m.map((e=>{const t=f.alternateDocVersions[e.name]??Se(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>g(e.name)}})),...i],b=(0,we.lO)(n)[0],v=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:Se(b).path;return h.length<=1?r.createElement(oe,(0,s.Z)({},u,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(pe,(0,s.Z)({},u,{mobile:t,label:v,to:y,items:h,isActive:a?()=>!1:void 0}))}};function _e(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function xe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(_e,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ce(e){return r.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Te(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ce,{onClick:()=>t.hide()}),t.content)}function Le(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(j,{header:r.createElement(K,null),primaryMenu:r.createElement(xe,null),secondaryMenu:r.createElement(Te,null)}):null}const Ae={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return r.createElement("div",(0,s.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Re(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:s,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(a.current)return void(a.current=!1);const s=r?.scrollY,l=document.documentElement.scrollHeight-o.current,c=window.innerHeight;s&&i>=s?n(!1):i+c<l&&n(!0)})),(0,u.S)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:s,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ae.navbarHideable,!l&&Ae.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Pe,{onClick:i.toggle}),r.createElement(Le,null))}var Ne=n(8780);const Oe={errorBoundaryError:"errorBoundaryError_a6uf"};function Ie(e){return r.createElement("button",(0,s.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function De(e){let{error:t}=e;const n=(0,Ne.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:Oe.errorBoundaryError},n)}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const je="right";function Fe(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,s.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Be(){const{toggle:e,shown:t}=(0,A.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Fe,null))}const ze={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Me,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(_e,e)))))}function $e(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function qe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??je)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement($e,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Be,null),r.createElement(W,null),r.createElement(Ue,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ue,{items:a}),r.createElement(Z,{className:ze.colorModeToggle}),!o&&r.createElement(ve,null,r.createElement(he.Z,null)))})}function Ge(){return r.createElement(Re,null,r.createElement(qe,null))}function He(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...l}=t,c=(0,X.Z)(n),u=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Q.Z,(0,s.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},l),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function Ze(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(He,{item:t}))}function Ve(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Ze,{key:t,item:e})))))}function We(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Ve,{key:t,column:e}))))}function Ye(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Ke(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(He,{item:t})}function Qe(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Ke,{item:e}),t.length!==n+1&&r.createElement(Ye,null))))))}function Xe(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(We,{columns:t}):r.createElement(Qe,{links:t})}var Je=n(941);const et={footerLogoLink:"footerLogoLink_BH7S"};function tt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Je.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function nt(e){let{logo:t}=e;return t.href?r.createElement(Q.Z,{href:t.href,className:et.footerLogoLink,target:t.target},r.createElement(tt,{logo:t})):r.createElement(tt,{logo:t})}function rt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function ot(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(at,{style:o,links:n&&n.length>0&&r.createElement(Xe,{links:n}),logo:a&&r.createElement(nt,{logo:a}),copyright:t&&r.createElement(rt,{copyright:t})})}const it=r.memo(ot),st=(0,R.Qc)([F.S,k.pl,P.OC,ke.L5,i.VC,function(e){let{children:t}=e;return r.createElement(N.n2,null,r.createElement(A.M,null,r.createElement(I,null,t)))}]);function lt(e){let{children:t}=e;return r.createElement(st,null,t)}function ct(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Ie,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(De,{error:t})))))}const ut={mainWrapper:"mainWrapper_z2l0"};function dt(e){const{children:t,noFooter:n,wrapperClassName:s,title:l,description:c}=e;return(0,b.t)(),r.createElement(lt,null,r.createElement(i.d,{title:l,description:c}),r.createElement(y,null),r.createElement(L,null),r.createElement(Ge,null),r.createElement("div",{id:d,className:(0,a.Z)(h.k.wrapper.main,ut.mainWrapper,s)},r.createElement(o.Z,{fallback:e=>r.createElement(ct,e)},t)),!n&&r.createElement(it,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),s=n(2263),l=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},s=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},s):s}function d(e){const{siteConfig:{title:t}}=(0,s.Z)(),{navbar:{title:n,logo:c}}=(0,l.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(c?.href||"/"),g=n?"":t,h=c?.alt??g;return a.createElement(o.Z,(0,r.Z)({to:m},f,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:h,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),s=n(2949);const l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,s.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(l.themedImage,l[`themedImage--${e}`],u)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>l,z:()=>h});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const s="ease-in-out";function l(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??s}`,height:`${t}px`}}function l(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?c:u}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:s,disableSSRStyle:l}=e;const c=(0,a.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:l?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:s},r)}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[s,l]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&l(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:s})):null}function h(e){let{lazy:t,...n}=e;const r=t?g:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),a=n(2389),o=n(12),i=n(902),s=n(6668);const l=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===l.get(),d=e=>l.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),s=n(6668);const l=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(l.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(l);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>h});var r=n(7294),a=n(143),o=n(9935),i=n(6668),s=n(2802),l=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function h(e){let{children:t}=e;return s.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(f);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>s});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function s(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function l(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>s,q:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(o.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(o);if(null===e)throw new a.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),s=(n(1688),n(902));function l(e){!function(e){const t=(0,i.k6)(),n=(0,s.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,s]=(0,r.useState)(!1);l((()=>{if(i)return s(!1),!1}));const u=(0,r.useCallback)((()=>{s((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&s(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>l,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=i,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const l=!1;function c(){const[e,t]=(0,r.useState)((()=>l?"ssr":s()));return(0,r.useEffect)((()=>{function e(){t(s())}const n=l?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>x,Wl:()=>m,_F:()=>v,cE:()=>p,jA:()=>g,xz:()=>f,hI:()=>_,lO:()=>k,vY:()=>E,oz:()=>S,s1:()=>w});var r=n(7294),a=n(6550),o=n(8790),i=n(143),s=n(373),l=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!i._r;function f(e){const t=(0,l.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,a.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>v(e,t)));function v(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||b(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function w(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function S(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,s=i.find((e=>(0,a.LX)(r.pathname,e)));if(!s)return null;const l=s.sidebar,c=l?n.docsSidebars[l]:void 0;return{docElement:(0,o.H)(i),sidebarName:l,sidebarItems:c}}function x(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),c=n(2263);function u(e){let{title:t,description:n,keywords:a,image:i,children:s}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),s)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:s},r.createElement(o.Z,null,r.createElement("html",{className:s})),n)}function f(e){let{children:t}=e;const n=s(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>l,i6:()=>s,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>l,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const s=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(s.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&a<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(a-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>l});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),s=o===n?e:e.replace(`/${o}/`,"/"),l=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${s}`:`${s}${e}/`}(r)}${l}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(a&&(a+=" "),a+=n);else for(t in e)e[t]&&(a&&(a+=" "),a+=t);return a}n.d(t,{Z:()=>a});const a=function(){for(var e,t,n=0,a="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(a&&(a+=" "),a+=t);return a}},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>L,Ep:()=>p});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r<a;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],s=e&&a(e),l=t&&a(t),c=s||l;if(e&&a(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=i.length;p>=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(2177);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var g=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",v="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),g||(0,s.Z)(!1);var t,n=window.history,a=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,c=i.forceRefresh,w=void 0!==c&&c,k=i.getUserConfirmation,S=void 0===k?h:k,E=i.keyLength,_=void 0===E?6:E,x=e.basename?d(l(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,a=window.location,o=a.pathname+a.search+a.hash;return x&&(o=u(o,x)),f(o,r,n)}function T(){return Math.random().toString(36).substr(2,_)}var L=m();function A(e){(0,r.Z)(U,e),U.length=n.length,L.notifyListeners(U.location,U.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||O(C(e.state))}function R(){O(C(y()))}var N=!1;function O(e){if(N)N=!1,A();else{L.confirmTransitionTo(e,"POP",S,(function(t){t?A({action:"POP",location:e}):function(e){var t=U.location,n=D.indexOf(t.key);-1===n&&(n=0);var r=D.indexOf(e.key);-1===r&&(r=0);var a=n-r;a&&(N=!0,j(a))}(e)}))}}var I=C(y()),D=[I.key];function M(e){return x+p(e)}function j(e){n.go(e)}var F=0;function B(e){1===(F+=e)&&1===e?(window.addEventListener(b,P),o&&window.addEventListener(v,R)):0===F&&(window.removeEventListener(b,P),o&&window.removeEventListener(v,R))}var z=!1;var U={length:n.length,action:"POP",location:I,createHref:M,push:function(e,t){var r="PUSH",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,s=o.state;if(a)if(n.pushState({key:i,state:s},null,t),w)window.location.href=t;else{var l=D.indexOf(U.location.key),c=D.slice(0,l+1);c.push(o.key),D=c,A({action:r,location:o})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,s=o.state;if(a)if(n.replaceState({key:i,state:s},null,t),w)window.location.replace(t);else{var l=D.indexOf(U.location.key);-1!==l&&(D[l]=o.key),A({action:r,location:o})}else window.location.replace(t)}}))},go:j,goBack:function(){j(-1)},goForward:function(){j(1)},block:function(e){void 0===e&&(e=!1);var t=L.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=L.appendListener(e);return B(1),function(){B(-1),t()}}};return U}var k="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+c(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:c,decodePath:l},slash:{encodePath:l,decodePath:l}};function E(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function _(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function x(e){window.location.replace(E(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),g||(0,s.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),a=n.getUserConfirmation,o=void 0===a?h:a,i=n.hashType,c=void 0===i?"slash":i,b=e.basename?d(l(e.basename)):"",v=S[c],y=v.encodePath,w=v.decodePath;function C(){var e=w(_());return b&&(e=u(e,b)),f(e)}var T=m();function L(e){(0,r.Z)(z,e),z.length=t.length,T.notifyListeners(z.location,z.action)}var A=!1,P=null;function R(){var e,t,n=_(),r=y(n);if(n!==r)x(r);else{var a=C(),i=z.location;if(!A&&(t=a,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===p(a))return;P=null,function(e){if(A)A=!1,L();else{var t="POP";T.confirmTransitionTo(e,t,o,(function(n){n?L({action:t,location:e}):function(e){var t=z.location,n=D.lastIndexOf(p(t));-1===n&&(n=0);var r=D.lastIndexOf(p(e));-1===r&&(r=0);var a=n-r;a&&(A=!0,M(a))}(e)}))}}(a)}}var N=_(),O=y(N);N!==O&&x(O);var I=C(),D=[p(I)];function M(e){t.go(e)}var j=0;function F(e){1===(j+=e)&&1===e?window.addEventListener(k,R):0===j&&window.removeEventListener(k,R)}var B=!1;var z={length:t.length,action:"POP",location:I,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=E(window.location.href)),n+"#"+y(b+p(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);if(_()!==a){P=t,function(e){window.location.hash=e}(a);var o=D.lastIndexOf(p(z.location)),i=D.slice(0,o+1);i.push(t),D=i,L({action:n,location:r})}else L()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);_()!==a&&(P=t,x(a));var o=D.indexOf(p(z.location));-1!==o&&(D[o]=t),L({action:n,location:r})}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return B||(F(1),B=!0),function(){return B&&(B=!1,F(-1)),t()}},listen:function(e){var t=T.appendListener(e);return F(1),function(){F(-1),t()}}};return z}function T(e,t,n){return Math.min(Math.max(e,t),n)}function L(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,a=t.initialEntries,o=void 0===a?["/"]:a,i=t.initialIndex,s=void 0===i?0:i,l=t.keyLength,c=void 0===l?6:l,u=m();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function g(){return Math.random().toString(36).substr(2,c)}var h=T(s,0,o.length-1),b=o.map((function(e){return f(e,void 0,"string"==typeof e?g():e.key||g())})),v=p;function y(e){var t=T(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:v,push:function(e,t){var r="PUSH",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),g=l(n),h=0;h<i.length;++h){var b=i[h];if(!(o[b]||r&&r[b]||g&&g[b]||s&&s[b])){var v=p(n,b);try{c(t,b,v)}catch(y){}}}}return t}},1143:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function a(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,s=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l<arguments.length;l++){for(var c in o=Object(arguments[l]))n.call(o,c)&&(s[c]=o[c]);if(t){i=t(o);for(var u=0;u<i.length;u++)r.call(o,i[u])&&(s[i[u]]=o[i[u]])}}return s}},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(i,f),i=f+d.length,p)s+=p[1];else{var m=e[i],g=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];s&&(r.push(s),s="");var k=null!=g&&null!=m&&m!==g,S="+"===y||"*"===y,E="?"===y||"*"===y,_=n[2]||u,x=b||v;r.push({name:h||o++,prefix:g||"",delimiter:_,optional:E,repeat:S,partial:k,asterisk:!!w,pattern:x?c(x):w?".*":"[^"+l(_)+"]+?"})}}return i<e.length&&(s+=e.substr(i)),s&&r.push(s),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),a=0;a<e.length;a++)"object"==typeof e[a]&&(n[a]=new RegExp("^(?:"+e[a].pattern+")$",d(t)));return function(t,a){for(var o="",s=t||{},l=(a||{}).pretty?i:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=s[u.name];if(null==p){if(u.optional){u.partial&&(o+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(r(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=l(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):l(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');o+=u.prefix+d}}else o+=u}return o}}function l(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var a=(n=n||{}).strict,o=!1!==n.end,i="",s=0;s<e.length;s++){var c=e[s];if("string"==typeof c)i+=l(c);else{var p=l(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),i+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var m=l(n.delimiter||"/"),g=i.slice(-m.length)===m;return a||(i=(g?i.slice(0,-m.length):i)+"(?:"+m+"(?=$))?"),i+=o?"$":a&&g?"":"(?="+m+"|$)",u(new RegExp("^"+i,d(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],a=0;a<e.length;a++)r.push(f(e[a],t,n).source);return u(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},7410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var a,o;switch(n=n||{},r.util.type(t)){case"Object":if(o=r.util.objId(t),n[o])return n[o];for(var i in a={},n[o]=a,t)t.hasOwnProperty(i)&&(a[i]=e(t[i],n));return a;case"Array":return o=r.util.objId(t),n[o]?n[o]:(a=[],n[o]=a,t.forEach((function(t,r){a[r]=e(t,n)})),a);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var a in t)n[a]=t[a];return n},insertBefore:function(e,t,n,a){var o=(a=a||r.languages)[e],i={};for(var s in o)if(o.hasOwnProperty(s)){if(s==t)for(var l in n)n.hasOwnProperty(l)&&(i[l]=n[l]);n.hasOwnProperty(s)||(i[s]=o[s])}var c=a[e];return a[e]=i,r.languages.DFS(r.languages,(function(t,n){n===c&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,a,o){o=o||{};var i=r.util.objId;for(var s in t)if(t.hasOwnProperty(s)){n.call(t,s,t[s],a||s);var l=t[s],c=r.util.type(l);"Object"!==c||o[i(l)]?"Array"!==c||o[i(l)]||(o[i(l)]=!0,e(l,n,s,o)):(o[i(l)]=!0,e(l,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};return r.hooks.run("before-tokenize",o),o.tokens=r.tokenize(o.code,o.grammar),r.hooks.run("after-tokenize",o),a.stringify(r.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var a=new s;return l(a,a.head,e),i(e,a,t,a.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(a)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var a,o=0;a=n[o++];)a(t)}},Token:a};function a(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function o(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var o=a[1].length;a.index+=o,a[0]=a[0].slice(o)}return a}function i(e,t,n,s,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(d&&d.cause==p+","+m)return;var g=f[m],h=g.inside,b=!!g.lookbehind,v=!!g.greedy,y=g.alias;if(v&&!g.pattern.global){var w=g.pattern.toString().match(/[imsuy]*$/)[0];g.pattern=RegExp(g.pattern.source,w+"g")}for(var k=g.pattern||g,S=s.next,E=u;S!==t.tail&&!(d&&E>=d.reach);E+=S.value.length,S=S.next){var _=S.value;if(t.length>e.length)return;if(!(_ instanceof a)){var x,C=1;if(v){if(!(x=o(k,E,e,b))||x.index>=e.length)break;var T=x.index,L=x.index+x[0].length,A=E;for(A+=S.value.length;T>=A;)A+=(S=S.next).value.length;if(E=A-=S.value.length,S.value instanceof a)continue;for(var P=S;P!==t.tail&&(A<L||"string"==typeof P.value);P=P.next)C++,A+=P.value.length;C--,_=e.slice(E,A),x.index-=E}else if(!(x=o(k,0,_,b)))continue;T=x.index;var R=x[0],N=_.slice(0,T),O=_.slice(T+R.length),I=E+_.length;d&&I>d.reach&&(d.reach=I);var D=S.prev;if(N&&(D=l(t,D,N),E+=N.length),c(t,D,C),S=l(t,D,new a(p,h?r.tokenize(R,h):R,y,R)),O&&l(t,S,O),C>1){var M={cause:p+","+m,reach:I};i(e,t,n,S.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}return a.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var a="";return t.forEach((function(t){a+=e(t,n)})),a}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),r.hooks.run("wrap",o);var s="";for(var l in o.attributes)s+=" "+l+'="'+(o.attributes[l]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+s+">"+o.content+"</"+o.tag+">"},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i<a.length;i++)o[a[i]]=e.languages.bash[a[i]];e.languages.shell=e.languages.bash}(a),a.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var a=t[n];if("code"===a.type){var o=a.content[1],i=a.content[3];if(o&&i&&"code-language"===o.type&&"code-block"===i.type&&"string"==typeof o.content){var s=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),l="language-"+(s=(/[a-z][\w-]*/i.exec(s)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,l]:i.alias.push(l):i.alias=[l]}}else e(a.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,a=t.classes.length;r<a;r++){var o=t.classes[r],c=/language-(.+)/.exec(o);if(c){n=c[1];break}}var u,d=e.languages[n];if(d)t.content=e.highlight((u=t.content,u.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),l(n);var r=s[t];return r||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var p="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=p,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(p);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),s={amp:"&",lt:"<",gt:">",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var a=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=p(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),a.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),a.length>0)){var s=p(/^\{$/,/^\}$/);if(-1===s)continue;for(var l=n;l<s;l++){var c=t[l];"variable"===c.type&&a.indexOf(c.content)>=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return!1}return!0}function p(e,r){for(var a=1,o=n;o<t.length;o++){var i=t[o],s=i.content;if("punctuation"===i.type&&"string"==typeof s)if(e.test(s))a++;else if(r.test(s)&&0===--a)return o}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),a.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function l(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,l(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=l(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=s(i++,r)););return u[n]=a,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,s=o.indexOf(a);if(-1!==s){++i;var l=o.substring(0,s),d=c(u[a]),f=o.substring(s+a.length),m=[];if(l&&m.push(l),m.push(d),f){var g=[f];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r<a;r++){var o=n[r];if("string"!=typeof o){var i=o.content;if(Array.isArray(i))if("template-string"===o.type){var s=i[1];if(3===i.length&&"string"!=typeof s&&"embedded-code"===s.type){var l=p(s),c=s.alias,d=Array.isArray(c)?c[0]:c,f=e.languages[d];if(!f)continue;i[1]=u(l,f,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(a),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var a=n[r],o=e.languages.javascript[a];"RegExp"===e.util.type(o)&&(o=e.languages.javascript[a]={pattern:o});var i=o.inside||{};o.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(a),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},s=function(t){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=!1;if("string"!=typeof a&&("tag"===a.type&&a.content[0]&&"tag"===a.content[0].type?"</"===a.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var l=i(a);r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(l+=i(t[r+1]),t.splice(r+1,1)),r>0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(l=i(t[r-1])+l,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",l,null,l)}a.content&&"string"!=typeof a.content&&s(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l<s.length&&!(a>=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++a;var g=p.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),v=[];g&&v.push.apply(v,i([g])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function a(r,o){if(!(r in n)){o.push(r);var i=o.indexOf(r);if(i<o.length-1)throw new Error("Circular dependency: "+o.slice(i).join(" -> "));var s={},l=e[r];if(l){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in s))for(var i in a(t,o),s[t]=!0,n[t])s[i]=!0}t(l.require,c),t(l.optional,c),t(l.modify,c)}n[r]=s,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,s){var l=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(l);i=i.map(c),s=(s||[]).map(c);var u=n(i),d=n(s);i.forEach((function e(n){var r=l[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(l),m=u;a(m);){for(var g in p={},m){var h=l[g];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in f(b))if(v in u){p[b]=!0;break}for(var y in m=p)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,s={},l={};function c(e){if(e in s)return s[e];l[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete l[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return s[e]=a}for(var u in n)c(u);var d=[];for(var p in l)d.push(s[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));var s=new Set,l={};function c(e,t){u(e,t),u(e+"Capture",t)}function u(e,t){for(l[e]=t,e=0;e<t.length;e++)s.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f=Object.prototype.hasOwnProperty,m={},g={};function h(e,t,n,r,a,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=a,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){b[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];b[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){b[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){b[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){b[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){b[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){b[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){b[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){b[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,r){var a=b.hasOwnProperty(t)?b[t]:null;(null!==a?0===a.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,a,r)&&(n=null),r||null===a?function(e){return!!f.call(g,e)||!f.call(m,e)&&(p.test(e)?g[e]=!0:(m[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):a.mustUseProperty?e[a.propertyName]=null===n?3!==a.type&&"":n:(t=a.attributeName,r=a.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(a=a.type)||4===a&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),b.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,S=60103,E=60106,_=60107,x=60108,C=60114,T=60109,L=60110,A=60112,P=60113,R=60120,N=60115,O=60116,I=60121,D=60128,M=60129,j=60130,F=60131;if("function"==typeof Symbol&&Symbol.for){var B=Symbol.for;S=B("react.element"),E=B("react.portal"),_=B("react.fragment"),x=B("react.strict_mode"),C=B("react.profiler"),T=B("react.provider"),L=B("react.context"),A=B("react.forward_ref"),P=B("react.suspense"),R=B("react.suspense_list"),N=B("react.memo"),O=B("react.lazy"),I=B("react.block"),B("react.scope"),D=B("react.opaque.id"),M=B("react.debug_trace_mode"),j=B("react.offscreen"),F=B("react.legacy_hidden")}var z,U="function"==typeof Symbol&&Symbol.iterator;function $(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=U&&e[U]||e["@@iterator"])?e:null}function q(e){if(void 0===z)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);z=t&&t[1]||""}return"\n"+z+e}var G=!1;function H(e,t){if(!e||G)return"";G=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(l){var r=l}Reflect.construct(e,[],t)}else{try{t.call()}catch(l){r=l}e.call(t.prototype)}else{try{throw Error()}catch(l){r=l}e()}}catch(l){if(l&&r&&"string"==typeof l.stack){for(var a=l.stack.split("\n"),o=r.stack.split("\n"),i=a.length-1,s=o.length-1;1<=i&&0<=s&&a[i]!==o[s];)s--;for(;1<=i&&0<=s;i--,s--)if(a[i]!==o[s]){if(1!==i||1!==s)do{if(i--,0>--s||a[i]!==o[s])return"\n"+a[i].replace(" at new "," at ")}while(1<=i&&0<=s);break}}}finally{G=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?q(e):""}function Z(e){switch(e.tag){case 5:return q(e.type);case 16:return q("Lazy");case 13:return q("Suspense");case 19:return q("SuspenseList");case 0:case 2:case 15:return e=H(e.type,!1);case 11:return e=H(e.type.render,!1);case 22:return e=H(e.type._render,!1);case 1:return e=H(e.type,!0);default:return""}}function V(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case E:return"Portal";case C:return"Profiler";case x:return"StrictMode";case P:return"Suspense";case R:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case L:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case A:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case N:return V(e.type);case I:return V(e._render);case O:t=e._payload,e=e._init;try{return V(e(t))}catch(n){}}return null}function W(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function Y(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function K(e){e._valueTracker||(e._valueTracker=function(e){var t=Y(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var a=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Y(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function X(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return a({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=W(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=W(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ae(e,t.type,n):t.hasOwnProperty("defaultValue")&&ae(e,t.type,W(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function re(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ae(e,t,n){"number"===t&&X(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function oe(e,t){return e=a({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a<n.length;a++)t["$"+n[a]]=!0;for(n=0;n<e.length;n++)a=t.hasOwnProperty("$"+e[n].value),e[n].selected!==a&&(e[n].selected=a),a&&r&&(e[n].defaultSelected=!0)}else{for(n=""+W(n),t=null,a=0;a<e.length;a++){if(e[a].value===n)return e[a].selected=!0,void(r&&(e[a].defaultSelected=!0));null!==t||e[a].disabled||(t=e[a])}null!==t&&(t.selected=!0)}}function se(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return a({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function le(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:W(n)}}function ce(e,t){var n=W(t.value),r=W(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ue(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function pe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function fe(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?pe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,ge,he=(ge=function(e,t){if(e.namespaceURI!==de.svg||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ge(e,t)}))}:ge);function be(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ve={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ye=["Webkit","ms","Moz","O"];function we(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ve.hasOwnProperty(e)&&ve[e]?(""+t).trim():t+"px"}function ke(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),a=we(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,a):e[n]=a}}Object.keys(ve).forEach((function(e){ye.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ve[t]=ve[e]}))}));var Se=a({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(Se[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function _e(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Ce=null,Te=null,Le=null;function Ae(e){if(e=na(e)){if("function"!=typeof Ce)throw Error(i(280));var t=e.stateNode;t&&(t=aa(t),Ce(e.stateNode,e.type,t))}}function Pe(e){Te?Le?Le.push(e):Le=[e]:Te=e}function Re(){if(Te){var e=Te,t=Le;if(Le=Te=null,Ae(e),t)for(e=0;e<t.length;e++)Ae(t[e])}}function Ne(e,t){return e(t)}function Oe(e,t,n,r,a){return e(t,n,r,a)}function Ie(){}var De=Ne,Me=!1,je=!1;function Fe(){null===Te&&null===Le||(Ie(),Re())}function Be(e,t){var n=e.stateNode;if(null===n)return null;var r=aa(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var ze=!1;if(d)try{var Ue={};Object.defineProperty(Ue,"passive",{get:function(){ze=!0}}),window.addEventListener("test",Ue,Ue),window.removeEventListener("test",Ue,Ue)}catch(ge){ze=!1}function $e(e,t,n,r,a,o,i,s,l){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var qe=!1,Ge=null,He=!1,Ze=null,Ve={onError:function(e){qe=!0,Ge=e}};function We(e,t,n,r,a,o,i,s,l){qe=!1,Ge=null,$e.apply(Ve,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ke(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Qe(e){if(Ye(e)!==e)throw Error(i(188))}function Xe(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var a=n.return;if(null===a)break;var o=a.alternate;if(null===o){if(null!==(r=a.return)){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return Qe(a),e;if(o===r)return Qe(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var s=!1,l=a.child;l;){if(l===n){s=!0,n=a,r=o;break}if(l===r){s=!0,r=a,n=o;break}l=l.sibling}if(!s){for(l=o.child;l;){if(l===n){s=!0,n=o,r=a;break}if(l===r){s=!0,r=o,n=a;break}l=l.sibling}if(!s)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function Je(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var et,tt,nt,rt,at=!1,ot=[],it=null,st=null,lt=null,ct=new Map,ut=new Map,dt=[],pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ft(e,t,n,r,a){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:a,targetContainers:[r]}}function mt(e,t){switch(e){case"focusin":case"focusout":it=null;break;case"dragenter":case"dragleave":st=null;break;case"mouseover":case"mouseout":lt=null;break;case"pointerover":case"pointerout":ct.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":ut.delete(t.pointerId)}}function gt(e,t,n,r,a,o){return null===e||e.nativeEvent!==o?(e=ft(t,n,r,a,o),null!==t&&(null!==(t=na(t))&&tt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==a&&-1===t.indexOf(a)&&t.push(a),e)}function ht(e){var t=ta(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ke(n)))return e.blockedOn=t,void rt(e.lanePriority,(function(){o.unstable_runWithPriority(e.priority,(function(){nt(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function bt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=na(n))&&tt(t),e.blockedOn=n,!1;t.shift()}return!0}function vt(e,t,n){bt(e)&&n.delete(t)}function yt(){for(at=!1;0<ot.length;){var e=ot[0];if(null!==e.blockedOn){null!==(e=na(e.blockedOn))&&et(e);break}for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&ot.shift()}null!==it&&bt(it)&&(it=null),null!==st&&bt(st)&&(st=null),null!==lt&&bt(lt)&&(lt=null),ct.forEach(vt),ut.forEach(vt)}function wt(e,t){e.blockedOn===t&&(e.blockedOn=null,at||(at=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,yt)))}function kt(e){function t(t){return wt(t,e)}if(0<ot.length){wt(ot[0],e);for(var n=1;n<ot.length;n++){var r=ot[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==it&&wt(it,e),null!==st&&wt(st,e),null!==lt&&wt(lt,e),ct.forEach(t),ut.forEach(t),n=0;n<dt.length;n++)(r=dt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<dt.length&&null===(n=dt[0]).blockedOn;)ht(n),null===n.blockedOn&&dt.shift()}function St(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:St("Animation","AnimationEnd"),animationiteration:St("Animation","AnimationIteration"),animationstart:St("Animation","AnimationStart"),transitionend:St("Transition","TransitionEnd")},_t={},xt={};function Ct(e){if(_t[e])return _t[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in xt)return _t[e]=n[t];return e}d&&(xt=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var Tt=Ct("animationend"),Lt=Ct("animationiteration"),At=Ct("animationstart"),Pt=Ct("transitionend"),Rt=new Map,Nt=new Map,Ot=["abort","abort",Tt,"animationEnd",Lt,"animationIteration",At,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Pt,"transitionEnd","waiting","waiting"];function It(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],a=e[n+1];a="on"+(a[0].toUpperCase()+a.slice(1)),Nt.set(r,t),Rt.set(r,a),c(a,[r])}}(0,o.unstable_now)();var Dt=8;function Mt(e){if(0!=(1&e))return Dt=15,1;if(0!=(2&e))return Dt=14,2;if(0!=(4&e))return Dt=13,4;var t=24&e;return 0!==t?(Dt=12,t):0!=(32&e)?(Dt=11,32):0!==(t=192&e)?(Dt=10,t):0!=(256&e)?(Dt=9,256):0!==(t=3584&e)?(Dt=8,t):0!=(4096&e)?(Dt=7,4096):0!==(t=4186112&e)?(Dt=6,t):0!==(t=62914560&e)?(Dt=5,t):67108864&e?(Dt=4,67108864):0!=(134217728&e)?(Dt=3,134217728):0!==(t=805306368&e)?(Dt=2,t):0!=(1073741824&e)?(Dt=1,1073741824):(Dt=8,e)}function jt(e,t){var n=e.pendingLanes;if(0===n)return Dt=0;var r=0,a=0,o=e.expiredLanes,i=e.suspendedLanes,s=e.pingedLanes;if(0!==o)r=o,a=Dt=15;else if(0!==(o=134217727&n)){var l=o&~i;0!==l?(r=Mt(l),a=Dt):0!==(s&=o)&&(r=Mt(s),a=Dt)}else 0!==(o=n&~i)?(r=Mt(o),a=Dt):0!==s&&(r=Mt(s),a=Dt);if(0===r)return 0;if(r=n&((0>(r=31-qt(r))?0:1<<r)<<1)-1,0!==t&&t!==r&&0==(t&i)){if(Mt(t),a<=Dt)return t;Dt=a}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)a=1<<(n=31-qt(t)),r|=e[n],t&=~a;return r}function Ft(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function Bt(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=zt(24&~t))?Bt(10,t):e;case 10:return 0===(e=zt(192&~t))?Bt(8,t):e;case 8:return 0===(e=zt(3584&~t))&&(0===(e=zt(4186112&~t))&&(e=512)),e;case 2:return 0===(t=zt(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function zt(e){return e&-e}function Ut(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function $t(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-qt(t)]=n}var qt=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(Gt(e)/Ht|0)|0},Gt=Math.log,Ht=Math.LN2;var Zt=o.unstable_UserBlockingPriority,Vt=o.unstable_runWithPriority,Wt=!0;function Yt(e,t,n,r){Me||Ie();var a=Qt,o=Me;Me=!0;try{Oe(a,e,t,n,r)}finally{(Me=o)||Fe()}}function Kt(e,t,n,r){Vt(Zt,Qt.bind(null,e,t,n,r))}function Qt(e,t,n,r){var a;if(Wt)if((a=0==(4&t))&&0<ot.length&&-1<pt.indexOf(e))e=ft(null,e,t,n,r),ot.push(e);else{var o=Xt(e,t,n,r);if(null===o)a&&mt(e,r);else{if(a){if(-1<pt.indexOf(e))return e=ft(o,e,t,n,r),void ot.push(e);if(function(e,t,n,r,a){switch(t){case"focusin":return it=gt(it,e,t,n,r,a),!0;case"dragenter":return st=gt(st,e,t,n,r,a),!0;case"mouseover":return lt=gt(lt,e,t,n,r,a),!0;case"pointerover":var o=a.pointerId;return ct.set(o,gt(ct.get(o)||null,e,t,n,r,a)),!0;case"gotpointercapture":return o=a.pointerId,ut.set(o,gt(ut.get(o)||null,e,t,n,r,a)),!0}return!1}(o,e,t,n,r))return;mt(e,r)}Ir(e,t,r,null,n)}}}function Xt(e,t,n,r){var a=xe(r);if(null!==(a=ta(a))){var o=Ye(a);if(null===o)a=null;else{var i=o.tag;if(13===i){if(null!==(a=Ke(o)))return a;a=null}else if(3===i){if(o.stateNode.hydrate)return 3===o.tag?o.stateNode.containerInfo:null;a=null}else o!==a&&(a=null)}}return Ir(e,t,r,a,n),null}var Jt=null,en=null,tn=null;function nn(){if(tn)return tn;var e,t,n=en,r=n.length,a="value"in Jt?Jt.value:Jt.textContent,o=a.length;for(e=0;e<r&&n[e]===a[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===a[o-t];t++);return tn=a.slice(e,1<t?1-t:void 0)}function rn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function an(){return!0}function on(){return!1}function sn(e){function t(t,n,r,a,o){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=a,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(a):a[i]);return this.isDefaultPrevented=(null!=a.defaultPrevented?a.defaultPrevented:!1===a.returnValue)?an:on,this.isPropagationStopped=on,this}return a(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=an)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=an)},persist:function(){},isPersistent:an}),t}var ln,cn,un,dn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},pn=sn(dn),fn=a({},dn,{view:0,detail:0}),mn=sn(fn),gn=a({},fn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Tn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==un&&(un&&"mousemove"===e.type?(ln=e.screenX-un.screenX,cn=e.screenY-un.screenY):cn=ln=0,un=e),ln)},movementY:function(e){return"movementY"in e?e.movementY:cn}}),hn=sn(gn),bn=sn(a({},gn,{dataTransfer:0})),vn=sn(a({},fn,{relatedTarget:0})),yn=sn(a({},dn,{animationName:0,elapsedTime:0,pseudoElement:0})),wn=a({},dn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),kn=sn(wn),Sn=sn(a({},dn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},_n={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},xn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Cn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=xn[e])&&!!t[e]}function Tn(){return Cn}var Ln=a({},fn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=rn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?_n[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Tn,charCode:function(e){return"keypress"===e.type?rn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?rn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),An=sn(Ln),Pn=sn(a({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Rn=sn(a({},fn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Tn})),Nn=sn(a({},dn,{propertyName:0,elapsedTime:0,pseudoElement:0})),On=a({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),In=sn(On),Dn=[9,13,27,32],Mn=d&&"CompositionEvent"in window,jn=null;d&&"documentMode"in document&&(jn=document.documentMode);var Fn=d&&"TextEvent"in window&&!jn,Bn=d&&(!Mn||jn&&8<jn&&11>=jn),zn=String.fromCharCode(32),Un=!1;function $n(e,t){switch(e){case"keyup":return-1!==Dn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function qn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Gn=!1;var Hn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Zn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Hn[e.type]:"textarea"===t}function Vn(e,t,n,r){Pe(r),0<(t=Mr(t,"onChange")).length&&(n=new pn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Wn=null,Yn=null;function Kn(e){Lr(e,0)}function Qn(e){if(Q(ra(e)))return e}function Xn(e,t){if("change"===e)return t}var Jn=!1;if(d){var er;if(d){var tr="oninput"in document;if(!tr){var nr=document.createElement("div");nr.setAttribute("oninput","return;"),tr="function"==typeof nr.oninput}er=tr}else er=!1;Jn=er&&(!document.documentMode||9<document.documentMode)}function rr(){Wn&&(Wn.detachEvent("onpropertychange",ar),Yn=Wn=null)}function ar(e){if("value"===e.propertyName&&Qn(Yn)){var t=[];if(Vn(t,Yn,e,xe(e)),e=Kn,Me)e(t);else{Me=!0;try{Ne(e,t)}finally{Me=!1,Fe()}}}}function or(e,t,n){"focusin"===e?(rr(),Yn=n,(Wn=t).attachEvent("onpropertychange",ar)):"focusout"===e&&rr()}function ir(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Qn(Yn)}function sr(e,t){if("click"===e)return Qn(t)}function lr(e,t){if("input"===e||"change"===e)return Qn(t)}var cr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},ur=Object.prototype.hasOwnProperty;function dr(e,t){if(cr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!ur.call(t,n[r])||!cr(e[n[r]],t[n[r]]))return!1;return!0}function pr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function fr(e,t){var n,r=pr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=pr(r)}}function mr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function gr(){for(var e=window,t=X();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=X((e=t.contentWindow).document)}return t}function hr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var br=d&&"documentMode"in document&&11>=document.documentMode,vr=null,yr=null,wr=null,kr=!1;function Sr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;kr||null==vr||vr!==X(r)||("selectionStart"in(r=vr)&&hr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},wr&&dr(wr,r)||(wr=r,0<(r=Mr(yr,"onSelect")).length&&(t=new pn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=vr)))}It("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),It("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),It(Ot,2);for(var Er="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),_r=0;_r<Er.length;_r++)Nt.set(Er[_r],0);u("onMouseEnter",["mouseout","mouseover"]),u("onMouseLeave",["mouseout","mouseover"]),u("onPointerEnter",["pointerout","pointerover"]),u("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var xr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Cr=new Set("cancel close invalid load scroll toggle".split(" ").concat(xr));function Tr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,a,o,s,l,c){if(We.apply(this,arguments),qe){if(!qe)throw Error(i(198));var u=Ge;qe=!1,Ge=null,He||(He=!0,Ze=u)}}(r,t,void 0,e),e.currentTarget=null}function Lr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],a=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var i=r.length-1;0<=i;i--){var s=r[i],l=s.instance,c=s.currentTarget;if(s=s.listener,l!==o&&a.isPropagationStopped())break e;Tr(a,s,c),o=l}else for(i=0;i<r.length;i++){if(l=(s=r[i]).instance,c=s.currentTarget,s=s.listener,l!==o&&a.isPropagationStopped())break e;Tr(a,s,c),o=l}}}if(He)throw e=Ze,He=!1,Ze=null,e}function Ar(e,t){var n=oa(t),r=e+"__bubble";n.has(r)||(Or(t,e,2,!1),n.add(r))}var Pr="_reactListening"+Math.random().toString(36).slice(2);function Rr(e){e[Pr]||(e[Pr]=!0,s.forEach((function(t){Cr.has(t)||Nr(t,!1,e,null),Nr(t,!0,e,null)})))}function Nr(e,t,n,r){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,o=n;if("selectionchange"===e&&9!==n.nodeType&&(o=n.ownerDocument),null!==r&&!t&&Cr.has(e)){if("scroll"!==e)return;a|=2,o=r}var i=oa(o),s=e+"__"+(t?"capture":"bubble");i.has(s)||(t&&(a|=4),Or(o,e,a,t),i.add(s))}function Or(e,t,n,r){var a=Nt.get(t);switch(void 0===a?2:a){case 0:a=Yt;break;case 1:a=Kt;break;default:a=Qt}n=a.bind(null,t,n,e),a=void 0,!ze||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(a=!0),r?void 0!==a?e.addEventListener(t,n,{capture:!0,passive:a}):e.addEventListener(t,n,!0):void 0!==a?e.addEventListener(t,n,{passive:a}):e.addEventListener(t,n,!1)}function Ir(e,t,n,r,a){var o=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var s=r.stateNode.containerInfo;if(s===a||8===s.nodeType&&s.parentNode===a)break;if(4===i)for(i=r.return;null!==i;){var l=i.tag;if((3===l||4===l)&&((l=i.stateNode.containerInfo)===a||8===l.nodeType&&l.parentNode===a))return;i=i.return}for(;null!==s;){if(null===(i=ta(s)))return;if(5===(l=i.tag)||6===l){r=o=i;continue e}s=s.parentNode}}r=r.return}!function(e,t,n){if(je)return e(t,n);je=!0;try{return De(e,t,n)}finally{je=!1,Fe()}}((function(){var r=o,a=xe(n),i=[];e:{var s=Rt.get(e);if(void 0!==s){var l=pn,c=e;switch(e){case"keypress":if(0===rn(n))break e;case"keydown":case"keyup":l=An;break;case"focusin":c="focus",l=vn;break;case"focusout":c="blur",l=vn;break;case"beforeblur":case"afterblur":l=vn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":l=hn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":l=bn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":l=Rn;break;case Tt:case Lt:case At:l=yn;break;case Pt:l=Nn;break;case"scroll":l=mn;break;case"wheel":l=In;break;case"copy":case"cut":case"paste":l=kn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":l=Pn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==s?s+"Capture":null:s;u=[];for(var f,m=r;null!==m;){var g=(f=m).stateNode;if(5===f.tag&&null!==g&&(f=g,null!==p&&(null!=(g=Be(m,p))&&u.push(Dr(m,g,f)))),d)break;m=m.return}0<u.length&&(s=new l(s,c,null,n,a),i.push({event:s,listeners:u}))}}if(0==(7&t)){if(l="mouseout"===e||"pointerout"===e,(!(s="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(c=n.relatedTarget||n.fromElement)||!ta(c)&&!c[Jr])&&(l||s)&&(s=a.window===a?a:(s=a.ownerDocument)?s.defaultView||s.parentWindow:window,l?(l=r,null!==(c=(c=n.relatedTarget||n.toElement)?ta(c):null)&&(c!==(d=Ye(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(l=null,c=r),l!==c)){if(u=hn,g="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Pn,g="onPointerLeave",p="onPointerEnter",m="pointer"),d=null==l?s:ra(l),f=null==c?s:ra(c),(s=new u(g,m+"leave",l,n,a)).target=d,s.relatedTarget=f,g=null,ta(a)===r&&((u=new u(p,m+"enter",c,n,a)).target=f,u.relatedTarget=d,g=u),d=g,l&&c)e:{for(p=c,m=0,f=u=l;f;f=jr(f))m++;for(f=0,g=p;g;g=jr(g))f++;for(;0<m-f;)u=jr(u),m--;for(;0<f-m;)p=jr(p),f--;for(;m--;){if(u===p||null!==p&&u===p.alternate)break e;u=jr(u),p=jr(p)}u=null}else u=null;null!==l&&Fr(i,s,l,u,!1),null!==c&&null!==d&&Fr(i,d,c,u,!0)}if("select"===(l=(s=r?ra(r):window).nodeName&&s.nodeName.toLowerCase())||"input"===l&&"file"===s.type)var h=Xn;else if(Zn(s))if(Jn)h=lr;else{h=ir;var b=or}else(l=s.nodeName)&&"input"===l.toLowerCase()&&("checkbox"===s.type||"radio"===s.type)&&(h=sr);switch(h&&(h=h(e,r))?Vn(i,h,n,a):(b&&b(e,s,r),"focusout"===e&&(b=s._wrapperState)&&b.controlled&&"number"===s.type&&ae(s,"number",s.value)),b=r?ra(r):window,e){case"focusin":(Zn(b)||"true"===b.contentEditable)&&(vr=b,yr=r,wr=null);break;case"focusout":wr=yr=vr=null;break;case"mousedown":kr=!0;break;case"contextmenu":case"mouseup":case"dragend":kr=!1,Sr(i,n,a);break;case"selectionchange":if(br)break;case"keydown":case"keyup":Sr(i,n,a)}var v;if(Mn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else Gn?$n(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Bn&&"ko"!==n.locale&&(Gn||"onCompositionStart"!==y?"onCompositionEnd"===y&&Gn&&(v=nn()):(en="value"in(Jt=a)?Jt.value:Jt.textContent,Gn=!0)),0<(b=Mr(r,y)).length&&(y=new Sn(y,e,null,n,a),i.push({event:y,listeners:b}),v?y.data=v:null!==(v=qn(n))&&(y.data=v))),(v=Fn?function(e,t){switch(e){case"compositionend":return qn(t);case"keypress":return 32!==t.which?null:(Un=!0,zn);case"textInput":return(e=t.data)===zn&&Un?null:e;default:return null}}(e,n):function(e,t){if(Gn)return"compositionend"===e||!Mn&&$n(e,t)?(e=nn(),tn=en=Jt=null,Gn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Bn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Mr(r,"onBeforeInput")).length&&(a=new Sn("onBeforeInput","beforeinput",null,n,a),i.push({event:a,listeners:r}),a.data=v))}Lr(i,t)}))}function Dr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Mr(e,t){for(var n=t+"Capture",r=[];null!==e;){var a=e,o=a.stateNode;5===a.tag&&null!==o&&(a=o,null!=(o=Be(e,n))&&r.unshift(Dr(e,o,a)),null!=(o=Be(e,t))&&r.push(Dr(e,o,a))),e=e.return}return r}function jr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Fr(e,t,n,r,a){for(var o=t._reactName,i=[];null!==n&&n!==r;){var s=n,l=s.alternate,c=s.stateNode;if(null!==l&&l===r)break;5===s.tag&&null!==c&&(s=c,a?null!=(l=Be(n,o))&&i.unshift(Dr(n,l,s)):a||null!=(l=Be(n,o))&&i.push(Dr(n,l,s))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function Br(){}var zr=null,Ur=null;function $r(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function qr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var Gr="function"==typeof setTimeout?setTimeout:void 0,Hr="function"==typeof clearTimeout?clearTimeout:void 0;function Zr(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Vr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Wr(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Yr=0;var Kr=Math.random().toString(36).slice(2),Qr="__reactFiber$"+Kr,Xr="__reactProps$"+Kr,Jr="__reactContainer$"+Kr,ea="__reactEvents$"+Kr;function ta(e){var t=e[Qr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Jr]||n[Qr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Wr(e);null!==e;){if(n=e[Qr])return n;e=Wr(e)}return t}n=(e=n).parentNode}return null}function na(e){return!(e=e[Qr]||e[Jr])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function ra(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function aa(e){return e[Xr]||null}function oa(e){var t=e[ea];return void 0===t&&(t=e[ea]=new Set),t}var ia=[],sa=-1;function la(e){return{current:e}}function ca(e){0>sa||(e.current=ia[sa],ia[sa]=null,sa--)}function ua(e,t){sa++,ia[sa]=e.current,e.current=t}var da={},pa=la(da),fa=la(!1),ma=da;function ga(e,t){var n=e.type.contextTypes;if(!n)return da;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var a,o={};for(a in n)o[a]=t[a];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function ha(e){return null!=(e=e.childContextTypes)}function ba(){ca(fa),ca(pa)}function va(e,t,n){if(pa.current!==da)throw Error(i(168));ua(pa,t),ua(fa,n)}function ya(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(i(108,V(t)||"Unknown",o));return a({},n,r)}function wa(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||da,ma=pa.current,ua(pa,e),ua(fa,fa.current),!0}function ka(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=ya(e,t,ma),r.__reactInternalMemoizedMergedChildContext=e,ca(fa),ca(pa),ua(pa,e)):ca(fa),ua(fa,n)}var Sa=null,Ea=null,_a=o.unstable_runWithPriority,xa=o.unstable_scheduleCallback,Ca=o.unstable_cancelCallback,Ta=o.unstable_shouldYield,La=o.unstable_requestPaint,Aa=o.unstable_now,Pa=o.unstable_getCurrentPriorityLevel,Ra=o.unstable_ImmediatePriority,Na=o.unstable_UserBlockingPriority,Oa=o.unstable_NormalPriority,Ia=o.unstable_LowPriority,Da=o.unstable_IdlePriority,Ma={},ja=void 0!==La?La:function(){},Fa=null,Ba=null,za=!1,Ua=Aa(),$a=1e4>Ua?Aa:function(){return Aa()-Ua};function qa(){switch(Pa()){case Ra:return 99;case Na:return 98;case Oa:return 97;case Ia:return 96;case Da:return 95;default:throw Error(i(332))}}function Ga(e){switch(e){case 99:return Ra;case 98:return Na;case 97:return Oa;case 96:return Ia;case 95:return Da;default:throw Error(i(332))}}function Ha(e,t){return e=Ga(e),_a(e,t)}function Za(e,t,n){return e=Ga(e),xa(e,t,n)}function Va(){if(null!==Ba){var e=Ba;Ba=null,Ca(e)}Wa()}function Wa(){if(!za&&null!==Fa){za=!0;var e=0;try{var t=Fa;Ha(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),Fa=null}catch(n){throw null!==Fa&&(Fa=Fa.slice(e+1)),xa(Ra,Va),n}finally{za=!1}}}var Ya=k.ReactCurrentBatchConfig;function Ka(e,t){if(e&&e.defaultProps){for(var n in t=a({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Qa=la(null),Xa=null,Ja=null,eo=null;function to(){eo=Ja=Xa=null}function no(e){var t=Qa.current;ca(Qa),e.type._context._currentValue=t}function ro(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function ao(e,t){Xa=e,eo=Ja=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Mi=!0),e.firstContext=null)}function oo(e,t){if(eo!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(eo=e,t=1073741823),t={context:e,observedBits:t,next:null},null===Ja){if(null===Xa)throw Error(i(308));Ja=t,Xa.dependencies={lanes:0,firstContext:t,responders:null}}else Ja=Ja.next=t;return e._currentValue}var io=!1;function so(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function lo(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function co(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function uo(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function po(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var a=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===o?a=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?a=o=t:o=o.next=t}else a=o=t;return n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:o,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function fo(e,t,n,r){var o=e.updateQueue;io=!1;var i=o.firstBaseUpdate,s=o.lastBaseUpdate,l=o.shared.pending;if(null!==l){o.shared.pending=null;var c=l,u=c.next;c.next=null,null===s?i=u:s.next=u,s=c;var d=e.alternate;if(null!==d){var p=(d=d.updateQueue).lastBaseUpdate;p!==s&&(null===p?d.firstBaseUpdate=u:p.next=u,d.lastBaseUpdate=c)}}if(null!==i){for(p=o.baseState,s=0,d=u=c=null;;){l=i.lane;var f=i.eventTime;if((r&l)===l){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var m=e,g=i;switch(l=t,f=n,g.tag){case 1:if("function"==typeof(m=g.payload)){p=m.call(f,p,l);break e}p=m;break e;case 3:m.flags=-4097&m.flags|64;case 0:if(null==(l="function"==typeof(m=g.payload)?m.call(f,p,l):m))break e;p=a({},p,l);break e;case 2:io=!0}}null!==i.callback&&(e.flags|=32,null===(l=o.effects)?o.effects=[i]:l.push(i))}else f={eventTime:f,lane:l,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(u=d=f,c=p):d=d.next=f,s|=l;if(null===(i=i.next)){if(null===(l=o.shared.pending))break;i=l.next,l.next=null,o.lastBaseUpdate=l,o.shared.pending=null}}null===d&&(c=p),o.baseState=c,o.firstBaseUpdate=u,o.lastBaseUpdate=d,Us|=s,e.lanes=s,e.memoizedState=p}}function mo(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],a=r.callback;if(null!==a){if(r.callback=null,r=n,"function"!=typeof a)throw Error(i(191,a));a.call(r)}}}var go=(new r.Component).refs;function ho(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:a({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var bo={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=pl(),a=fl(e),o=co(r,a);o.payload=t,null!=n&&(o.callback=n),uo(e,o),ml(e,a,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=pl(),a=fl(e),o=co(r,a);o.tag=1,o.payload=t,null!=n&&(o.callback=n),uo(e,o),ml(e,a,r)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=pl(),r=fl(e),a=co(n,r);a.tag=2,null!=t&&(a.callback=t),uo(e,a),ml(e,r,n)}};function vo(e,t,n,r,a,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!dr(n,r)||!dr(a,o))}function yo(e,t,n){var r=!1,a=da,o=t.contextType;return"object"==typeof o&&null!==o?o=oo(o):(a=ha(t)?ma:pa.current,o=(r=null!=(r=t.contextTypes))?ga(e,a):da),t=new t(n,o),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=bo,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=a,e.__reactInternalMemoizedMaskedChildContext=o),t}function wo(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&bo.enqueueReplaceState(t,t.state,null)}function ko(e,t,n,r){var a=e.stateNode;a.props=n,a.state=e.memoizedState,a.refs=go,so(e);var o=t.contextType;"object"==typeof o&&null!==o?a.context=oo(o):(o=ha(t)?ma:pa.current,a.context=ga(e,o)),fo(e,n,a,r),a.state=e.memoizedState,"function"==typeof(o=t.getDerivedStateFromProps)&&(ho(e,t,o,n),a.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof a.getSnapshotBeforeUpdate||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||(t=a.state,"function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount(),t!==a.state&&bo.enqueueReplaceState(a,a.state,null),fo(e,n,a,r),a.state=e.memoizedState),"function"==typeof a.componentDidMount&&(e.flags|=4)}var So=Array.isArray;function Eo(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=r.refs;t===go&&(t=r.refs={}),null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function _o(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function xo(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function a(e,t){return(e=Zl(e,t)).index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags=2,n):r:(t.flags=2,n):n}function s(t){return e&&null===t.alternate&&(t.flags=2),t}function l(e,t,n,r){return null===t||6!==t.tag?((t=Kl(n,e.mode,r)).return=e,t):((t=a(t,n)).return=e,t)}function c(e,t,n,r){return null!==t&&t.elementType===n.type?((r=a(t,n.props)).ref=Eo(e,t,n),r.return=e,r):((r=Vl(n.type,n.key,n.props,null,e.mode,r)).ref=Eo(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Ql(n,e.mode,r)).return=e,t):((t=a(t,n.children||[])).return=e,t)}function d(e,t,n,r,o){return null===t||7!==t.tag?((t=Wl(n,e.mode,r,o)).return=e,t):((t=a(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Kl(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case S:return(n=Vl(t.type,t.key,t.props,null,e.mode,n)).ref=Eo(e,null,t),n.return=e,n;case E:return(t=Ql(t,e.mode,n)).return=e,t}if(So(t)||$(t))return(t=Wl(t,e.mode,n,null)).return=e,t;_o(e,t)}return null}function f(e,t,n,r){var a=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==a?null:l(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case S:return n.key===a?n.type===_?d(e,t,n.props.children,r,a):c(e,t,n,r):null;case E:return n.key===a?u(e,t,n,r):null}if(So(n)||$(n))return null!==a?null:d(e,t,n,r,null);_o(e,n)}return null}function m(e,t,n,r,a){if("string"==typeof r||"number"==typeof r)return l(t,e=e.get(n)||null,""+r,a);if("object"==typeof r&&null!==r){switch(r.$$typeof){case S:return e=e.get(null===r.key?n:r.key)||null,r.type===_?d(t,e,r.props.children,a,r.key):c(t,e,r,a);case E:return u(t,e=e.get(null===r.key?n:r.key)||null,r,a)}if(So(r)||$(r))return d(t,e=e.get(n)||null,r,a,null);_o(t,r)}return null}function g(a,i,s,l){for(var c=null,u=null,d=i,g=i=0,h=null;null!==d&&g<s.length;g++){d.index>g?(h=d,d=null):h=d.sibling;var b=f(a,d,s[g],l);if(null===b){null===d&&(d=h);break}e&&d&&null===b.alternate&&t(a,d),i=o(b,i,g),null===u?c=b:u.sibling=b,u=b,d=h}if(g===s.length)return n(a,d),c;if(null===d){for(;g<s.length;g++)null!==(d=p(a,s[g],l))&&(i=o(d,i,g),null===u?c=d:u.sibling=d,u=d);return c}for(d=r(a,d);g<s.length;g++)null!==(h=m(d,a,g,s[g],l))&&(e&&null!==h.alternate&&d.delete(null===h.key?g:h.key),i=o(h,i,g),null===u?c=h:u.sibling=h,u=h);return e&&d.forEach((function(e){return t(a,e)})),c}function h(a,s,l,c){var u=$(l);if("function"!=typeof u)throw Error(i(150));if(null==(l=u.call(l)))throw Error(i(151));for(var d=u=null,g=s,h=s=0,b=null,v=l.next();null!==g&&!v.done;h++,v=l.next()){g.index>h?(b=g,g=null):b=g.sibling;var y=f(a,g,v.value,c);if(null===y){null===g&&(g=b);break}e&&g&&null===y.alternate&&t(a,g),s=o(y,s,h),null===d?u=y:d.sibling=y,d=y,g=b}if(v.done)return n(a,g),u;if(null===g){for(;!v.done;h++,v=l.next())null!==(v=p(a,v.value,c))&&(s=o(v,s,h),null===d?u=v:d.sibling=v,d=v);return u}for(g=r(a,g);!v.done;h++,v=l.next())null!==(v=m(g,a,h,v.value,c))&&(e&&null!==v.alternate&&g.delete(null===v.key?h:v.key),s=o(v,s,h),null===d?u=v:d.sibling=v,d=v);return e&&g.forEach((function(e){return t(a,e)})),u}return function(e,r,o,l){var c="object"==typeof o&&null!==o&&o.type===_&&null===o.key;c&&(o=o.props.children);var u="object"==typeof o&&null!==o;if(u)switch(o.$$typeof){case S:e:{for(u=o.key,c=r;null!==c;){if(c.key===u){if(7===c.tag){if(o.type===_){n(e,c.sibling),(r=a(c,o.props.children)).return=e,e=r;break e}}else if(c.elementType===o.type){n(e,c.sibling),(r=a(c,o.props)).ref=Eo(e,c,o),r.return=e,e=r;break e}n(e,c);break}t(e,c),c=c.sibling}o.type===_?((r=Wl(o.props.children,e.mode,l,o.key)).return=e,e=r):((l=Vl(o.type,o.key,o.props,null,e.mode,l)).ref=Eo(e,r,o),l.return=e,e=l)}return s(e);case E:e:{for(c=o.key;null!==r;){if(r.key===c){if(4===r.tag&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),(r=a(r,o.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Ql(o,e.mode,l)).return=e,e=r}return s(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==r&&6===r.tag?(n(e,r.sibling),(r=a(r,o)).return=e,e=r):(n(e,r),(r=Kl(o,e.mode,l)).return=e,e=r),s(e);if(So(o))return g(e,r,o,l);if($(o))return h(e,r,o,l);if(u&&_o(e,o),void 0===o&&!c)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,V(e.type)||"Component"))}return n(e,r)}}var Co=xo(!0),To=xo(!1),Lo={},Ao=la(Lo),Po=la(Lo),Ro=la(Lo);function No(e){if(e===Lo)throw Error(i(174));return e}function Oo(e,t){switch(ua(Ro,t),ua(Po,e),ua(Ao,Lo),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:fe(null,"");break;default:t=fe(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}ca(Ao),ua(Ao,t)}function Io(){ca(Ao),ca(Po),ca(Ro)}function Do(e){No(Ro.current);var t=No(Ao.current),n=fe(t,e.type);t!==n&&(ua(Po,e),ua(Ao,n))}function Mo(e){Po.current===e&&(ca(Ao),ca(Po))}var jo=la(0);function Fo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Bo=null,zo=null,Uo=!1;function $o(e,t){var n=Gl(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function qo(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function Go(e){if(Uo){var t=zo;if(t){var n=t;if(!qo(e,t)){if(!(t=Vr(n.nextSibling))||!qo(e,t))return e.flags=-1025&e.flags|2,Uo=!1,void(Bo=e);$o(Bo,n)}Bo=e,zo=Vr(t.firstChild)}else e.flags=-1025&e.flags|2,Uo=!1,Bo=e}}function Ho(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;Bo=e}function Zo(e){if(e!==Bo)return!1;if(!Uo)return Ho(e),Uo=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!qr(t,e.memoizedProps))for(t=zo;t;)$o(e,t),t=Vr(t.nextSibling);if(Ho(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){zo=Vr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}zo=null}}else zo=Bo?Vr(e.stateNode.nextSibling):null;return!0}function Vo(){zo=Bo=null,Uo=!1}var Wo=[];function Yo(){for(var e=0;e<Wo.length;e++)Wo[e]._workInProgressVersionPrimary=null;Wo.length=0}var Ko=k.ReactCurrentDispatcher,Qo=k.ReactCurrentBatchConfig,Xo=0,Jo=null,ei=null,ti=null,ni=!1,ri=!1;function ai(){throw Error(i(321))}function oi(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!cr(e[n],t[n]))return!1;return!0}function ii(e,t,n,r,a,o){if(Xo=o,Jo=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Ko.current=null===e||null===e.memoizedState?Ni:Oi,e=n(r,a),ri){o=0;do{if(ri=!1,!(25>o))throw Error(i(301));o+=1,ti=ei=null,t.updateQueue=null,Ko.current=Ii,e=n(r,a)}while(ri)}if(Ko.current=Ri,t=null!==ei&&null!==ei.next,Xo=0,ti=ei=Jo=null,ni=!1,t)throw Error(i(300));return e}function si(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ti?Jo.memoizedState=ti=e:ti=ti.next=e,ti}function li(){if(null===ei){var e=Jo.alternate;e=null!==e?e.memoizedState:null}else e=ei.next;var t=null===ti?Jo.memoizedState:ti.next;if(null!==t)ti=t,ei=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ei=e).memoizedState,baseState:ei.baseState,baseQueue:ei.baseQueue,queue:ei.queue,next:null},null===ti?Jo.memoizedState=ti=e:ti=ti.next=e}return ti}function ci(e,t){return"function"==typeof t?t(e):t}function ui(e){var t=li(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=ei,a=r.baseQueue,o=n.pending;if(null!==o){if(null!==a){var s=a.next;a.next=o.next,o.next=s}r.baseQueue=a=o,n.pending=null}if(null!==a){a=a.next,r=r.baseState;var l=s=o=null,c=a;do{var u=c.lane;if((Xo&u)===u)null!==l&&(l=l.next={lane:0,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null}),r=c.eagerReducer===e?c.eagerState:e(r,c.action);else{var d={lane:u,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null};null===l?(s=l=d,o=r):l=l.next=d,Jo.lanes|=u,Us|=u}c=c.next}while(null!==c&&c!==a);null===l?o=r:l.next=s,cr(r,t.memoizedState)||(Mi=!0),t.memoizedState=r,t.baseState=o,t.baseQueue=l,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function di(e){var t=li(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(null!==a){n.pending=null;var s=a=a.next;do{o=e(o,s.action),s=s.next}while(s!==a);cr(o,t.memoizedState)||(Mi=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function pi(e,t,n){var r=t._getVersion;r=r(t._source);var a=t._workInProgressVersionPrimary;if(null!==a?e=a===r:(e=e.mutableReadLanes,(e=(Xo&e)===e)&&(t._workInProgressVersionPrimary=r,Wo.push(t))),e)return n(t._source);throw Wo.push(t),Error(i(350))}function fi(e,t,n,r){var a=Os;if(null===a)throw Error(i(349));var o=t._getVersion,s=o(t._source),l=Ko.current,c=l.useState((function(){return pi(a,t,n)})),u=c[1],d=c[0];c=ti;var p=e.memoizedState,f=p.refs,m=f.getSnapshot,g=p.source;p=p.subscribe;var h=Jo;return e.memoizedState={refs:f,source:t,subscribe:r},l.useEffect((function(){f.getSnapshot=n,f.setSnapshot=u;var e=o(t._source);if(!cr(s,e)){e=n(t._source),cr(d,e)||(u(e),e=fl(h),a.mutableReadLanes|=e&a.pendingLanes),e=a.mutableReadLanes,a.entangledLanes|=e;for(var r=a.entanglements,i=e;0<i;){var l=31-qt(i),c=1<<l;r[l]|=e,i&=~c}}}),[n,t,r]),l.useEffect((function(){return r(t._source,(function(){var e=f.getSnapshot,n=f.setSnapshot;try{n(e(t._source));var r=fl(h);a.mutableReadLanes|=r&a.pendingLanes}catch(o){n((function(){throw o}))}}))}),[t,r]),cr(m,n)&&cr(g,t)&&cr(p,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:d}).dispatch=u=Pi.bind(null,Jo,e),c.queue=e,c.baseQueue=null,d=pi(a,t,n),c.memoizedState=c.baseState=d),d}function mi(e,t,n){return fi(li(),e,t,n)}function gi(e){var t=si();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:e}).dispatch=Pi.bind(null,Jo,e),[t.memoizedState,e]}function hi(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=Jo.updateQueue)?(t={lastEffect:null},Jo.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function bi(e){return e={current:e},si().memoizedState=e}function vi(){return li().memoizedState}function yi(e,t,n,r){var a=si();Jo.flags|=e,a.memoizedState=hi(1|t,n,void 0,void 0===r?null:r)}function wi(e,t,n,r){var a=li();r=void 0===r?null:r;var o=void 0;if(null!==ei){var i=ei.memoizedState;if(o=i.destroy,null!==r&&oi(r,i.deps))return void hi(t,n,o,r)}Jo.flags|=e,a.memoizedState=hi(1|t,n,o,r)}function ki(e,t){return yi(516,4,e,t)}function Si(e,t){return wi(516,4,e,t)}function Ei(e,t){return wi(4,2,e,t)}function _i(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function xi(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,_i.bind(null,t,e),n)}function Ci(){}function Ti(e,t){var n=li();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Li(e,t){var n=li();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Ai(e,t){var n=qa();Ha(98>n?98:n,(function(){e(!0)})),Ha(97<n?97:n,(function(){var n=Qo.transition;Qo.transition=1;try{e(!1),t()}finally{Qo.transition=n}}))}function Pi(e,t,n){var r=pl(),a=fl(e),o={lane:a,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?o.next=o:(o.next=i.next,i.next=o),t.pending=o,i=e.alternate,e===Jo||null!==i&&i===Jo)ri=ni=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var s=t.lastRenderedState,l=i(s,n);if(o.eagerReducer=i,o.eagerState=l,cr(l,s))return}catch(c){}ml(e,a,r)}}var Ri={readContext:oo,useCallback:ai,useContext:ai,useEffect:ai,useImperativeHandle:ai,useLayoutEffect:ai,useMemo:ai,useReducer:ai,useRef:ai,useState:ai,useDebugValue:ai,useDeferredValue:ai,useTransition:ai,useMutableSource:ai,useOpaqueIdentifier:ai,unstable_isNewReconciler:!1},Ni={readContext:oo,useCallback:function(e,t){return si().memoizedState=[e,void 0===t?null:t],e},useContext:oo,useEffect:ki,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,yi(4,2,_i.bind(null,t,e),n)},useLayoutEffect:function(e,t){return yi(4,2,e,t)},useMemo:function(e,t){var n=si();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=si();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Pi.bind(null,Jo,e),[r.memoizedState,e]},useRef:bi,useState:gi,useDebugValue:Ci,useDeferredValue:function(e){var t=gi(e),n=t[0],r=t[1];return ki((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=gi(!1),t=e[0];return bi(e=Ai.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var r=si();return r.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},fi(r,e,t,n)},useOpaqueIdentifier:function(){if(Uo){var e=!1,t=function(e){return{$$typeof:D,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Yr++).toString(36))),Error(i(355))})),n=gi(t)[1];return 0==(2&Jo.mode)&&(Jo.flags|=516,hi(5,(function(){n("r:"+(Yr++).toString(36))}),void 0,null)),t}return gi(t="r:"+(Yr++).toString(36)),t},unstable_isNewReconciler:!1},Oi={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:ui,useRef:vi,useState:function(){return ui(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=ui(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=ui(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return ui(ci)[0]},unstable_isNewReconciler:!1},Ii={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:di,useRef:vi,useState:function(){return di(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=di(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=di(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ci)[0]},unstable_isNewReconciler:!1},Di=k.ReactCurrentOwner,Mi=!1;function ji(e,t,n,r){t.child=null===e?To(t,null,n,r):Co(t,e.child,n,r)}function Fi(e,t,n,r,a){n=n.render;var o=t.ref;return ao(t,a),r=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,r,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,os(e,t,a))}function Bi(e,t,n,r,a,o){if(null===e){var i=n.type;return"function"!=typeof i||Hl(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Vl(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,zi(e,t,i,r,a,o))}return i=e.child,0==(a&o)&&(a=i.memoizedProps,(n=null!==(n=n.compare)?n:dr)(a,r)&&e.ref===t.ref)?os(e,t,o):(t.flags|=1,(e=Zl(i,r)).ref=t.ref,e.return=t,t.child=e)}function zi(e,t,n,r,a,o){if(null!==e&&dr(e.memoizedProps,r)&&e.ref===t.ref){if(Mi=!1,0==(o&a))return t.lanes=e.lanes,os(e,t,o);0!=(16384&e.flags)&&(Mi=!0)}return qi(e,t,n,r,o)}function Ui(e,t,n){var r=t.pendingProps,a=r.children,o=null!==e?e.memoizedState:null;if("hidden"===r.mode||"unstable-defer-without-hiding"===r.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},Sl(t,n);else{if(0==(1073741824&n))return e=null!==o?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},Sl(t,e),null;t.memoizedState={baseLanes:0},Sl(t,null!==o?o.baseLanes:n)}else null!==o?(r=o.baseLanes|n,t.memoizedState=null):r=n,Sl(t,r);return ji(e,t,a,n),t.child}function $i(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function qi(e,t,n,r,a){var o=ha(n)?ma:pa.current;return o=ga(t,o),ao(t,a),n=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,n,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,os(e,t,a))}function Gi(e,t,n,r,a){if(ha(n)){var o=!0;wa(t)}else o=!1;if(ao(t,a),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),yo(t,n,r),ko(t,n,r,a),r=!0;else if(null===e){var i=t.stateNode,s=t.memoizedProps;i.props=s;var l=i.context,c=n.contextType;"object"==typeof c&&null!==c?c=oo(c):c=ga(t,c=ha(n)?ma:pa.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==r||l!==c)&&wo(t,i,r,c),io=!1;var p=t.memoizedState;i.state=p,fo(t,r,i,a),l=t.memoizedState,s!==r||p!==l||fa.current||io?("function"==typeof u&&(ho(t,n,u,r),l=t.memoizedState),(s=io||vo(t,n,s,r,p,l,c))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=r,t.memoizedState=l),i.props=r,i.state=l,i.context=c,r=s):("function"==typeof i.componentDidMount&&(t.flags|=4),r=!1)}else{i=t.stateNode,lo(e,t),s=t.memoizedProps,c=t.type===t.elementType?s:Ka(t.type,s),i.props=c,d=t.pendingProps,p=i.context,"object"==typeof(l=n.contextType)&&null!==l?l=oo(l):l=ga(t,l=ha(n)?ma:pa.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==d||p!==l)&&wo(t,i,r,l),io=!1,p=t.memoizedState,i.state=p,fo(t,r,i,a);var m=t.memoizedState;s!==d||p!==m||fa.current||io?("function"==typeof f&&(ho(t,n,f,r),m=t.memoizedState),(c=io||vo(t,n,c,r,p,m,l))?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,m,l),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,m,l)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),t.memoizedProps=r,t.memoizedState=m),i.props=r,i.state=m,i.context=l,r=c):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),r=!1)}return Hi(e,t,n,r,o,a)}function Hi(e,t,n,r,a,o){$i(e,t);var i=0!=(64&t.flags);if(!r&&!i)return a&&ka(t,n,!1),os(e,t,o);r=t.stateNode,Di.current=t;var s=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=Co(t,e.child,null,o),t.child=Co(t,null,s,o)):ji(e,t,s,o),t.memoizedState=r.state,a&&ka(t,n,!0),t.child}function Zi(e){var t=e.stateNode;t.pendingContext?va(0,t.pendingContext,t.pendingContext!==t.context):t.context&&va(0,t.context,!1),Oo(e,t.containerInfo)}var Vi,Wi,Yi,Ki,Qi={dehydrated:null,retryLane:0};function Xi(e,t,n){var r,a=t.pendingProps,o=jo.current,i=!1;return(r=0!=(64&t.flags))||(r=(null===e||null!==e.memoizedState)&&0!=(2&o)),r?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===a.fallback||!0===a.unstable_avoidThisFallback||(o|=1),ua(jo,1&o),null===e?(void 0!==a.fallback&&Go(t),e=a.children,o=a.fallback,i?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,e):"number"==typeof a.unstable_expectedLoadTime?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,t.lanes=33554432,e):((n=Yl({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(a=ts(e,t,a.children,a.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=null===o?{baseLanes:n}:{baseLanes:o.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Qi,a):(n=es(e,t,a.children,n),t.memoizedState=null,n))}function Ji(e,t,n,r){var a=e.mode,o=e.child;return t={mode:"hidden",children:t},0==(2&a)&&null!==o?(o.childLanes=0,o.pendingProps=t):o=Yl(t,a,0,null),n=Wl(n,a,r,null),o.return=e,n.return=e,o.sibling=n,e.child=o,n}function es(e,t,n,r){var a=e.child;return e=a.sibling,n=Zl(a,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=r),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function ts(e,t,n,r,a){var o=t.mode,i=e.child;e=i.sibling;var s={mode:"hidden",children:n};return 0==(2&o)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=s,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=Zl(i,s),null!==e?r=Zl(e,r):(r=Wl(r,o,a,null)).flags|=2,r.return=t,n.return=t,n.sibling=r,t.child=n,r}function ns(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),ro(e.return,t)}function rs(e,t,n,r,a,o){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:a,lastEffect:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=a,i.lastEffect=o)}function as(e,t,n){var r=t.pendingProps,a=r.revealOrder,o=r.tail;if(ji(e,t,r.children,n),0!=(2&(r=jo.current)))r=1&r|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&ns(e,n);else if(19===e.tag)ns(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(ua(jo,r),0==(2&t.mode))t.memoizedState=null;else switch(a){case"forwards":for(n=t.child,a=null;null!==n;)null!==(e=n.alternate)&&null===Fo(e)&&(a=n),n=n.sibling;null===(n=a)?(a=t.child,t.child=null):(a=n.sibling,n.sibling=null),rs(t,!1,a,n,o,t.lastEffect);break;case"backwards":for(n=null,a=t.child,t.child=null;null!==a;){if(null!==(e=a.alternate)&&null===Fo(e)){t.child=a;break}e=a.sibling,a.sibling=n,n=a,a=e}rs(t,!0,n,null,o,t.lastEffect);break;case"together":rs(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function os(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Us|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Zl(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Zl(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function is(e,t){if(!Uo)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ss(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return ha(t.type)&&ba(),null;case 3:return Io(),ca(fa),ca(pa),Yo(),(r=t.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Zo(t)?t.flags|=4:r.hydrate||(t.flags|=256)),Wi(t),null;case 5:Mo(t);var o=No(Ro.current);if(n=t.type,null!==e&&null!=t.stateNode)Yi(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=128);else{if(!r){if(null===t.stateNode)throw Error(i(166));return null}if(e=No(Ao.current),Zo(t)){r=t.stateNode,n=t.type;var s=t.memoizedProps;switch(r[Qr]=t,r[Xr]=s,n){case"dialog":Ar("cancel",r),Ar("close",r);break;case"iframe":case"object":case"embed":Ar("load",r);break;case"video":case"audio":for(e=0;e<xr.length;e++)Ar(xr[e],r);break;case"source":Ar("error",r);break;case"img":case"image":case"link":Ar("error",r),Ar("load",r);break;case"details":Ar("toggle",r);break;case"input":ee(r,s),Ar("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!s.multiple},Ar("invalid",r);break;case"textarea":le(r,s),Ar("invalid",r)}for(var c in Ee(n,s),e=null,s)s.hasOwnProperty(c)&&(o=s[c],"children"===c?"string"==typeof o?r.textContent!==o&&(e=["children",o]):"number"==typeof o&&r.textContent!==""+o&&(e=["children",""+o]):l.hasOwnProperty(c)&&null!=o&&"onScroll"===c&&Ar("scroll",r));switch(n){case"input":K(r),re(r,s,!0);break;case"textarea":K(r),ue(r);break;case"select":case"option":break;default:"function"==typeof s.onClick&&(r.onclick=Br)}r=e,t.updateQueue=r,null!==r&&(t.flags|=4)}else{switch(c=9===o.nodeType?o:o.ownerDocument,e===de.html&&(e=pe(n)),e===de.html?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[Qr]=t,e[Xr]=r,Vi(e,t,!1,!1),t.stateNode=e,c=_e(n,r),n){case"dialog":Ar("cancel",e),Ar("close",e),o=r;break;case"iframe":case"object":case"embed":Ar("load",e),o=r;break;case"video":case"audio":for(o=0;o<xr.length;o++)Ar(xr[o],e);o=r;break;case"source":Ar("error",e),o=r;break;case"img":case"image":case"link":Ar("error",e),Ar("load",e),o=r;break;case"details":Ar("toggle",e),o=r;break;case"input":ee(e,r),o=J(e,r),Ar("invalid",e);break;case"option":o=oe(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=a({},r,{value:void 0}),Ar("invalid",e);break;case"textarea":le(e,r),o=se(e,r),Ar("invalid",e);break;default:o=r}Ee(n,o);var u=o;for(s in u)if(u.hasOwnProperty(s)){var d=u[s];"style"===s?ke(e,d):"dangerouslySetInnerHTML"===s?null!=(d=d?d.__html:void 0)&&he(e,d):"children"===s?"string"==typeof d?("textarea"!==n||""!==d)&&be(e,d):"number"==typeof d&&be(e,""+d):"suppressContentEditableWarning"!==s&&"suppressHydrationWarning"!==s&&"autoFocus"!==s&&(l.hasOwnProperty(s)?null!=d&&"onScroll"===s&&Ar("scroll",e):null!=d&&w(e,s,d,c))}switch(n){case"input":K(e),re(e,r,!1);break;case"textarea":K(e),ue(e);break;case"option":null!=r.value&&e.setAttribute("value",""+W(r.value));break;case"select":e.multiple=!!r.multiple,null!=(s=r.value)?ie(e,!!r.multiple,s,!1):null!=r.defaultValue&&ie(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Br)}$r(n,r)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Ki(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));n=No(Ro.current),No(Ao.current),Zo(t)?(r=t.stateNode,n=t.memoizedProps,r[Qr]=t,r.nodeValue!==n&&(t.flags|=4)):((r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[Qr]=t,t.stateNode=r)}return null;case 13:return ca(jo),r=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(r=null!==r,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Zo(t):n=null!==e.memoizedState,r&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&jo.current)?0===Fs&&(Fs=3):(0!==Fs&&3!==Fs||(Fs=4),null===Os||0==(134217727&Us)&&0==(134217727&$s)||vl(Os,Ds))),(r||n)&&(t.flags|=4),null);case 4:return Io(),Wi(t),null===e&&Rr(t.stateNode.containerInfo),null;case 10:return no(t),null;case 19:if(ca(jo),null===(r=t.memoizedState))return null;if(s=0!=(64&t.flags),null===(c=r.rendering))if(s)is(r,!1);else{if(0!==Fs||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(c=Fo(e))){for(t.flags|=64,is(r,!1),null!==(s=c.updateQueue)&&(t.updateQueue=s,t.flags|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=n,n=t.child;null!==n;)e=r,(s=n).flags&=2,s.nextEffect=null,s.firstEffect=null,s.lastEffect=null,null===(c=s.alternate)?(s.childLanes=0,s.lanes=e,s.child=null,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=c.childLanes,s.lanes=c.lanes,s.child=c.child,s.memoizedProps=c.memoizedProps,s.memoizedState=c.memoizedState,s.updateQueue=c.updateQueue,s.type=c.type,e=c.dependencies,s.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return ua(jo,1&jo.current|2),t.child}e=e.sibling}null!==r.tail&&$a()>Zs&&(t.flags|=64,s=!0,is(r,!1),t.lanes=33554432)}else{if(!s)if(null!==(e=Fo(c))){if(t.flags|=64,s=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),is(r,!0),null===r.tail&&"hidden"===r.tailMode&&!c.alternate&&!Uo)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*$a()-r.renderingStartTime>Zs&&1073741824!==n&&(t.flags|=64,s=!0,is(r,!1),t.lanes=33554432);r.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=r.last)?n.sibling=c:t.child=c,r.last=c)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=$a(),n.sibling=null,t=jo.current,ua(jo,s?1&t|2:1&t),n):null;case 23:case 24:return El(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function ls(e){switch(e.tag){case 1:ha(e.type)&&ba();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Io(),ca(fa),ca(pa),Yo(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Mo(e),null;case 13:return ca(jo),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return ca(jo),null;case 4:return Io(),null;case 10:return no(e),null;case 23:case 24:return El(),null;default:return null}}function cs(e,t){try{var n="",r=t;do{n+=Z(r),r=r.return}while(r);var a=n}catch(o){a="\nError generating stack: "+o.message+"\n"+o.stack}return{value:e,source:t,stack:a}}function us(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Vi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Wi=function(){},Yi=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,No(Ao.current);var i,s=null;switch(n){case"input":o=J(e,o),r=J(e,r),s=[];break;case"option":o=oe(e,o),r=oe(e,r),s=[];break;case"select":o=a({},o,{value:void 0}),r=a({},r,{value:void 0}),s=[];break;case"textarea":o=se(e,o),r=se(e,r),s=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Br)}for(d in Ee(n,r),n=null,o)if(!r.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(i in c)c.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(l.hasOwnProperty(d)?s||(s=[]):(s=s||[]).push(d,null));for(d in r){var u=r[d];if(c=null!=o?o[d]:void 0,r.hasOwnProperty(d)&&u!==c&&(null!=u||null!=c))if("style"===d)if(c){for(i in c)!c.hasOwnProperty(i)||u&&u.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in u)u.hasOwnProperty(i)&&c[i]!==u[i]&&(n||(n={}),n[i]=u[i])}else n||(s||(s=[]),s.push(d,n)),n=u;else"dangerouslySetInnerHTML"===d?(u=u?u.__html:void 0,c=c?c.__html:void 0,null!=u&&c!==u&&(s=s||[]).push(d,u)):"children"===d?"string"!=typeof u&&"number"!=typeof u||(s=s||[]).push(d,""+u):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(l.hasOwnProperty(d)?(null!=u&&"onScroll"===d&&Ar("scroll",e),s||c===u||(s=[])):"object"==typeof u&&null!==u&&u.$$typeof===D?u.toString():(s=s||[]).push(d,u))}n&&(s=s||[]).push("style",n);var d=s;(t.updateQueue=d)&&(t.flags|=4)}},Ki=function(e,t,n,r){n!==r&&(t.flags|=4)};var ds="function"==typeof WeakMap?WeakMap:Map;function ps(e,t,n){(n=co(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Ks||(Ks=!0,Qs=r),us(0,t)},n}function fs(e,t,n){(n=co(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var a=t.value;n.payload=function(){return us(0,t),r(a)}}var o=e.stateNode;return null!==o&&"function"==typeof o.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Xs?Xs=new Set([this]):Xs.add(this),us(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var ms="function"==typeof WeakSet?WeakSet:Set;function gs(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){zl(e,n)}else t.current=null}function hs(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ka(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Zr(t.stateNode.containerInfo))}throw Error(i(163))}function bs(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var a=e;r=a.next,0!=(4&(a=a.tag))&&0!=(1&a)&&(jl(n,e),Ml(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ka(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&mo(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}mo(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&$r(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&kt(n)))))}throw Error(i(163))}function vs(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var a=n.memoizedProps.style;a=null!=a&&a.hasOwnProperty("display")?a.display:null,r.style.display=we("display",a)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function ys(e,t){if(Ea&&"function"==typeof Ea.onCommitFiberUnmount)try{Ea.onCommitFiberUnmount(Sa,t)}catch(o){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,a=r.destroy;if(r=r.tag,void 0!==a)if(0!=(4&r))jl(t,n);else{r=t;try{a()}catch(o){zl(r,o)}}n=n.next}while(n!==e)}break;case 1:if(gs(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(o){zl(t,o)}break;case 5:gs(t);break;case 4:xs(e,t)}}function ws(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function ks(e){return 5===e.tag||3===e.tag||4===e.tag}function Ss(e){e:{for(var t=e.return;null!==t;){if(ks(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(i(161))}16&n.flags&&(be(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||ks(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?Es(e,n,t):_s(e,n,t)}function Es(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Br));else if(4!==r&&null!==(e=e.child))for(Es(e,t,n),e=e.sibling;null!==e;)Es(e,t,n),e=e.sibling}function _s(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(_s(e,t,n),e=e.sibling;null!==e;)_s(e,t,n),e=e.sibling}function xs(e,t){for(var n,r,a=t,o=!1;;){if(!o){o=a.return;e:for(;;){if(null===o)throw Error(i(160));switch(n=o.stateNode,o.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}o=o.return}o=!0}if(5===a.tag||6===a.tag){e:for(var s=e,l=a,c=l;;)if(ys(s,c),null!==c.child&&4!==c.tag)c.child.return=c,c=c.child;else{if(c===l)break e;for(;null===c.sibling;){if(null===c.return||c.return===l)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}r?(s=n,l=a.stateNode,8===s.nodeType?s.parentNode.removeChild(l):s.removeChild(l)):n.removeChild(a.stateNode)}else if(4===a.tag){if(null!==a.child){n=a.stateNode.containerInfo,r=!0,a.child.return=a,a=a.child;continue}}else if(ys(e,a),null!==a.child){a.child.return=a,a=a.child;continue}if(a===t)break;for(;null===a.sibling;){if(null===a.return||a.return===t)return;4===(a=a.return).tag&&(o=!1)}a.sibling.return=a.return,a=a.sibling}}function Cs(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var a=null!==e?e.memoizedProps:r;e=t.type;var o=t.updateQueue;if(t.updateQueue=null,null!==o){for(n[Xr]=r,"input"===e&&"radio"===r.type&&null!=r.name&&te(n,r),_e(e,a),t=_e(e,r),a=0;a<o.length;a+=2){var s=o[a],l=o[a+1];"style"===s?ke(n,l):"dangerouslySetInnerHTML"===s?he(n,l):"children"===s?be(n,l):w(n,s,l,t)}switch(e){case"input":ne(n,r);break;case"textarea":ce(n,r);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(o=r.value)?ie(n,!!r.multiple,o,!1):e!==!!r.multiple&&(null!=r.defaultValue?ie(n,!!r.multiple,r.defaultValue,!0):ie(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,kt(n.containerInfo)));case 13:return null!==t.memoizedState&&(Hs=$a(),vs(t.child,!0)),void Ts(t);case 19:return void Ts(t);case 23:case 24:return void vs(t,null!==t.memoizedState)}throw Error(i(163))}function Ts(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new ms),t.forEach((function(t){var r=$l.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function Ls(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var As=Math.ceil,Ps=k.ReactCurrentDispatcher,Rs=k.ReactCurrentOwner,Ns=0,Os=null,Is=null,Ds=0,Ms=0,js=la(0),Fs=0,Bs=null,zs=0,Us=0,$s=0,qs=0,Gs=null,Hs=0,Zs=1/0;function Vs(){Zs=$a()+500}var Ws,Ys=null,Ks=!1,Qs=null,Xs=null,Js=!1,el=null,tl=90,nl=[],rl=[],al=null,ol=0,il=null,sl=-1,ll=0,cl=0,ul=null,dl=!1;function pl(){return 0!=(48&Ns)?$a():-1!==sl?sl:sl=$a()}function fl(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===qa()?1:2;if(0===ll&&(ll=zs),0!==Ya.transition){0!==cl&&(cl=null!==Gs?Gs.pendingLanes:0),e=ll;var t=4186112&~cl;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=qa(),0!=(4&Ns)&&98===e?e=Bt(12,ll):e=Bt(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ll),e}function ml(e,t,n){if(50<ol)throw ol=0,il=null,Error(i(185));if(null===(e=gl(e,t)))return null;$t(e,t,n),e===Os&&($s|=t,4===Fs&&vl(e,Ds));var r=qa();1===t?0!=(8&Ns)&&0==(48&Ns)?yl(e):(hl(e,n),0===Ns&&(Vs(),Va())):(0==(4&Ns)||98!==r&&99!==r||(null===al?al=new Set([e]):al.add(e)),hl(e,n)),Gs=e}function gl(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function hl(e,t){for(var n=e.callbackNode,r=e.suspendedLanes,a=e.pingedLanes,o=e.expirationTimes,s=e.pendingLanes;0<s;){var l=31-qt(s),c=1<<l,u=o[l];if(-1===u){if(0==(c&r)||0!=(c&a)){u=t,Mt(c);var d=Dt;o[l]=10<=d?u+250:6<=d?u+5e3:-1}}else u<=t&&(e.expiredLanes|=c);s&=~c}if(r=jt(e,e===Os?Ds:0),t=Dt,0===r)null!==n&&(n!==Ma&&Ca(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Ma&&Ca(n)}15===t?(n=yl.bind(null,e),null===Fa?(Fa=[n],Ba=xa(Ra,Wa)):Fa.push(n),n=Ma):14===t?n=Za(99,yl.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Za(n,bl.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function bl(e){if(sl=-1,cl=ll=0,0!=(48&Ns))throw Error(i(327));var t=e.callbackNode;if(Dl()&&e.callbackNode!==t)return null;var n=jt(e,e===Os?Ds:0);if(0===n)return null;var r=n,a=Ns;Ns|=16;var o=Cl();for(Os===e&&Ds===r||(Vs(),_l(e,r));;)try{Al();break}catch(l){xl(e,l)}if(to(),Ps.current=o,Ns=a,null!==Is?r=0:(Os=null,Ds=0,r=Fs),0!=(zs&$s))_l(e,0);else if(0!==r){if(2===r&&(Ns|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(n=Ft(e))&&(r=Tl(e,n))),1===r)throw t=Bs,_l(e,0),vl(e,n),hl(e,$a()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,r){case 0:case 1:throw Error(i(345));case 2:case 5:Nl(e);break;case 3:if(vl(e,n),(62914560&n)===n&&10<(r=Hs+500-$a())){if(0!==jt(e,0))break;if(((a=e.suspendedLanes)&n)!==n){pl(),e.pingedLanes|=e.suspendedLanes&a;break}e.timeoutHandle=Gr(Nl.bind(null,e),r);break}Nl(e);break;case 4:if(vl(e,n),(4186112&n)===n)break;for(r=e.eventTimes,a=-1;0<n;){var s=31-qt(n);o=1<<s,(s=r[s])>a&&(a=s),n&=~o}if(n=a,10<(n=(120>(n=$a()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*As(n/1960))-n)){e.timeoutHandle=Gr(Nl.bind(null,e),n);break}Nl(e);break;default:throw Error(i(329))}}return hl(e,$a()),e.callbackNode===t?bl.bind(null,e):null}function vl(e,t){for(t&=~qs,t&=~$s,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-qt(t),r=1<<n;e[n]=-1,t&=~r}}function yl(e){if(0!=(48&Ns))throw Error(i(327));if(Dl(),e===Os&&0!=(e.expiredLanes&Ds)){var t=Ds,n=Tl(e,t);0!=(zs&$s)&&(n=Tl(e,t=jt(e,t)))}else n=Tl(e,t=jt(e,0));if(0!==e.tag&&2===n&&(Ns|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(t=Ft(e))&&(n=Tl(e,t))),1===n)throw n=Bs,_l(e,0),vl(e,t),hl(e,$a()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,Nl(e),hl(e,$a()),null}function wl(e,t){var n=Ns;Ns|=1;try{return e(t)}finally{0===(Ns=n)&&(Vs(),Va())}}function kl(e,t){var n=Ns;Ns&=-2,Ns|=8;try{return e(t)}finally{0===(Ns=n)&&(Vs(),Va())}}function Sl(e,t){ua(js,Ms),Ms|=t,zs|=t}function El(){Ms=js.current,ca(js)}function _l(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,Hr(n)),null!==Is)for(n=Is.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&ba();break;case 3:Io(),ca(fa),ca(pa),Yo();break;case 5:Mo(r);break;case 4:Io();break;case 13:case 19:ca(jo);break;case 10:no(r);break;case 23:case 24:El()}n=n.return}Os=e,Is=Zl(e.current,null),Ds=Ms=zs=t,Fs=0,Bs=null,qs=$s=Us=0}function xl(e,t){for(;;){var n=Is;try{if(to(),Ko.current=Ri,ni){for(var r=Jo.memoizedState;null!==r;){var a=r.queue;null!==a&&(a.pending=null),r=r.next}ni=!1}if(Xo=0,ti=ei=Jo=null,ri=!1,Rs.current=null,null===n||null===n.return){Fs=1,Bs=t,Is=null;break}e:{var o=e,i=n.return,s=n,l=t;if(t=Ds,s.flags|=2048,s.firstEffect=s.lastEffect=null,null!==l&&"object"==typeof l&&"function"==typeof l.then){var c=l;if(0==(2&s.mode)){var u=s.alternate;u?(s.updateQueue=u.updateQueue,s.memoizedState=u.memoizedState,s.lanes=u.lanes):(s.updateQueue=null,s.memoizedState=null)}var d=0!=(1&jo.current),p=i;do{var f;if(f=13===p.tag){var m=p.memoizedState;if(null!==m)f=null!==m.dehydrated;else{var g=p.memoizedProps;f=void 0!==g.fallback&&(!0!==g.unstable_avoidThisFallback||!d)}}if(f){var h=p.updateQueue;if(null===h){var b=new Set;b.add(c),p.updateQueue=b}else h.add(c);if(0==(2&p.mode)){if(p.flags|=64,s.flags|=16384,s.flags&=-2981,1===s.tag)if(null===s.alternate)s.tag=17;else{var v=co(-1,1);v.tag=2,uo(s,v)}s.lanes|=1;break e}l=void 0,s=t;var y=o.pingCache;if(null===y?(y=o.pingCache=new ds,l=new Set,y.set(c,l)):void 0===(l=y.get(c))&&(l=new Set,y.set(c,l)),!l.has(s)){l.add(s);var w=Ul.bind(null,o,c,s);c.then(w,w)}p.flags|=4096,p.lanes=t;break e}p=p.return}while(null!==p);l=Error((V(s.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Fs&&(Fs=2),l=cs(l,s),p=i;do{switch(p.tag){case 3:o=l,p.flags|=4096,t&=-t,p.lanes|=t,po(p,ps(0,o,t));break e;case 1:o=l;var k=p.type,S=p.stateNode;if(0==(64&p.flags)&&("function"==typeof k.getDerivedStateFromError||null!==S&&"function"==typeof S.componentDidCatch&&(null===Xs||!Xs.has(S)))){p.flags|=4096,t&=-t,p.lanes|=t,po(p,fs(p,o,t));break e}}p=p.return}while(null!==p)}Rl(n)}catch(E){t=E,Is===n&&null!==n&&(Is=n=n.return);continue}break}}function Cl(){var e=Ps.current;return Ps.current=Ri,null===e?Ri:e}function Tl(e,t){var n=Ns;Ns|=16;var r=Cl();for(Os===e&&Ds===t||_l(e,t);;)try{Ll();break}catch(a){xl(e,a)}if(to(),Ns=n,Ps.current=r,null!==Is)throw Error(i(261));return Os=null,Ds=0,Fs}function Ll(){for(;null!==Is;)Pl(Is)}function Al(){for(;null!==Is&&!Ta();)Pl(Is)}function Pl(e){var t=Ws(e.alternate,e,Ms);e.memoizedProps=e.pendingProps,null===t?Rl(e):Is=t,Rs.current=null}function Rl(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ss(n,t,Ms)))return void(Is=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&Ms)||0==(4&n.mode)){for(var r=0,a=n.child;null!==a;)r|=a.lanes|a.childLanes,a=a.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=ls(t)))return n.flags&=2047,void(Is=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Is=t);Is=t=e}while(null!==t);0===Fs&&(Fs=5)}function Nl(e){var t=qa();return Ha(99,Ol.bind(null,e,t)),null}function Ol(e,t){do{Dl()}while(null!==el);if(0!=(48&Ns))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var r=n.lanes|n.childLanes,a=r,o=e.pendingLanes&~a;e.pendingLanes=a,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=a,e.mutableReadLanes&=a,e.entangledLanes&=a,a=e.entanglements;for(var s=e.eventTimes,l=e.expirationTimes;0<o;){var c=31-qt(o),u=1<<c;a[c]=0,s[c]=-1,l[c]=-1,o&=~u}if(null!==al&&0==(24&r)&&al.has(e)&&al.delete(e),e===Os&&(Is=Os=null,Ds=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,r=n.firstEffect):r=n:r=n.firstEffect,null!==r){if(a=Ns,Ns|=32,Rs.current=null,zr=Wt,hr(s=gr())){if("selectionStart"in s)l={start:s.selectionStart,end:s.selectionEnd};else e:if(l=(l=s.ownerDocument)&&l.defaultView||window,(u=l.getSelection&&l.getSelection())&&0!==u.rangeCount){l=u.anchorNode,o=u.anchorOffset,c=u.focusNode,u=u.focusOffset;try{l.nodeType,c.nodeType}catch(C){l=null;break e}var d=0,p=-1,f=-1,m=0,g=0,h=s,b=null;t:for(;;){for(var v;h!==l||0!==o&&3!==h.nodeType||(p=d+o),h!==c||0!==u&&3!==h.nodeType||(f=d+u),3===h.nodeType&&(d+=h.nodeValue.length),null!==(v=h.firstChild);)b=h,h=v;for(;;){if(h===s)break t;if(b===l&&++m===o&&(p=d),b===c&&++g===u&&(f=d),null!==(v=h.nextSibling))break;b=(h=b).parentNode}h=v}l=-1===p||-1===f?null:{start:p,end:f}}else l=null;l=l||{start:0,end:0}}else l=null;Ur={focusedElem:s,selectionRange:l},Wt=!1,ul=null,dl=!1,Ys=r;do{try{Il()}catch(C){if(null===Ys)throw Error(i(330));zl(Ys,C),Ys=Ys.nextEffect}}while(null!==Ys);ul=null,Ys=r;do{try{for(s=e;null!==Ys;){var y=Ys.flags;if(16&y&&be(Ys.stateNode,""),128&y){var w=Ys.alternate;if(null!==w){var k=w.ref;null!==k&&("function"==typeof k?k(null):k.current=null)}}switch(1038&y){case 2:Ss(Ys),Ys.flags&=-3;break;case 6:Ss(Ys),Ys.flags&=-3,Cs(Ys.alternate,Ys);break;case 1024:Ys.flags&=-1025;break;case 1028:Ys.flags&=-1025,Cs(Ys.alternate,Ys);break;case 4:Cs(Ys.alternate,Ys);break;case 8:xs(s,l=Ys);var S=l.alternate;ws(l),null!==S&&ws(S)}Ys=Ys.nextEffect}}catch(C){if(null===Ys)throw Error(i(330));zl(Ys,C),Ys=Ys.nextEffect}}while(null!==Ys);if(k=Ur,w=gr(),y=k.focusedElem,s=k.selectionRange,w!==y&&y&&y.ownerDocument&&mr(y.ownerDocument.documentElement,y)){null!==s&&hr(y)&&(w=s.start,void 0===(k=s.end)&&(k=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(k,y.value.length)):(k=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(k=k.getSelection(),l=y.textContent.length,S=Math.min(s.start,l),s=void 0===s.end?S:Math.min(s.end,l),!k.extend&&S>s&&(l=s,s=S,S=l),l=fr(y,S),o=fr(y,s),l&&o&&(1!==k.rangeCount||k.anchorNode!==l.node||k.anchorOffset!==l.offset||k.focusNode!==o.node||k.focusOffset!==o.offset)&&((w=w.createRange()).setStart(l.node,l.offset),k.removeAllRanges(),S>s?(k.addRange(w),k.extend(o.node,o.offset)):(w.setEnd(o.node,o.offset),k.addRange(w))))),w=[];for(k=y;k=k.parentNode;)1===k.nodeType&&w.push({element:k,left:k.scrollLeft,top:k.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(k=w[y]).element.scrollLeft=k.left,k.element.scrollTop=k.top}Wt=!!zr,Ur=zr=null,e.current=n,Ys=r;do{try{for(y=e;null!==Ys;){var E=Ys.flags;if(36&E&&bs(y,Ys.alternate,Ys),128&E){w=void 0;var _=Ys.ref;if(null!==_){var x=Ys.stateNode;Ys.tag,w=x,"function"==typeof _?_(w):_.current=w}}Ys=Ys.nextEffect}}catch(C){if(null===Ys)throw Error(i(330));zl(Ys,C),Ys=Ys.nextEffect}}while(null!==Ys);Ys=null,ja(),Ns=a}else e.current=n;if(Js)Js=!1,el=e,tl=t;else for(Ys=r;null!==Ys;)t=Ys.nextEffect,Ys.nextEffect=null,8&Ys.flags&&((E=Ys).sibling=null,E.stateNode=null),Ys=t;if(0===(r=e.pendingLanes)&&(Xs=null),1===r?e===il?ol++:(ol=0,il=e):ol=0,n=n.stateNode,Ea&&"function"==typeof Ea.onCommitFiberRoot)try{Ea.onCommitFiberRoot(Sa,n,void 0,64==(64&n.current.flags))}catch(C){}if(hl(e,$a()),Ks)throw Ks=!1,e=Qs,Qs=null,e;return 0!=(8&Ns)||Va(),null}function Il(){for(;null!==Ys;){var e=Ys.alternate;dl||null===ul||(0!=(8&Ys.flags)?Je(Ys,ul)&&(dl=!0):13===Ys.tag&&Ls(e,Ys)&&Je(Ys,ul)&&(dl=!0));var t=Ys.flags;0!=(256&t)&&hs(e,Ys),0==(512&t)||Js||(Js=!0,Za(97,(function(){return Dl(),null}))),Ys=Ys.nextEffect}}function Dl(){if(90!==tl){var e=97<tl?97:tl;return tl=90,Ha(e,Fl)}return!1}function Ml(e,t){nl.push(t,e),Js||(Js=!0,Za(97,(function(){return Dl(),null})))}function jl(e,t){rl.push(t,e),Js||(Js=!0,Za(97,(function(){return Dl(),null})))}function Fl(){if(null===el)return!1;var e=el;if(el=null,0!=(48&Ns))throw Error(i(331));var t=Ns;Ns|=32;var n=rl;rl=[];for(var r=0;r<n.length;r+=2){var a=n[r],o=n[r+1],s=a.destroy;if(a.destroy=void 0,"function"==typeof s)try{s()}catch(c){if(null===o)throw Error(i(330));zl(o,c)}}for(n=nl,nl=[],r=0;r<n.length;r+=2){a=n[r],o=n[r+1];try{var l=a.create;a.destroy=l()}catch(c){if(null===o)throw Error(i(330));zl(o,c)}}for(l=e.current.firstEffect;null!==l;)e=l.nextEffect,l.nextEffect=null,8&l.flags&&(l.sibling=null,l.stateNode=null),l=e;return Ns=t,Va(),!0}function Bl(e,t,n){uo(e,t=ps(0,t=cs(n,t),1)),t=pl(),null!==(e=gl(e,1))&&($t(e,1,t),hl(e,t))}function zl(e,t){if(3===e.tag)Bl(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Bl(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Xs||!Xs.has(r))){var a=fs(n,e=cs(t,e),1);if(uo(n,a),a=pl(),null!==(n=gl(n,1)))$t(n,1,a),hl(n,a);else if("function"==typeof r.componentDidCatch&&(null===Xs||!Xs.has(r)))try{r.componentDidCatch(t,e)}catch(o){}break}}n=n.return}}function Ul(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=pl(),e.pingedLanes|=e.suspendedLanes&n,Os===e&&(Ds&n)===n&&(4===Fs||3===Fs&&(62914560&Ds)===Ds&&500>$a()-Hs?_l(e,0):qs|=n),hl(e,t)}function $l(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===qa()?1:2:(0===ll&&(ll=zs),0===(t=zt(62914560&~ll))&&(t=4194304))),n=pl(),null!==(e=gl(e,t))&&($t(e,t,n),hl(e,n))}function ql(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Gl(e,t,n,r){return new ql(e,t,n,r)}function Hl(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Zl(e,t){var n=e.alternate;return null===n?((n=Gl(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Vl(e,t,n,r,a,o){var s=2;if(r=e,"function"==typeof e)Hl(e)&&(s=1);else if("string"==typeof e)s=5;else e:switch(e){case _:return Wl(n.children,a,o,t);case M:s=8,a|=16;break;case x:s=8,a|=1;break;case C:return(e=Gl(12,n,t,8|a)).elementType=C,e.type=C,e.lanes=o,e;case P:return(e=Gl(13,n,t,a)).type=P,e.elementType=P,e.lanes=o,e;case R:return(e=Gl(19,n,t,a)).elementType=R,e.lanes=o,e;case j:return Yl(n,a,o,t);case F:return(e=Gl(24,n,t,a)).elementType=F,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:s=10;break e;case L:s=9;break e;case A:s=11;break e;case N:s=14;break e;case O:s=16,r=null;break e;case I:s=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=Gl(s,n,t,a)).elementType=e,t.type=r,t.lanes=o,t}function Wl(e,t,n,r){return(e=Gl(7,e,r,t)).lanes=n,e}function Yl(e,t,n,r){return(e=Gl(23,e,r,t)).elementType=j,e.lanes=n,e}function Kl(e,t,n){return(e=Gl(6,e,null,t)).lanes=n,e}function Ql(e,t,n){return(t=Gl(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Xl(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Ut(0),this.expirationTimes=Ut(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ut(0),this.mutableSourceEagerHydrationData=null}function Jl(e,t,n,r){var a=t.current,o=pl(),s=fl(a);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var l=n;do{switch(l.tag){case 3:l=l.stateNode.context;break t;case 1:if(ha(l.type)){l=l.stateNode.__reactInternalMemoizedMergedChildContext;break t}}l=l.return}while(null!==l);throw Error(i(171))}if(1===n.tag){var c=n.type;if(ha(c)){n=ya(n,c,l);break e}}n=l}else n=da;return null===t.context?t.context=n:t.pendingContext=n,(t=co(o,s)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),uo(a,t),ml(a,s,o),s}function ec(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function tc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function nc(e,t){tc(e,t),(e=e.alternate)&&tc(e,t)}function rc(e,t,n){var r=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Xl(e,t,null!=n&&!0===n.hydrate),t=Gl(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,so(t),e[Jr]=n.current,Rr(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var a=(t=r[e])._getVersion;a=a(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,a]:n.mutableSourceEagerHydrationData.push(t,a)}this._internalRoot=n}function ac(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function oc(e,t,n,r,a){var o=n._reactRootContainer;if(o){var i=o._internalRoot;if("function"==typeof a){var s=a;a=function(){var e=ec(i);s.call(e)}}Jl(t,i,e,a)}else{if(o=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new rc(e,0,t?{hydrate:!0}:void 0)}(n,r),i=o._internalRoot,"function"==typeof a){var l=a;a=function(){var e=ec(i);l.call(e)}}kl((function(){Jl(t,i,e,a)}))}return ec(i)}function ic(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!ac(t))throw Error(i(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:E,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)}Ws=function(e,t,n){var r=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||fa.current)Mi=!0;else{if(0==(n&r)){switch(Mi=!1,t.tag){case 3:Zi(t),Vo();break;case 5:Do(t);break;case 1:ha(t.type)&&wa(t);break;case 4:Oo(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value;var a=t.type._context;ua(Qa,a._currentValue),a._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Xi(e,t,n):(ua(jo,1&jo.current),null!==(t=os(e,t,n))?t.sibling:null);ua(jo,1&jo.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(64&e.flags)){if(r)return as(e,t,n);t.flags|=64}if(null!==(a=t.memoizedState)&&(a.rendering=null,a.tail=null,a.lastEffect=null),ua(jo,jo.current),r)break;return null;case 23:case 24:return t.lanes=0,Ui(e,t,n)}return os(e,t,n)}Mi=0!=(16384&e.flags)}else Mi=!1;switch(t.lanes=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=ga(t,pa.current),ao(t,n),a=ii(null,t,r,e,a,n),t.flags|=1,"object"==typeof a&&null!==a&&"function"==typeof a.render&&void 0===a.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,ha(r)){var o=!0;wa(t)}else o=!1;t.memoizedState=null!==a.state&&void 0!==a.state?a.state:null,so(t);var s=r.getDerivedStateFromProps;"function"==typeof s&&ho(t,r,s,e),a.updater=bo,t.stateNode=a,a._reactInternals=t,ko(t,r,e,n),t=Hi(null,t,r,!0,o,n)}else t.tag=0,ji(null,t,a,n),t=t.child;return t;case 16:a=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=(o=a._init)(a._payload),t.type=a,o=t.tag=function(e){if("function"==typeof e)return Hl(e)?1:0;if(null!=e){if((e=e.$$typeof)===A)return 11;if(e===N)return 14}return 2}(a),e=Ka(a,e),o){case 0:t=qi(null,t,a,e,n);break e;case 1:t=Gi(null,t,a,e,n);break e;case 11:t=Fi(null,t,a,e,n);break e;case 14:t=Bi(null,t,a,Ka(a.type,e),r,n);break e}throw Error(i(306,a,""))}return t;case 0:return r=t.type,a=t.pendingProps,qi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 1:return r=t.type,a=t.pendingProps,Gi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 3:if(Zi(t),r=t.updateQueue,null===e||null===r)throw Error(i(282));if(r=t.pendingProps,a=null!==(a=t.memoizedState)?a.element:null,lo(e,t),fo(t,r,null,n),(r=t.memoizedState.element)===a)Vo(),t=os(e,t,n);else{if((o=(a=t.stateNode).hydrate)&&(zo=Vr(t.stateNode.containerInfo.firstChild),Bo=t,o=Uo=!0),o){if(null!=(e=a.mutableSourceEagerHydrationData))for(a=0;a<e.length;a+=2)(o=e[a])._workInProgressVersionPrimary=e[a+1],Wo.push(o);for(n=To(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else ji(e,t,r,n),Vo();t=t.child}return t;case 5:return Do(t),null===e&&Go(t),r=t.type,a=t.pendingProps,o=null!==e?e.memoizedProps:null,s=a.children,qr(r,a)?s=null:null!==o&&qr(r,o)&&(t.flags|=16),$i(e,t),ji(e,t,s,n),t.child;case 6:return null===e&&Go(t),null;case 13:return Xi(e,t,n);case 4:return Oo(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Co(t,null,r,n):ji(e,t,r,n),t.child;case 11:return r=t.type,a=t.pendingProps,Fi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 7:return ji(e,t,t.pendingProps,n),t.child;case 8:case 12:return ji(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,a=t.pendingProps,s=t.memoizedProps,o=a.value;var l=t.type._context;if(ua(Qa,l._currentValue),l._currentValue=o,null!==s)if(l=s.value,0===(o=cr(l,o)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(l,o):1073741823))){if(s.children===a.children&&!fa.current){t=os(e,t,n);break e}}else for(null!==(l=t.child)&&(l.return=t);null!==l;){var c=l.dependencies;if(null!==c){s=l.child;for(var u=c.firstContext;null!==u;){if(u.context===r&&0!=(u.observedBits&o)){1===l.tag&&((u=co(-1,n&-n)).tag=2,uo(l,u)),l.lanes|=n,null!==(u=l.alternate)&&(u.lanes|=n),ro(l.return,n),c.lanes|=n;break}u=u.next}}else s=10===l.tag&&l.type===t.type?null:l.child;if(null!==s)s.return=l;else for(s=l;null!==s;){if(s===t){s=null;break}if(null!==(l=s.sibling)){l.return=s.return,s=l;break}s=s.return}l=s}ji(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,r=(o=t.pendingProps).children,ao(t,n),r=r(a=oo(a,o.unstable_observedBits)),t.flags|=1,ji(e,t,r,n),t.child;case 14:return o=Ka(a=t.type,t.pendingProps),Bi(e,t,a,o=Ka(a.type,o),r,n);case 15:return zi(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,a=t.pendingProps,a=t.elementType===r?a:Ka(r,a),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,ha(r)?(e=!0,wa(t)):e=!1,ao(t,n),yo(t,r,a),ko(t,r,a,n),Hi(null,t,r,!0,e,n);case 19:return as(e,t,n);case 23:case 24:return Ui(e,t,n)}throw Error(i(156,t.tag))},rc.prototype.render=function(e){Jl(e,this._internalRoot,null,null)},rc.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;Jl(null,e,null,(function(){t[Jr]=null}))},et=function(e){13===e.tag&&(ml(e,4,pl()),nc(e,4))},tt=function(e){13===e.tag&&(ml(e,67108864,pl()),nc(e,67108864))},nt=function(e){if(13===e.tag){var t=pl(),n=fl(e);ml(e,n,t),nc(e,n)}},rt=function(e,t){return t()},Ce=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=aa(r);if(!a)throw Error(i(90));Q(r),ne(r,a)}}}break;case"textarea":ce(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Ne=wl,Oe=function(e,t,n,r,a){var o=Ns;Ns|=4;try{return Ha(98,e.bind(null,t,n,r,a))}finally{0===(Ns=o)&&(Vs(),Va())}},Ie=function(){0==(49&Ns)&&(function(){if(null!==al){var e=al;al=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,hl(e,$a())}))}Va()}(),Dl())},De=function(e,t){var n=Ns;Ns|=2;try{return e(t)}finally{0===(Ns=n)&&(Vs(),Va())}};var sc={Events:[na,ra,aa,Pe,Re,Dl,{current:!1}]},lc={findFiberByHostInstance:ta,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},cc={bundleType:lc.bundleType,version:lc.version,rendererPackageName:lc.rendererPackageName,rendererConfig:lc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Xe(e))?null:e.stateNode},findFiberByHostInstance:lc.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var uc=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!uc.isDisabled&&uc.supportsFiber)try{Sa=uc.inject(cc),Ea=uc}catch(ge){}}t.hydrate=function(e,t,n){if(!ac(t))throw Error(i(200));return oc(null,e,t,!0,n)}},3935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(4448)},9590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var s,l,c,u;if(Array.isArray(e)){if((s=e.length)!=i.length)return!1;for(l=s;0!=l--;)if(!o(e[l],i[l]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!i.has(l.value[0]))return!1;for(u=e.entries();!(l=u.next()).done;)if(!o(l.value[1],i.get(l.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!i.has(l.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((s=e.length)!=i.length)return!1;for(l=s;0!=l--;)if(e[l]!==i[l])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((s=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(l=s;0!=l--;)if(!Object.prototype.hasOwnProperty.call(i,c[l]))return!1;if(t&&e instanceof Element)return!1;for(l=s;0!=l--;)if(("_owner"!==c[l]&&"__v"!==c[l]&&"__o"!==c[l]||!e.$$typeof)&&!o(e[c[l]],i[c[l]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>H,ql:()=>J});var r=n(7294),a=n(5697),o=n.n(a),i=n(9590),s=n.n(i),l=n(1143),c=n.n(l),u=n(6774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function g(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(h).map((function(e){return h[e]})),k={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},S=Object.keys(k).reduce((function(e,t){return e[k[t]]=t,e}),{}),E=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=E(e,h.TITLE),n=E(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=E(e,"defaultTitle");return t||r||void 0},x=function(e){return E(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a<r.length;a+=1){var o=r[a].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},L=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var a={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var s=o[i],l=s.toLowerCase();-1===t.indexOf(l)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===l&&"stylesheet"===e[l].toLowerCase()||(n=l),-1===t.indexOf(s)||"innerHTML"!==s&&"cssText"!==s&&"itemprop"!==s||(n=s)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),a[n]||(a[n]={}),!r[n][c]&&(a[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(a),i=0;i<o.length;i+=1){var s=o[i],l=p({},r[s],a[s]);r[s]=l}return e}),[]).reverse()},A=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},R=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},O=[h.NOSCRIPT,h.SCRIPT,h.STYLE],I=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},D=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},M=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[k[n]||n]=e[n],t}),t)},j=function(e,t){return t.map((function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach((function(e){var n=k[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),r.createElement(e,o)}))},F=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=M(n,a),[r.createElement(h.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=D(n),o=P(t);return a?"<"+e+' data-rh="true" '+a+">"+I(o,r)+"</"+e+">":"<"+e+' data-rh="true">'+I(o,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return M(t)},toString:function(){return D(t)}};default:return{toComponent:function(){return j(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+I(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===O.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,s=e.title,l=void 0===s?"":s,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=R(e.metaTags,y),o=R(t,b),i=R(n,v);return{priorityMethods:{toComponent:function(){return[].concat(j(h.META,a.priority),j(h.LINK,o.priority),j(h.SCRIPT,i.priority))},toString:function(){return F(h.META,a.priority,r)+" "+F(h.LINK,o.priority,r)+" "+F(h.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);f=m.priorityMethods,u=m.linkTags,d=m.metaTags,p=m.scriptTags}return{priority:f,base:F(h.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",a,r),link:F(h.LINK,u,r),meta:F(h.META,d,r),noscript:F(h.NOSCRIPT,o,r),script:F(h.SCRIPT,p,r),style:F(h.STYLE,i,r),title:F(h.TITLE,{title:l,titleAttributes:c},r)}},z=[],U=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},$=r.createContext({}),q=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),G="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new U(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement($.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=G,H.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var Z=function(e,t){var n,r=document.head||document.querySelector(h.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,r.isEqualNode(e)}))?o.splice(n,1):i.push(r)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:o,newTags:i}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),s=0;s<i.length;s+=1){var l=i[s],c=t[l]||"";n.getAttribute(l)!==c&&n.setAttribute(l,c),-1===a.indexOf(l)&&a.push(l);var u=o.indexOf(l);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},W=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,s=e.onChangeClientState,l=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;V(h.BODY,e.bodyAttributes),V(h.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),V(h.TITLE,t)}(u,d);var p={baseTag:Z(h.BASE,n),linkTags:Z(h.LINK,a),metaTags:Z(h.META,o),noscriptTags:Z(h.NOSCRIPT,i),scriptTags:Z(h.SCRIPT,l),styleTags:Z(h.STYLE,c)},f={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),s(e,f,m)},Y=null,K=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,a=null,o=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:E(e,"defer"),encode:E(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:L(h.LINK,["rel","href"],e),metaTags:L(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:L(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:x(e),scriptTags:L(h.SCRIPT,["src","innerHTML"],e),styleTags:L(h.STYLE,["cssText"],e),title:_(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:A(e,"prioritizeSeoTags")});H.canUseDOM?(t=o,Y&&cancelAnimationFrame(Y),t.defer?Y=requestAnimationFrame((function(){W(t,(function(){Y=null}))})):(W(t),Y=null)):B&&(a=B(o)),r(a)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);K.propTypes={context:q.isRequired},K.displayName="HelmetDispatcher";var Q=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!s()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case h.TITLE:return p({},a,((t={})[r.type]=i,t.titleAttributes=p({},o),t));case h.BODY:return p({},a,{bodyAttributes:p({},o)});case h.HTML:return p({},a,{htmlAttributes:p({},o)});default:return p({},a,((n={})[r.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,o=r.children,i=g(r,Q),s=Object.keys(i).reduce((function(e,t){return e[S[t]||t]=i[t],e}),{}),l=e.type;switch("symbol"==typeof l?l=l.toString():n.warnOnInvalidChildren(e,o),l){case h.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:s,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:s,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=g(e,X),a=p({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof U||(o=new U(o.context,o.instances)),o?r.createElement(K,p({},a,{context:o.value,helmetData:void 0})):r.createElement($.Consumer,null,(function(e){return r.createElement(K,p({},a,{context:e}))}))},t}(r.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},9921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,s=n?Symbol.for("react.profiler"):60114,l=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,g=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case o:case s:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case h:case g:case l:return e;default:return t}}case a:return t}}}function S(e){return k(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=l,t.Element=r,t.ForwardRef=p,t.Fragment=o,t.Lazy=h,t.Memo=g,t.Portal=a,t.Profiler=s,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return S(e)||k(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===c},t.isContextProvider=function(e){return k(e)===l},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===p},t.isFragment=function(e){return k(e)===o},t.isLazy=function(e){return k(e)===h},t.isMemo=function(e){return k(e)===g},t.isPortal=function(e){return k(e)===a},t.isProfiler=function(e){return k(e)===s},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===s||e===i||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===g||e.$$typeof===l||e.$$typeof===c||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=k},9864:(e,t,n)=>{"use strict";e.exports=n(9921)},8356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var s=n(7294),l=n(5697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var a=d(e[r]);a.loading?t.loading=!0:(t.loaded[r]=a.loaded,t.error=a.error),n.push(a.promise),a.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return s.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),g=null;function h(){return g||(g=e(m.loader)),g.promise}return c.push(h),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=d=function(t){function n(n){var r;return o(a(a(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),g=e(m.loader),r._loadModule()})),h(),r.state={error:g.error,pastDelay:!1,timedOut:!1,loading:g.loading,loaded:g.loaded},r}r(n,t),n.preload=function(){return h()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.loadable.report(t)})),g.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:g.error,loaded:g.loaded,loading:g.loading}),e._clearTimeouts()};g.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?s.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(s.Component),o(d,"contextTypes",{loadable:l.shape({report:l.func.isRequired})}),p}function g(e){return m(d,e)}g.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return s.Children.only(this.props.children)},t}(s.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}o(h,"propTypes",{report:l.func.isRequired}),o(h,"childContextTypes",{loadable:l.shape({report:l.func.isRequired}).isRequired}),g.Capture=h,g.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},g.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=g},8790:(e,t,n)=>{"use strict";n.d(t,{H:()=>s,f:()=>i});var r=n(6550),a=n(7462),o=n(7294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var a=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return a&&(n.push({route:e,match:a}),e.routes&&i(e.routes,t,n)),a})),n}function s(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(r.rs,n,e.map((function(e,n){return o.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,a.Z)({},n,{},t,{route:e})):o.createElement(e.component,(0,a.Z)({},n,t,{route:e}))}})}))):null}},3727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>u,rU:()=>h});var r=n(6550),a=n(5068),o=n(7294),i=n(9318),s=n(7462),l=n(3366),c=n(2177),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.lX)(t.props),t}return(0,a.Z)(t,e),t.prototype.render=function(){return o.createElement(r.F0,{history:this.history,children:this.props.children})},t}(o.Component);o.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},f=function(e){return e},m=o.forwardRef;void 0===m&&(m=f);var g=m((function(e,t){var n=e.innerRef,r=e.navigate,a=e.onClick,i=(0,l.Z)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,s.Z)({},i,{onClick:function(e){try{a&&a(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=f!==m&&t||n,o.createElement("a",u)}));var h=m((function(e,t){var n=e.component,a=void 0===n?g:n,u=e.replace,h=e.to,b=e.innerRef,v=(0,l.Z)(e,["component","replace","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,r=p(d(h,e.location),e.location),l=r?n.createHref(r):"",g=(0,s.Z)({},v,{href:l,navigate:function(){var t=d(h,e.location),r=(0,i.Ep)(e.location)===(0,i.Ep)(p(t));(u||r?n.replace:n.push)(t)}});return f!==m?g.ref=t||b:g.innerRef=b,o.createElement(a,g)}))})),b=function(e){return e},v=o.forwardRef;void 0===v&&(v=b);var y=v((function(e,t){var n=e["aria-current"],a=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,f=e.activeStyle,m=e.className,g=e.exact,y=e.isActive,w=e.location,k=e.sensitive,S=e.strict,E=e.style,_=e.to,x=e.innerRef,C=(0,l.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=w||e.location,i=p(d(_,n),n),l=i.pathname,T=l&&l.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),L=T?(0,r.LX)(n.pathname,{path:T,exact:g,sensitive:k,strict:S}):null,A=!!(y?y(L,n):L),P="function"==typeof m?m(A):m,R="function"==typeof E?E(A):E;A&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,u),R=(0,s.Z)({},R,f));var N=(0,s.Z)({"aria-current":A&&a||null,className:P,style:R,to:i},C);return b!==v?N.ref=t||x:N.innerRef=x,o.createElement(h,N)}))}))},6550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>_,F0:()=>y,LX:()=>E,TH:()=>O,k6:()=>N,rs:()=>P,s6:()=>v});var r=n(5068),a=n(7294),o=n(5697),i=n.n(o),s=n(9318),l=n(2177),c=n(7462),u=n(4779),d=n.n(u),p=(n(9864),n(3366)),f=(n(8679),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var g=a.createContext||function(e,t){var n,o,s="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",l=function(e){function n(){for(var t,n,r,a=arguments.length,o=new Array(a),i=0;i<a;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.Z)(n,e);var a=n.prototype;return a.getChildContext=function(){var e;return(e={})[s]=this.emitter,e},a.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(i=a)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(r,a):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},a.render=function(){return this.props.children},n}(a.Component);l.childContextTypes=((n={})[s]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var a=n.prototype;return a.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},a.componentDidMount=function(){this.context[s]&&this.context[s].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},a.componentWillUnmount=function(){this.context[s]&&this.context[s].off(this.onUpdate)},a.getValue=function(){return this.context[s]?this.context[s].get():e},a.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(a.Component);return c.contextTypes=((o={})[s]=i().object,o),{Provider:l,Consumer:c}},h=function(e){var t=g();return t.displayName=e,t},b=h("Router-History"),v=h("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return a.createElement(v.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},a.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(a.Component);a.Component;a.Component;var w={},k=1e4,S=0;function E(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,i=n.strict,s=void 0!==i&&i,l=n.sensitive,c=void 0!==l&&l;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var a=[],o={regexp:d()(e,a,t),keys:a};return S<k&&(r[e]=o,S++),o}(n,{end:o,strict:s,sensitive:c}),a=r.regexp,i=r.keys,l=a.exec(e);if(!l)return null;var u=l[0],p=l.slice(1),f=e===u;return o&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var _=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,l.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?E(n.pathname,e.props):t.match,o=(0,c.Z)({},t,{location:n,match:r}),i=e.props,s=i.children,u=i.component,d=i.render;return Array.isArray(s)&&function(e){return 0===a.Children.count(e)}(s)&&(s=null),a.createElement(v.Provider,{value:o},o.match?s?"function"==typeof s?s(o):s:u?a.createElement(u,o):d?d(o):null:"function"==typeof s?s(o):null)}))},t}(a.Component);function x(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=x(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,s.Ep)(e)}function L(e){return function(){(0,l.Z)(!1)}}function A(){}a.Component;var P=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,l.Z)(!1);var n,r,o=e.props.location||t.location;return a.Children.forEach(e.props.children,(function(e){if(null==r&&a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?E(o.pathname,(0,c.Z)({},e.props,{path:i})):t.match}})),r?a.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(a.Component);var R=a.useContext;function N(){return R(b)}function O(){return R(v).location}},2408:(e,t,n)=>{"use strict";var r=n(7418),a=60103,o=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,s=60110,l=60112;t.Suspense=60113;var c=60115,u=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;a=d("react.element"),o=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),s=d("react.context"),l=d("react.forward_ref"),t.Suspense=d("react.suspense"),c=d("react.memo"),u=d("react.lazy")}var p="function"==typeof Symbol&&Symbol.iterator;function f(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g={};function h(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}function b(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}h.prototype.isReactComponent={},h.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(f(85));this.updater.enqueueSetState(this,e,t,"setState")},h.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=h.prototype;var y=v.prototype=new b;y.constructor=v,r(y,h.prototype),y.isPureReactComponent=!0;var w={current:null},k=Object.prototype.hasOwnProperty,S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,n){var r,o={},i=null,s=null;if(null!=t)for(r in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(i=""+t.key),t)k.call(t,r)&&!S.hasOwnProperty(r)&&(o[r]=t[r]);var l=arguments.length-2;if(1===l)o.children=n;else if(1<l){for(var c=Array(l),u=0;u<l;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(r in l=e.defaultProps)void 0===o[r]&&(o[r]=l[r]);return{$$typeof:a,type:e,key:i,ref:s,props:o,_owner:w.current}}function _(e){return"object"==typeof e&&null!==e&&e.$$typeof===a}var x=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,n,r,i){var s=typeof e;"undefined"!==s&&"boolean"!==s||(e=null);var l=!1;if(null===e)l=!0;else switch(s){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case a:case o:l=!0}}if(l)return i=i(l=e),e=""===r?"."+C(l,0):r,Array.isArray(i)?(n="",null!=e&&(n=e.replace(x,"$&/")+"/"),T(i,t,n,"",(function(e){return e}))):null!=i&&(_(i)&&(i=function(e,t){return{$$typeof:a,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||l&&l.key===i.key?"":(""+i.key).replace(x,"$&/")+"/")+e)),t.push(i)),1;if(l=0,r=""===r?".":r+":",Array.isArray(e))for(var c=0;c<e.length;c++){var u=r+C(s=e[c],c);l+=T(s,t,n,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=p&&e[p]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(s=e.next()).done;)l+=T(s=s.value,t,n,u=r+C(s,c++),i);else if("object"===s)throw t=""+e,Error(f(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return l}function L(e,t,n){if(null==e)return e;var r=[],a=0;return T(e,r,"","",(function(e){return t.call(n,e,a++)})),r}function A(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function R(){var e=P.current;if(null===e)throw Error(f(321));return e}var N={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:L,forEach:function(e,t,n){L(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return L(e,(function(){t++})),t},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!_(e))throw Error(f(143));return e}},t.Component=h,t.PureComponent=v,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=N,t.cloneElement=function(e,t,n){if(null==e)throw Error(f(267,e));var o=r({},e.props),i=e.key,s=e.ref,l=e._owner;if(null!=t){if(void 0!==t.ref&&(s=t.ref,l=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(u in t)k.call(t,u)&&!S.hasOwnProperty(u)&&(o[u]=void 0===t[u]&&void 0!==c?c[u]:t[u])}var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){c=Array(u);for(var d=0;d<u;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:a,type:e.type,key:i,ref:s,props:o,_owner:l}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:s,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:l,render:e}},t.isValidElement=_,t.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:A}},t.memo=function(e,t){return{$$typeof:c,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return R().useCallback(e,t)},t.useContext=function(e,t){return R().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return R().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return R().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return R().useLayoutEffect(e,t)},t.useMemo=function(e,t){return R().useMemo(e,t)},t.useReducer=function(e,t,n){return R().useReducer(e,t,n)},t.useRef=function(e){return R().useRef(e)},t.useState=function(e){return R().useState(e)},t.version="17.0.2"},7294:(e,t,n)=>{"use strict";e.exports=n(2408)},53:(e,t)=>{"use strict";var n,r,a,o;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var s=Date,l=s.now();t.unstable_now=function(){return s.now()-l}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var c=null,u=null,d=function(){if(null!==c)try{var e=t.unstable_now();c(!0,e),c=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==c?setTimeout(n,0,e):(c=e,setTimeout(d,0))},r=function(e,t){u=setTimeout(e,t)},a=function(){clearTimeout(u)},t.unstable_shouldYield=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var p=window.setTimeout,f=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var g=!1,h=null,b=-1,v=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):v=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,k=w.port2;w.port1.onmessage=function(){if(null!==h){var e=t.unstable_now();y=e+v;try{h(!0,e)?k.postMessage(null):(g=!1,h=null)}catch(n){throw k.postMessage(null),n}}else g=!1},n=function(e){h=e,g||(g=!0,k.postMessage(null))},r=function(e,n){b=p((function(){e(t.unstable_now())}),n)},a=function(){f(b),b=-1}}function S(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<x(a,t)))break e;e[r]=t,e[n]=a,n=r}}function E(e){return void 0===(e=e[0])?null:e}function _(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var o=2*(r+1)-1,i=e[o],s=o+1,l=e[s];if(void 0!==i&&0>x(i,n))void 0!==l&&0>x(l,i)?(e[r]=l,e[s]=n,r=s):(e[r]=i,e[o]=n,r=o);else{if(!(void 0!==l&&0>x(l,n)))break e;e[r]=l,e[s]=n,r=s}}}return t}return null}function x(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],T=[],L=1,A=null,P=3,R=!1,N=!1,O=!1;function I(e){for(var t=E(T);null!==t;){if(null===t.callback)_(T);else{if(!(t.startTime<=e))break;_(T),t.sortIndex=t.expirationTime,S(C,t)}t=E(T)}}function D(e){if(O=!1,I(e),!N)if(null!==E(C))N=!0,n(M);else{var t=E(T);null!==t&&r(D,t.startTime-e)}}function M(e,n){N=!1,O&&(O=!1,a()),R=!0;var o=P;try{for(I(n),A=E(C);null!==A&&(!(A.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=A.callback;if("function"==typeof i){A.callback=null,P=A.priorityLevel;var s=i(A.expirationTime<=n);n=t.unstable_now(),"function"==typeof s?A.callback=s:A===E(C)&&_(C),I(n)}else _(C);A=E(C)}if(null!==A)var l=!0;else{var c=E(T);null!==c&&r(D,c.startTime-n),l=!1}return l}finally{A=null,P=o,R=!1}}var j=o;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){N||R||(N=!0,n(M))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return E(C)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=j,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,o,i){var s=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?s+i:s:i=s,e){case 1:var l=-1;break;case 2:l=250;break;case 5:l=1073741823;break;case 4:l=1e4;break;default:l=5e3}return e={id:L++,callback:o,priorityLevel:e,startTime:i,expirationTime:l=i+l,sortIndex:-1},i>s?(e.sortIndex=i,S(T,e),null===E(C)&&e===E(T)&&(O?a():O=!0,r(D,i-s))):(e.sortIndex=l,S(C,e),N||R||(N=!0,n(M))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},3840:(e,t,n)=>{"use strict";e.exports=n(53)},6774:e=>{e.exports=function(e,t,n,r){var a=n?n.call(r,e,t):void 0;if(void 0!==a)return!!a;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var s=Object.prototype.hasOwnProperty.bind(t),l=0;l<o.length;l++){var c=o[l];if(!s(c))return!1;var u=e[c],d=t[c];if(!1===(a=n?n.call(r,u,d,c):void 0)||void 0===a&&u!==d)return!1}return!0}},2177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t;throw new Error(n?a+": "+n:a)}}},3250:(e,t,n)=>{"use strict";var r=n(7294);var a="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=r.useState,i=r.useEffect,s=r.useLayoutEffect,l=r.useDebugValue;function c(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!a(e,n)}catch(r){return!0}}var u="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=o({inst:{value:n,getSnapshot:t}}),a=r[0].inst,u=r[1];return s((function(){a.value=n,a.getSnapshot=t,c(a)&&u({inst:a})}),[e,n,t]),i((function(){return c(a)&&u({inst:a}),e((function(){c(a)&&u({inst:a})}))}),[e]),l(n),n};void 0!==r.useSyncExternalStore&&r.useSyncExternalStore},1688:(e,t,n)=>{"use strict";n(3250)},6809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"The Cwtch Handbook",tagline:"Your Guide to setting up, and using, Surveillance Resistant Infrastructure",url:"https://docs.cwtch.im",baseUrl:"/es/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/favicon.png",organizationName:"Open Privacy Research Society",projectName:"cwtch.im",i18n:{defaultLocale:"en",locales:["en","es","de","it"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/",remarkPlugins:[null],rehypePlugins:[null]},blog:{feedOptions:{type:"all",copyright:"Copyright \xa9 ${new Date().getFullYear()} Open Privacy Research Society",title:"Cwtch Development Log",description:"The latest insight into Cwtch Development and what the Cwtch team are working on"},blogSidebarCount:20},theme:{customCss:"/home/sarah/PARA/projects/docs.cwtch.im/src/css/custom.css"}}]],themeConfig:{image:"img/cwtch_handbook_header.jpg",colorMode:{defaultMode:"dark",disableSwitch:!1,respectPrefersColorScheme:!1},navbar:{title:"Manual de Cwtch",logo:{alt:"Cwtch Logo",src:"img/knott.png"},items:[{type:"doc",docId:"intro",position:"left",label:"Intro de Cwtch"},{to:"/security/intro",position:"left",label:"Security Handbook"},{to:"/developing/intro",position:"left",label:"Developers Handbook"},{to:"blog",position:"left",label:"Development Log"},{href:"https://openprivacy.ca/donate",label:"Donate",position:"right"},{href:"https://patreon.com/openprivacy",label:"Patreon",position:"right"},{href:"https://cwtch.im/download",label:"Download",position:"right"},{type:"localeDropdown",position:"right",dropdownItemsBefore:[],dropdownItemsAfter:[]}],hideOnScroll:!1},footer:{links:[{title:"Documentaci\xf3n",items:[{label:"Introduction",to:"/docs/intro"},{to:"/security/intro",label:"Security Handbook"},{to:"/developing/intro",label:"Developer Guide"}]},{title:"Comunidad",items:[{label:"Mastodon",href:"https://fosstodon.org/@cwtch"},{label:"Twitter",href:"https://twitter.com/cwtch_im"}]},{title:"Contribute",items:[{label:"Donate",href:"https://openprivacy.ca/donate"},{label:"Patreon",href:"https://patreon.com/openprivacy"},{label:"Source Code",href:"https://git.openprivacy.ca/cwtch.im"},{label:"Download",href:"https://cwtch.im/download"}]}],copyright:"Copyright \xa9 Open Privacy Research Society",style:"light"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},plugins:[["@docusaurus/plugin-content-docs",{id:"docs-security",path:"security",routeBasePath:"security",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}],["@docusaurus/plugin-content-docs",{id:"docs-developer",path:"developing",routeBasePath:"developing",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}]],stylesheets:[{href:"/katex/katex.min.css",type:"text/css"}],baseUrlIssueBanner:!0,onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},themes:[],scripts:[],headTags:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{mermaid:!1}}},7462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},5068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>a})},3366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}n.d(t,{Z:()=>r})},7529:e=>{"use strict";e.exports=JSON.parse('{"theme.AnnouncementBar.closeButtonAriaLabel":"Cerrar","theme.BackToTopButton.buttonAriaLabel":"Desplazarse hacia arriba","theme.CodeBlock.copied":"Copiado","theme.CodeBlock.copy":"Copiar","theme.CodeBlock.copyButtonAriaLabel":"Copiar c\xf3digo al portapaples","theme.CodeBlock.wordWrapToggle":"Habilitar ajuste de l\xednea","theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel":"Desplegar la barra lateral categor\xeda \'{label}\'","theme.ErrorPageContent.title":"Ha ocurrido un error en la p\xe1gina.","theme.ErrorPageContent.tryAgain":"Int\xe9ntalo de nuevo","theme.NavBar.navAriaLabel":"Main","theme.NotFound.p1":"No pudimos encontrar lo que buscas.","theme.NotFound.p2":"Por favor, contacta al propietario del sitio al que est\xe1 enlazada la URL original y hazle saber que el enlace est\xe1 roto.","theme.NotFound.title":"P\xe1gina No Encontrada","theme.TOCCollapsible.toggleButtonLabel":"En esta p\xe1gina","theme.admonition.caution":"caution","theme.admonition.danger":"danger","theme.admonition.info":"info","theme.admonition.note":"note","theme.admonition.tip":"tip","theme.blog.archive.description":"Archivo","theme.blog.archive.title":"Archivo","theme.blog.paginator.navAriaLabel":"Navegaci\xf3n por lista de blogs","theme.blog.paginator.newerEntries":"Entradas m\xe1s recientes","theme.blog.paginator.olderEntries":"Entradas m\xe1s antiguas","theme.blog.post.paginator.navAriaLabel":"Navegaci\xf3n por publicaciones de blog","theme.blog.post.paginator.newerPost":"Art\xedculo m\xe1s reciente","theme.blog.post.paginator.olderPost":"Art\xedculo m\xe1s antiguo","theme.blog.post.plurals":"Un art\xedculo|{count} art\xedculos","theme.blog.post.readMore":"Leer m\xe1s","theme.blog.post.readMoreLabel":"Leer m\xe1s sobre {title}","theme.blog.post.readingTime.plurals":"Lectura de un minuto|Lectura de {readingTime} minutos","theme.blog.sidebar.navAriaLabel":"Navegaci\xf3n por art\xedculos recientes del blog","theme.blog.tagTitle":"{nPosts} etiquetados con \\"{tagName}\\"","theme.colorToggle.ariaLabel":"Cambiar entre modo claro y oscuro (actualmente {mode})","theme.colorToggle.ariaLabel.mode.dark":"modo oscuro","theme.colorToggle.ariaLabel.mode.light":"modo claro","theme.common.editThisPage":"Editar esta p\xe1gina","theme.common.headingLinkTitle":"Enlace directo al encabezado","theme.common.skipToMainContent":"Ir al contenido principal","theme.docs.DocCard.categoryDescription":"{count} \xedtems","theme.docs.breadcrumbs.home":"P\xe1gina de inicio","theme.docs.breadcrumbs.navAriaLabel":"Migajas","theme.docs.paginator.navAriaLabel":"Navegaci\xf3n de p\xe1ginas de documentaci\xf3n","theme.docs.paginator.next":"Siguiente","theme.docs.paginator.previous":"Anterior","theme.docs.sidebar.closeSidebarButtonAriaLabel":"Close navigation bar","theme.docs.sidebar.collapseButtonAriaLabel":"Ocultar la barra lateral","theme.docs.sidebar.collapseButtonTitle":"Ocultar la barra lateral","theme.docs.sidebar.expandButtonAriaLabel":"Expandir la barra lateral","theme.docs.sidebar.expandButtonTitle":"Expandir la barra lateral","theme.docs.sidebar.navAriaLabel":"Docs sidebar","theme.docs.sidebar.toggleSidebarButtonAriaLabel":"Toggle navigation bar","theme.docs.tagDocListPageTitle":"{nDocsTagged} with \\"{tagName}\\"","theme.docs.tagDocListPageTitle.nDocsTagged":"Un documento etiquetado|{count} documentos etiquetados","theme.docs.versionBadge.label":"Versi\xf3n: {versionLabel}","theme.docs.versions.latestVersionLinkLabel":"\xfaltima versi\xf3n","theme.docs.versions.latestVersionSuggestionLabel":"Para documentaci\xf3n actualizada, ver {latestVersionLink} ({versionLabel}).","theme.docs.versions.unmaintainedVersionLabel":"Esta es documentaci\xf3n para {siteTitle} {versionLabel}, la cual ya no se mantiene activamente.","theme.docs.versions.unreleasedVersionLabel":"Esta es documentaci\xf3n no publicada para la versi\xf3n {versionLabel} de {siteTitle}.","theme.lastUpdated.atDate":" en {date}","theme.lastUpdated.byUser":" por {user}","theme.lastUpdated.lastUpdatedAtBy":"\xdaltima actualizaci\xf3n {atDate} {byUser}","theme.navbar.mobileLanguageDropdown.label":"Idiomas","theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel":"\u2190 Volver al men\xfa principal","theme.navbar.mobileVersionsDropdown.label":"Versiones","theme.tags.tagsListLabel":"Etiquetas:","theme.tags.tagsPageLink":"Ver Todas Las Etiquetas","theme.tags.tagsPageTitle":"Tags","Get Started With Cwtch":"Get Started With Cwtch","The Cwtch Handbook":"The Cwtch Handbook","Your Guide to setting up, and using, Surveillance Resistant Infrastructure":"Your Guide to setting up, and using, Surveillance Resistant Infrastructure"}')},6887:e=>{"use strict";e.exports=JSON.parse('{"/es/blog-b72":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"metadata":"8fd5e00a"},"/es/blog/archive-29b":{"__comp":"9e4087bc","__context":{"plugin":"c94c4dfb"},"archive":"95c68178"},"/es/blog/autobindings-5ab":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9dd8190d"},"/es/blog/autobindings-ii-b84":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"8fe7a387"},"/es/blog/availability-status-profile-attributes-688":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6a78f460"},"/es/blog/cwtch-android-reproducibility-aa8":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9b12a270"},"/es/blog/cwtch-bindings-reproducible-d63":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"0d64c1d9"},"/es/blog/cwtch-developer-documentation-0f0":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a65a3c47"},"/es/blog/cwtch-documentation-1b6":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6275ceb4"},"/es/blog/cwtch-nightly-1-11-597":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"c96c5262"},"/es/blog/cwtch-nightly-1-12-f37":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a02b4022"},"/es/blog/cwtch-nightly-v.11-74-302":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5beee875"},"/es/blog/cwtch-platform-support-a5e":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5e5faacc"},"/es/blog/cwtch-stable-api-design-98d":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9e2a7473"},"/es/blog/cwtch-stable-roadmap-update-d51":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"af23c5f9"},"/es/blog/cwtch-stable-roadmap-update-june-296":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"61794344"},"/es/blog/cwtch-testing-i-e6c":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"43b107c1"},"/es/blog/cwtch-testing-ii-c00":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9f1c7621"},"/es/blog/page/2-f76":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"metadata":"26a00d26"},"/es/blog/path-to-cwtch-stable-1d4":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"b0404c31"},"/es/blog/tags-699":{"__comp":"01a85c17","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","tags":"8df6de9b"},"/es/blog/tags/api-dad":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"a79c88c2"}],"tag":"e5c4909f","listMetadata":"474a1a11"},"/es/blog/tags/autobindings-144":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"7a4d337c","listMetadata":"062eafd9"},"/es/blog/tags/bindings-b13":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"},{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"1f984337","listMetadata":"302af923"},"/es/blog/tags/cwtch-976":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"d7b9dd5a","listMetadata":"1cd6f7c0"},"/es/blog/tags/cwtch-stable-78e":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"3a042459","listMetadata":"03aa1116"},"/es/blog/tags/cwtch-stable/page/2-1c3":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"d5055ac4","listMetadata":"00242891"},"/es/blog/tags/cwtch/page/2-9ce":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"86813741","listMetadata":"fd33d4dc"},"/es/blog/tags/developer-documentation-b2d":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"fe1dd7ae"},{"content":"5cb298ca"}],"tag":"5ca95110","listMetadata":"cbbc0b0f"},"/es/blog/tags/documentation-6fa":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"72315c3e","listMetadata":"dc4e6075"},"/es/blog/tags/libcwtch-b51":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"ee1e10c4","listMetadata":"1f18ed69"},"/es/blog/tags/nightly-da6":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"141cdfa9"}],"tag":"64fc8eaf","listMetadata":"d6f4db7a"},"/es/blog/tags/planning-249":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"f041e880"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"23c99aae","listMetadata":"9ef77088"},"/es/blog/tags/release-caf":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"4aa555c3"},{"content":"89f86a37"}],"tag":"9af9bb9d","listMetadata":"1e810a61"},"/es/blog/tags/repliqate-f55":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"70a92a1e","listMetadata":"c21eb9f5"},"/es/blog/tags/reproducible-builds-d6a":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"e0693172","listMetadata":"3ace3922"},"/es/blog/tags/security-handbook-612":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"86aebd6f","listMetadata":"4df29f52"},"/es/blog/tags/support-ee7":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"},{"content":"ef78badf"}],"tag":"0c1afdee","listMetadata":"d7127c3b"},"/es/blog/tags/testing-712":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"}],"tag":"1af3d897","listMetadata":"da0de98b"},"/es/developing-041":{"__comp":"1be78505","__context":{"plugin":"d5f314f9"},"versionMetadata":"f928e8d9"},"/es/developing/building-a-cwtch-app/building-an-echobot-87f":{"__comp":"17896441","content":"fd27e325"},"/es/developing/building-a-cwtch-app/core-concepts-e3b":{"__comp":"17896441","content":"c14f15fd"},"/es/developing/building-a-cwtch-app/intro-b7a":{"__comp":"17896441","content":"824a28c6"},"/es/developing/category/building-a-cwtch-app-8e8":{"__comp":"14eb3368","categoryGeneratedIndex":"43449e47"},"/es/developing/intro-25a":{"__comp":"17896441","content":"fb3c1916"},"/es/developing/release-493":{"__comp":"17896441","content":"5dc151e9"},"/es/docs-9d0":{"__comp":"1be78505","__context":{"plugin":"3db42865"},"versionMetadata":"935f2afb"},"/es/docs/category/appearance-cb7":{"__comp":"14eb3368","categoryGeneratedIndex":"e490445a"},"/es/docs/category/behaviour-9a3":{"__comp":"14eb3368","categoryGeneratedIndex":"8a73259a"},"/es/docs/category/contribute-533":{"__comp":"14eb3368","categoryGeneratedIndex":"02d640a3"},"/es/docs/category/conversations-68a":{"__comp":"14eb3368","categoryGeneratedIndex":"5f8a68fd"},"/es/docs/category/experiments-ca0":{"__comp":"14eb3368","categoryGeneratedIndex":"95f63404"},"/es/docs/category/getting-started-0e6":{"__comp":"14eb3368","categoryGeneratedIndex":"fdfd1857"},"/es/docs/category/groups-b91":{"__comp":"14eb3368","categoryGeneratedIndex":"15cce247"},"/es/docs/category/platforms-0b6":{"__comp":"14eb3368","categoryGeneratedIndex":"b0367817"},"/es/docs/category/profiles-992":{"__comp":"14eb3368","categoryGeneratedIndex":"8eaa4178"},"/es/docs/category/servers-8a4":{"__comp":"14eb3368","categoryGeneratedIndex":"f53ef702"},"/es/docs/category/settings-784":{"__comp":"14eb3368","categoryGeneratedIndex":"33c3c542"},"/es/docs/chat/accept-deny-new-conversation-845":{"__comp":"17896441","content":"b4165829"},"/es/docs/chat/add-contact-bc2":{"__comp":"17896441","content":"ead134b2"},"/es/docs/chat/block-contact-838":{"__comp":"17896441","content":"af971761"},"/es/docs/chat/conversation-settings-549":{"__comp":"17896441","content":"652ba846"},"/es/docs/chat/delete-contact-303":{"__comp":"17896441","content":"1c2b746e"},"/es/docs/chat/introduction-49e":{"__comp":"17896441","content":"559441ca"},"/es/docs/chat/message-formatting-759":{"__comp":"17896441","content":"c5e058ac"},"/es/docs/chat/reply-to-message-129":{"__comp":"17896441","content":"6d68d408"},"/es/docs/chat/save-conversation-history-7fa":{"__comp":"17896441","content":"be9a5550"},"/es/docs/chat/share-address-with-friends-123":{"__comp":"17896441","content":"270b2a86"},"/es/docs/chat/share-file-ac5":{"__comp":"17896441","content":"ebdc3447"},"/es/docs/chat/unblock-contact-3cc":{"__comp":"17896441","content":"ac9aaa3f"},"/es/docs/contribute/developing-c8d":{"__comp":"17896441","content":"1c48b4d1"},"/es/docs/contribute/documentation-c96":{"__comp":"17896441","content":"24c23e10"},"/es/docs/contribute/stickers-6ac":{"__comp":"17896441","content":"daa83a73"},"/es/docs/contribute/testing-e1b":{"__comp":"17896441","content":"3ec42fa4"},"/es/docs/contribute/translate-733":{"__comp":"17896441","content":"6bdc8c14"},"/es/docs/getting-started/supported_platforms-108":{"__comp":"17896441","content":"bcc84138"},"/es/docs/groups/accept-group-invite-477":{"__comp":"17896441","content":"25b9f0e4"},"/es/docs/groups/create-group-026":{"__comp":"17896441","content":"cdd10d0d"},"/es/docs/groups/edit-group-name-9a8":{"__comp":"17896441","content":"ce68aa0f"},"/es/docs/groups/introduction-260":{"__comp":"17896441","content":"404e0e09"},"/es/docs/groups/leave-group-a8e":{"__comp":"17896441","content":"d6981a76"},"/es/docs/groups/manage-known-servers-065":{"__comp":"17896441","content":"6ae2b8f9"},"/es/docs/groups/send-invite-a91":{"__comp":"17896441","content":"f384c30f"},"/es/docs/intro-98b":{"__comp":"17896441","content":"359fb69f"},"/es/docs/platforms/tails-3ca":{"__comp":"17896441","content":"b4876842"},"/es/docs/profiles/availability-status-c52":{"__comp":"17896441","content":"dbda29f5"},"/es/docs/profiles/change-name-11d":{"__comp":"17896441","content":"06622c1f"},"/es/docs/profiles/change-password-53d":{"__comp":"17896441","content":"e48e682c"},"/es/docs/profiles/change-profile-image-9c9":{"__comp":"17896441","content":"c953ad65"},"/es/docs/profiles/create-a-profile-e83":{"__comp":"17896441","content":"ea60411e"},"/es/docs/profiles/delete-profile-edf":{"__comp":"17896441","content":"b77581fc"},"/es/docs/profiles/exporting-profile-ce5":{"__comp":"17896441","content":"dbc23903"},"/es/docs/profiles/importing-a-profile-f0e":{"__comp":"17896441","content":"52564945"},"/es/docs/profiles/introduction-8da":{"__comp":"17896441","content":"81d88b95"},"/es/docs/profiles/profile-info-99b":{"__comp":"17896441","content":"4d4c5a31"},"/es/docs/profiles/unlock-profile-283":{"__comp":"17896441","content":"0e00d73c"},"/es/docs/servers/create-server-aaf":{"__comp":"17896441","content":"e20a62ae"},"/es/docs/servers/delete-server-b73":{"__comp":"17896441","content":"c688cd93"},"/es/docs/servers/edit-server-69e":{"__comp":"17896441","content":"d7c28e69"},"/es/docs/servers/introduction-668":{"__comp":"17896441","content":"0aa99d8f"},"/es/docs/servers/share-key-351":{"__comp":"17896441","content":"21b6537d"},"/es/docs/servers/unlock-server-1ee":{"__comp":"17896441","content":"7d7ca3f1"},"/es/docs/settings/appearance/change-language-646":{"__comp":"17896441","content":"bdf5d676"},"/es/docs/settings/appearance/light-dark-mode-e9c":{"__comp":"17896441","content":"7ae36327"},"/es/docs/settings/appearance/streamer-mode-ac2":{"__comp":"17896441","content":"114c7a7e"},"/es/docs/settings/appearance/ui-columns-2ba":{"__comp":"17896441","content":"05def798"},"/es/docs/settings/behaviour/block-unknown-connections-8d8":{"__comp":"17896441","content":"5ec66a01"},"/es/docs/settings/behaviour/notification-content-ad2":{"__comp":"17896441","content":"54611c16"},"/es/docs/settings/behaviour/notification-policy-e34":{"__comp":"17896441","content":"7a3564c1"},"/es/docs/settings/experiments/clickable-links-39b":{"__comp":"17896441","content":"34545dcf"},"/es/docs/settings/experiments/file-sharing-fec":{"__comp":"17896441","content":"bb45cad0"},"/es/docs/settings/experiments/group-experiment-c4f":{"__comp":"17896441","content":"049fd9f7"},"/es/docs/settings/experiments/image-previews-and-profile-pictures-aa0":{"__comp":"17896441","content":"0e5857d6"},"/es/docs/settings/experiments/message-formatting-8fb":{"__comp":"17896441","content":"618f3057"},"/es/docs/settings/experiments/qrcodes-652":{"__comp":"17896441","content":"94594657"},"/es/docs/settings/experiments/server-hosting-7d6":{"__comp":"17896441","content":"af2fa732"},"/es/docs/settings/introduction-bb6":{"__comp":"17896441","content":"2928a17c"},"/es/docs/tor-463":{"__comp":"17896441","content":"fcdd064d"},"/es/security-204":{"__comp":"1be78505","__context":{"plugin":"4f68bcc6"},"versionMetadata":"a8c7fdc6"},"/es/security/category/connectivity--tor-c78":{"__comp":"14eb3368","categoryGeneratedIndex":"3cd9b44e"},"/es/security/category/cwtch-4bb":{"__comp":"14eb3368","categoryGeneratedIndex":"cf7ec223"},"/es/security/category/cwtch-components-915":{"__comp":"14eb3368","categoryGeneratedIndex":"e2f5db39"},"/es/security/category/cwtch-ui-87f":{"__comp":"14eb3368","categoryGeneratedIndex":"72ed38d2"},"/es/security/category/tapir-1e5":{"__comp":"14eb3368","categoryGeneratedIndex":"4a6801a7"},"/es/security/components/connectivity/intro-78d":{"__comp":"17896441","content":"31631b3e"},"/es/security/components/cwtch/groups-988":{"__comp":"17896441","content":"c567d895"},"/es/security/components/cwtch/key_bundles-123":{"__comp":"17896441","content":"5181f1e2"},"/es/security/components/cwtch/message_formats-9ff":{"__comp":"17896441","content":"de3e8d19"},"/es/security/components/cwtch/server-bb3":{"__comp":"17896441","content":"0c1d60b0"},"/es/security/components/ecosystem-overview-4dd":{"__comp":"17896441","content":"c521ebb9"},"/es/security/components/intro-627":{"__comp":"17896441","content":"511b7c07"},"/es/security/components/tapir/authentication_protocol-fd8":{"__comp":"17896441","content":"c3ed911f"},"/es/security/components/tapir/packet_format-be9":{"__comp":"17896441","content":"2d2c7491"},"/es/security/components/ui/android-33f":{"__comp":"17896441","content":"f6d09a50"},"/es/security/components/ui/image_previews-7b3":{"__comp":"17896441","content":"60846aee"},"/es/security/components/ui/input-204":{"__comp":"17896441","content":"66cb26f4"},"/es/security/components/ui/overlays-fc0":{"__comp":"17896441","content":"3ca9f026"},"/es/security/deployment-9f5":{"__comp":"17896441","content":"d3029be3"},"/es/security/development-48b":{"__comp":"17896441","content":"f63f85fb"},"/es/security/intro-927":{"__comp":"17896441","content":"09ee442d"},"/es/security/references-8d7":{"__comp":"17896441","content":"91341964"},"/es/security/risk-a35":{"__comp":"17896441","content":"9479ba79"},"/es/-926":{"__comp":"c4f5d8e4","__context":{"plugin":"e88d32a9"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[532],(()=>{return t=9383,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/build-staging/es/assets/js/main.7630ede2.js.LICENSE.txt b/build-staging/es/assets/js/main.7630ede2.js.LICENSE.txt new file mode 100644 index 00000000..eb75d691 --- /dev/null +++ b/build-staging/es/assets/js/main.7630ede2.js.LICENSE.txt @@ -0,0 +1,63 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/** + * @license React + * use-sync-external-store-shim.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + */ + +/** @license React v0.20.2 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/build-staging/es/assets/js/runtime~main.d774faa8.js b/build-staging/es/assets/js/runtime~main.d774faa8.js new file mode 100644 index 00000000..5282a905 --- /dev/null +++ b/build-staging/es/assets/js/runtime~main.d774faa8.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,a,c,d,f,b={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return b[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=b,r.c=t,e=[],r.O=(a,c,d,f)=>{if(!c){var b=1/0;for(i=0;i<e.length;i++){c=e[i][0],d=e[i][1],f=e[i][2];for(var t=!0,o=0;o<c.length;o++)(!1&f||b>=f)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,f<b&&(b=f));if(t){e.splice(i--,1);var n=d();void 0!==n&&(a=n)}}return a}f=f||0;for(var i=e.length;i>0&&e[i-1][2]>f;i--)e[i]=e[i-1];e[i]=[c,d,f]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var f=Object.create(null);r.r(f);var b={};a=a||[null,c({}),c([]),c(c)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,r.d(f,b),f},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({26:"5181f1e2",53:"935f2afb",153:"43449e47",276:"fb3c1916",283:"ebdc3447",322:"e48e682c",355:"270b2a86",411:"dbc23903",413:"c953ad65",426:"049fd9f7",433:"618f3057",439:"6a78f460",490:"81d88b95",568:"8fd5e00a",724:"511b7c07",788:"4d27f429",799:"d7b9dd5a",836:"0e00d73c",908:"bb45cad0",923:"5dc151e9",984:"062eafd9",1084:"c521ebb9",1121:"5ca95110",1199:"fd27e325",1258:"9e2a7473",1312:"9f1c7621",1319:"09ee442d",1434:"dbda29f5",1443:"1af3d897",1539:"1c2b746e",1570:"fdfd1857",1601:"d7c28e69",1602:"a8c7fdc6",1664:"302af923",1787:"fd33d4dc",1825:"474a1a11",1949:"7ae36327",1979:"fe1dd7ae",2017:"c5e058ac",2023:"dc4e6075",2033:"b4165829",2054:"2928a17c",2091:"c3ed911f",2182:"cdd10d0d",2184:"f76a3b8e",2279:"be9a5550",2516:"3a042459",2524:"114c7a7e",2535:"814f3328",2682:"559441ca",2688:"9dd8190d",2722:"e0693172",2806:"21b6537d",2815:"e20a62ae",2858:"64fc8eaf",2909:"5cb298ca",2995:"1cd6f7c0",3066:"02d640a3",3077:"e5c4909f",3089:"a6aa9e1f",3214:"91341964",3218:"af23c5f9",3337:"60846aee",3346:"24c23e10",3405:"ea60411e",3441:"5ec66a01",3455:"2d2c7491",3492:"a02b4022",3516:"4f68bcc6",3570:"de3e8d19",3608:"9e4087bc",3633:"0aa99d8f",3761:"c96c5262",3769:"1f984337",3775:"6bdc8c14",3787:"52564945",3957:"6ae2b8f9",4013:"01a85c17",4138:"5f8a68fd",4170:"7a4d337c",4174:"0c1d60b0",4195:"c4f5d8e4",4273:"4df29f52",4318:"15cce247",4398:"7d7ca3f1",4533:"1e810a61",4667:"00242891",4679:"652ba846",4685:"359fb69f",4697:"4a6801a7",4733:"33c3c542",4788:"1ebd8798",4811:"06622c1f",5004:"b77581fc",5103:"bcc84138",5170:"31631b3e",5226:"f041e880",5233:"8fe7a387",5273:"bf059cf9",5291:"bdf5d676",5401:"d6f4db7a",5467:"94594657",5532:"daa83a73",5566:"72315c3e",5583:"3ec42fa4",5602:"9ef77088",5703:"404e0e09",5732:"1a25c548",5760:"f384c30f",5761:"d6981a76",5841:"9af9bb9d",5869:"d5f314f9",5889:"0e5857d6",5905:"824a28c6",5910:"c21eb9f5",5986:"c567d895",6017:"f53ef702",6021:"b4876842",6060:"0c1afdee",6103:"ccc49370",6162:"8a73259a",6164:"e2f5db39",6179:"8eaa4178",6205:"95c68178",6232:"61794344",6433:"9479ba79",6520:"d3029be3",6555:"6275ceb4",6585:"e88d32a9",6588:"4d4c5a31",6649:"25b9f0e4",6679:"86813741",6719:"26a00d26",6753:"af2fa732",6774:"da0de98b",6801:"ac9aaa3f",7075:"95f63404",7139:"3db42865",7251:"af971761",7264:"c688cd93",7293:"141cdfa9",7372:"ee1e10c4",7519:"70a92a1e",7591:"a65a3c47",7594:"53cc4802",7649:"c14f15fd",7782:"3a109bd3",7797:"4aa555c3",7860:"b0404c31",7918:"17896441",8002:"ead134b2",8031:"54611c16",8177:"3ca9f026",8186:"3cd9b44e",8192:"5e5faacc",8261:"1f18ed69",8330:"6d68d408",8525:"b0367817",8537:"f63f85fb",8543:"fcdd064d",8566:"cf7ec223",8609:"d5055ac4",8610:"6875c492",8639:"23c99aae",8664:"1c48b4d1",8667:"34545dcf",8710:"0d64c1d9",8786:"f928e8d9",8798:"05def798",8799:"b125d866",8835:"c747432f",8922:"ef78badf",8962:"f6d09a50",8974:"3ace3922",9146:"c94c4dfb",9200:"43b107c1",9249:"9b12a270",9334:"cbbc0b0f",9444:"5beee875",9453:"66cb26f4",9514:"1be78505",9587:"03aa1116",9599:"86aebd6f",9759:"89f86a37",9765:"e490445a",9793:"ce68aa0f",9817:"14eb3368",9858:"72ed38d2",9930:"7a3564c1",9954:"8df6de9b",9958:"d7127c3b",9976:"a79c88c2"}[e]||e)+"."+{26:"0dbff0ec",53:"ee974ae8",153:"7c30d776",276:"872615eb",283:"279c0f2a",322:"0cff7e1b",355:"4eb699d2",411:"2a3fcb44",413:"3094368f",426:"2c598970",433:"e0c71e08",439:"15b9b73b",490:"aab45f5c",568:"030bf1c3",724:"1dc648e2",788:"93b89f91",799:"939a5305",836:"e93221bd",908:"30e00de6",923:"56486496",984:"24dd9419",1084:"aec6b83a",1121:"39e04a7f",1199:"93065cb0",1258:"1f61baec",1312:"657f8b4f",1319:"c0a61b67",1434:"f937dc7d",1443:"05f2d997",1539:"ad6be4f5",1570:"63bd4b8c",1601:"1cda3189",1602:"8abc03ab",1664:"36b0527a",1787:"75f47db3",1825:"6f6502bc",1949:"92375b54",1979:"c18024ee",2017:"ff52790d",2023:"f26fb504",2033:"35928455",2054:"7412f6b7",2091:"21534c5a",2182:"46a676f4",2184:"c0899ada",2279:"08f0d5b4",2516:"0e82c2da",2524:"6593dfd5",2535:"dab4f975",2682:"28bb5a71",2688:"f4e110b9",2722:"f99cafb0",2806:"06433fac",2815:"f642dad7",2858:"809fa82d",2909:"39a0ae85",2995:"24f5b1b9",3066:"9bc03a47",3077:"9242e056",3089:"8ac198c5",3214:"d796dbab",3218:"faebd2cb",3337:"1180f6f5",3346:"2a5ce882",3405:"d7f9429e",3441:"debca232",3455:"761fd692",3492:"ff8b72fb",3516:"d9b156bf",3570:"f15dbe35",3608:"582408aa",3633:"1048080d",3761:"c2f9d73d",3769:"9a9de679",3775:"87cae20b",3787:"903c212a",3957:"be84c69e",4013:"fbcc85f1",4138:"555ac856",4170:"39d56149",4174:"73c4584d",4195:"ea3b76f3",4273:"94cada4a",4318:"5aeb757f",4398:"49e68129",4533:"bb60f444",4667:"62d32fdf",4679:"266e344c",4685:"b8e0e841",4697:"83c15240",4733:"7cd1cc21",4788:"80be0f08",4811:"35e752cc",4972:"486cf118",5004:"36d30fdd",5103:"5bb1e05c",5170:"beb6fb60",5226:"fe38fdf2",5233:"2fa91d2e",5273:"c718c160",5291:"5ba7b55d",5401:"1b6b2690",5467:"90c23965",5532:"e70fcb06",5566:"c9658a71",5583:"61f4a24d",5602:"cdd221d9",5703:"606db230",5732:"54459e7f",5760:"e1b97bdd",5761:"e0b288aa",5841:"c9dc5261",5869:"1dc05f26",5889:"52a7d47f",5905:"bbeb6a19",5910:"46800ab1",5986:"92b6bd3f",6017:"216ea841",6021:"3aede96b",6048:"e7c7c18a",6060:"2cd087a1",6103:"a9ca1f91",6162:"d83ce251",6164:"9ecf00b5",6179:"fb5d204a",6205:"210d403e",6232:"a3bb40cb",6433:"bb5c5d71",6520:"03b2d6c0",6555:"12fa173d",6585:"ff20b8ba",6588:"68003e61",6649:"5fecb48b",6679:"2158c6b4",6719:"52c0f2a0",6753:"7fc763b4",6774:"5e492249",6801:"f662d91d",7075:"dce04067",7139:"27ab3fca",7251:"397b2387",7264:"780495d4",7293:"3e834abc",7372:"8e8a516f",7519:"51ada7b2",7591:"360aa4d8",7594:"3b1e644b",7649:"96c2246e",7782:"f064b182",7797:"da7eeb80",7860:"be62635c",7918:"27340309",8002:"400c7729",8031:"3b0a29e1",8177:"619ce63a",8186:"16ca6c39",8192:"34927fd8",8261:"10d0b90f",8330:"3d4fb168",8525:"4d1f5666",8537:"5b2f2150",8543:"8c75555c",8566:"3b65b550",8609:"95953496",8610:"a3d95c11",8639:"a5c52f6a",8664:"b4858c3a",8667:"e9bf7bdd",8710:"427c695b",8786:"80bb4b49",8798:"8eeab94d",8799:"164edb4b",8835:"6555923b",8922:"c85ba6c9",8962:"114ee1a4",8974:"74740c09",9146:"5e3bcaf2",9200:"2a677536",9249:"47315695",9334:"6e72d682",9444:"33a0527e",9453:"04618bc5",9514:"c2da882e",9587:"d741ae55",9599:"8292d4fa",9759:"4b34c50d",9765:"86813d8a",9785:"e0c467d7",9793:"f44e6112",9817:"5ac78d9e",9858:"1e0a8f75",9930:"e36fa6db",9954:"b9435ee3",9958:"2158e7fc",9976:"bfaf70a8"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},f="user-handbook:",r.l=(e,a,c,b)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==f+c){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",f+c),t.src=e),d[e]=[a];var l=(a,c)=>{t.onerror=t.onload=null,clearTimeout(s);var f=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),f&&f.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/es/",r.gca=function(e){return e={17896441:"7918",52564945:"3787",61794344:"6232",86813741:"6679",91341964:"3214",94594657:"5467","5181f1e2":"26","935f2afb":"53","43449e47":"153",fb3c1916:"276",ebdc3447:"283",e48e682c:"322","270b2a86":"355",dbc23903:"411",c953ad65:"413","049fd9f7":"426","618f3057":"433","6a78f460":"439","81d88b95":"490","8fd5e00a":"568","511b7c07":"724","4d27f429":"788",d7b9dd5a:"799","0e00d73c":"836",bb45cad0:"908","5dc151e9":"923","062eafd9":"984",c521ebb9:"1084","5ca95110":"1121",fd27e325:"1199","9e2a7473":"1258","9f1c7621":"1312","09ee442d":"1319",dbda29f5:"1434","1af3d897":"1443","1c2b746e":"1539",fdfd1857:"1570",d7c28e69:"1601",a8c7fdc6:"1602","302af923":"1664",fd33d4dc:"1787","474a1a11":"1825","7ae36327":"1949",fe1dd7ae:"1979",c5e058ac:"2017",dc4e6075:"2023",b4165829:"2033","2928a17c":"2054",c3ed911f:"2091",cdd10d0d:"2182",f76a3b8e:"2184",be9a5550:"2279","3a042459":"2516","114c7a7e":"2524","814f3328":"2535","559441ca":"2682","9dd8190d":"2688",e0693172:"2722","21b6537d":"2806",e20a62ae:"2815","64fc8eaf":"2858","5cb298ca":"2909","1cd6f7c0":"2995","02d640a3":"3066",e5c4909f:"3077",a6aa9e1f:"3089",af23c5f9:"3218","60846aee":"3337","24c23e10":"3346",ea60411e:"3405","5ec66a01":"3441","2d2c7491":"3455",a02b4022:"3492","4f68bcc6":"3516",de3e8d19:"3570","9e4087bc":"3608","0aa99d8f":"3633",c96c5262:"3761","1f984337":"3769","6bdc8c14":"3775","6ae2b8f9":"3957","01a85c17":"4013","5f8a68fd":"4138","7a4d337c":"4170","0c1d60b0":"4174",c4f5d8e4:"4195","4df29f52":"4273","15cce247":"4318","7d7ca3f1":"4398","1e810a61":"4533","00242891":"4667","652ba846":"4679","359fb69f":"4685","4a6801a7":"4697","33c3c542":"4733","1ebd8798":"4788","06622c1f":"4811",b77581fc:"5004",bcc84138:"5103","31631b3e":"5170",f041e880:"5226","8fe7a387":"5233",bf059cf9:"5273",bdf5d676:"5291",d6f4db7a:"5401",daa83a73:"5532","72315c3e":"5566","3ec42fa4":"5583","9ef77088":"5602","404e0e09":"5703","1a25c548":"5732",f384c30f:"5760",d6981a76:"5761","9af9bb9d":"5841",d5f314f9:"5869","0e5857d6":"5889","824a28c6":"5905",c21eb9f5:"5910",c567d895:"5986",f53ef702:"6017",b4876842:"6021","0c1afdee":"6060",ccc49370:"6103","8a73259a":"6162",e2f5db39:"6164","8eaa4178":"6179","95c68178":"6205","9479ba79":"6433",d3029be3:"6520","6275ceb4":"6555",e88d32a9:"6585","4d4c5a31":"6588","25b9f0e4":"6649","26a00d26":"6719",af2fa732:"6753",da0de98b:"6774",ac9aaa3f:"6801","95f63404":"7075","3db42865":"7139",af971761:"7251",c688cd93:"7264","141cdfa9":"7293",ee1e10c4:"7372","70a92a1e":"7519",a65a3c47:"7591","53cc4802":"7594",c14f15fd:"7649","3a109bd3":"7782","4aa555c3":"7797",b0404c31:"7860",ead134b2:"8002","54611c16":"8031","3ca9f026":"8177","3cd9b44e":"8186","5e5faacc":"8192","1f18ed69":"8261","6d68d408":"8330",b0367817:"8525",f63f85fb:"8537",fcdd064d:"8543",cf7ec223:"8566",d5055ac4:"8609","6875c492":"8610","23c99aae":"8639","1c48b4d1":"8664","34545dcf":"8667","0d64c1d9":"8710",f928e8d9:"8786","05def798":"8798",b125d866:"8799",c747432f:"8835",ef78badf:"8922",f6d09a50:"8962","3ace3922":"8974",c94c4dfb:"9146","43b107c1":"9200","9b12a270":"9249",cbbc0b0f:"9334","5beee875":"9444","66cb26f4":"9453","1be78505":"9514","03aa1116":"9587","86aebd6f":"9599","89f86a37":"9759",e490445a:"9765",ce68aa0f:"9793","14eb3368":"9817","72ed38d2":"9858","7a3564c1":"9930","8df6de9b":"9954",d7127c3b:"9958",a79c88c2:"9976"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(a,c)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var f=new Promise(((c,f)=>d=e[a]=[c,f]));c.push(d[2]=f);var b=r.p+r.u(a),t=new Error;r.l(b,(c=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var f=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+f+": "+b+")",t.name="ChunkLoadError",t.type=f,t.request=b,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var d,f,b=c[0],t=c[1],o=c[2],n=0;if(b.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(c);n<b.length;n++)f=b[n],r.o(e,f)&&e[f]&&e[f][0](),e[f]=0;return r.O(i)},c=self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})(); \ No newline at end of file diff --git a/build-staging/es/blog/archive/index.html b/build-staging/es/blog/archive/index.html new file mode 100644 index 00000000..2ea44e51 --- /dev/null +++ b/build-staging/es/blog/archive/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html lang="es" dir="ltr" class="plugin-blog plugin-id-default"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v2.4.1"> +<title data-rh="true">Archivo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/blog/atom.xml b/build-staging/es/blog/atom.xml new file mode 100644 index 00000000..8075f279 --- /dev/null +++ b/build-staging/es/blog/atom.xml @@ -0,0 +1,276 @@ + + + https://docs.cwtch.im/es/blog + Cwtch Development Log + 2023-06-30T00:00:00.000Z + https://github.com/jpmonette/feed + + The latest insight into Cwtch Development and what the Cwtch team are working on + https://docs.cwtch.im/es/img/favicon.png + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update-june + + 2023-06-30T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/es/blog/cwtch-nightly-1-12 + + 2023-06-16T00:00:00.000Z + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/es/blog/cwtch-nightly-v.11-74 + + 2023-06-07T00:00:00.000Z + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/es/blog/cwtch-developer-documentation + + 2023-04-28T00:00:00.000Z + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/es/blog/availability-status-profile-attributes + + 2023-04-06T00:00:00.000Z + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update + + 2023-03-31T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/es/blog/cwtch-nightly-1-11 + + 2023-03-29T00:00:00.000Z + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/es/blog/cwtch-documentation + + 2023-03-10T00:00:00.000Z + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/es/blog/autobindings-ii + + 2023-03-03T00:00:00.000Z + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/es/blog/autobindings + + 2023-02-24T00:00:00.000Z + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/es/blog/cwtch-testing-ii + + 2023-02-17T00:00:00.000Z + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/es/blog/cwtch-android-reproducibility + + 2023-02-10T00:00:00.000Z + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/es/blog/cwtch-testing-i + + 2023-02-03T00:00:00.000Z + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/es/blog/cwtch-platform-support + + 2023-01-27T00:00:00.000Z + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/es/blog/cwtch-bindings-reproducible + + 2023-01-20T00:00:00.000Z + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/es/blog/cwtch-stable-api-design + + 2023-01-13T00:00:00.000Z + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/es/blog/path-to-cwtch-stable + + 2023-01-06T00:00:00.000Z + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+
\ No newline at end of file diff --git a/build-staging/es/blog/autobindings-ii/index.html b/build-staging/es/blog/autobindings-ii/index.html new file mode 100644 index 00000000..f9d0e3e2 --- /dev/null +++ b/build-staging/es/blog/autobindings-ii/index.html @@ -0,0 +1,33 @@ + + + + + +Compile-time Optional Application Experiments (Autobindings) | The Cwtch Handbook + + + + + + + + + + + + +
+

Compile-time Optional Application Experiments (Autobindings)

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/autobindings/index.html b/build-staging/es/blog/autobindings/index.html new file mode 100644 index 00000000..64026a05 --- /dev/null +++ b/build-staging/es/blog/autobindings/index.html @@ -0,0 +1,26 @@ + + + + + +Autogenerating Cwtch Bindings | The Cwtch Handbook + + + + + + + + + + + + +
+

Autogenerating Cwtch Bindings

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/availability-status-profile-attributes/index.html b/build-staging/es/blog/availability-status-profile-attributes/index.html new file mode 100644 index 00000000..bdb7ef1c --- /dev/null +++ b/build-staging/es/blog/availability-status-profile-attributes/index.html @@ -0,0 +1,25 @@ + + + + + +Availability Status and Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Availability Status and Profile Attributes

· Lectura de 2 minutos
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-android-reproducibility/index.html b/build-staging/es/blog/cwtch-android-reproducibility/index.html new file mode 100644 index 00000000..e06b6d1e --- /dev/null +++ b/build-staging/es/blog/cwtch-android-reproducibility/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Android Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Android Bindings Reproducible

· Lectura de 3 minutos
Sarah Jamie Lewis

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-bindings-reproducible/index.html b/build-staging/es/blog/cwtch-bindings-reproducible/index.html new file mode 100644 index 00000000..637243cc --- /dev/null +++ b/build-staging/es/blog/cwtch-bindings-reproducible/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Bindings Reproducible

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-developer-documentation/index.html b/build-staging/es/blog/cwtch-developer-documentation/index.html new file mode 100644 index 00000000..5100275b --- /dev/null +++ b/build-staging/es/blog/cwtch-developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly. | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.

· Lectura de 3 minutos
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-documentation/index.html b/build-staging/es/blog/cwtch-documentation/index.html new file mode 100644 index 00000000..faeaaadf --- /dev/null +++ b/build-staging/es/blog/cwtch-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Updates to Cwtch Documentation | The Cwtch Handbook + + + + + + + + + + + + +
+

Updates to Cwtch Documentation

· Lectura de 3 minutos
Sarah Jamie Lewis

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-nightly-1-11/index.html b/build-staging/es/blog/cwtch-nightly-1-11/index.html new file mode 100644 index 00000000..a13b97a4 --- /dev/null +++ b/build-staging/es/blog/cwtch-nightly-1-11/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.11 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.11

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-nightly-1-12/index.html b/build-staging/es/blog/cwtch-nightly-1-12/index.html new file mode 100644 index 00000000..3c5faf6d --- /dev/null +++ b/build-staging/es/blog/cwtch-nightly-1-12/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.12 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.12

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-nightly-v.11-74/index.html b/build-staging/es/blog/cwtch-nightly-v.11-74/index.html new file mode 100644 index 00000000..0d5f57b0 --- /dev/null +++ b/build-staging/es/blog/cwtch-nightly-v.11-74/index.html @@ -0,0 +1,24 @@ + + + + + +New Cwtch Nightly (v1.11.0-74-g0406) | The Cwtch Handbook + + + + + + + + + + + + +
+

New Cwtch Nightly (v1.11.0-74-g0406)

· Lectura de 2 minutos
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-platform-support/index.html b/build-staging/es/blog/cwtch-platform-support/index.html new file mode 100644 index 00000000..19ec114c --- /dev/null +++ b/build-staging/es/blog/cwtch-platform-support/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI Platform Support | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch UI Platform Support

· Lectura de 11 minutos
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-stable-api-design/index.html b/build-staging/es/blog/cwtch-stable-api-design/index.html new file mode 100644 index 00000000..25a061d1 --- /dev/null +++ b/build-staging/es/blog/cwtch-stable-api-design/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable API Design | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable API Design

· Lectura de 18 minutos
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-stable-roadmap-update-june/index.html b/build-staging/es/blog/cwtch-stable-roadmap-update-june/index.html new file mode 100644 index 00000000..1f8a59ac --- /dev/null +++ b/build-staging/es/blog/cwtch-stable-roadmap-update-june/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-stable-roadmap-update/index.html b/build-staging/es/blog/cwtch-stable-roadmap-update/index.html new file mode 100644 index 00000000..fc6033ee --- /dev/null +++ b/build-staging/es/blog/cwtch-stable-roadmap-update/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-testing-i/index.html b/build-staging/es/blog/cwtch-testing-i/index.html new file mode 100644 index 00000000..4b0595da --- /dev/null +++ b/build-staging/es/blog/cwtch-testing-i/index.html @@ -0,0 +1,25 @@ + + + + + +Notes on Cwtch UI Testing | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing

· Lectura de 5 minutos
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/cwtch-testing-ii/index.html b/build-staging/es/blog/cwtch-testing-ii/index.html new file mode 100644 index 00000000..33e42cc2 --- /dev/null +++ b/build-staging/es/blog/cwtch-testing-ii/index.html @@ -0,0 +1,26 @@ + + + + + +Notes on Cwtch UI Testing (II) | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing (II)

· Lectura de 2 minutos
Sarah Jamie Lewis

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/feed.json b/build-staging/es/blog/feed.json new file mode 100644 index 00000000..113db52d --- /dev/null +++ b/build-staging/es/blog/feed.json @@ -0,0 +1,292 @@ +{ + "version": "https://jsonfeed.org/version/1", + "title": "Cwtch Development Log", + "home_page_url": "https://docs.cwtch.im/es/blog", + "description": "The latest insight into Cwtch Development and what the Cwtch team are working on", + "items": [ + { + "id": "https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update-june", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update-june", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals", + "date_modified": "2023-06-30T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-nightly-1-12", + "content_html": "

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-nightly-1-12", + "title": "Cwtch Beta 1.12", + "summary": "Cwtch Beta 1.12 is now available for download", + "date_modified": "2023-06-16T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-nightly-v.11-74", + "content_html": "

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-nightly-v.11-74", + "title": "New Cwtch Nightly (v1.11.0-74-g0406)", + "summary": "In this development log we take a look at the new Cwtch Nightly", + "date_modified": "2023-06-07T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-developer-documentation", + "content_html": "

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-developer-documentation", + "title": "Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.", + "summary": "In this development log we take a look at the new Cwtch developer docs!", + "date_modified": "2023-04-28T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/availability-status-profile-attributes", + "content_html": "

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like\nours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are \"Away\" or \"Busy\".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/availability-status-profile-attributes", + "title": "Availability Status and Profile Attributes", + "summary": "Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.", + "date_modified": "2023-04-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "nightly" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more", + "date_modified": "2023-03-31T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-nightly-1-11", + "content_html": "

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-nightly-1-11", + "title": "Cwtch Beta 1.11", + "summary": "Cwtch Beta 1.11 is now available for download", + "date_modified": "2023-03-29T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-documentation", + "content_html": "

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-documentation", + "title": "Updates to Cwtch Documentation", + "summary": " In this development log we will highlight some of the major documentation updates over the last few weeks.", + "date_modified": "2023-03-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "documentation", + "security-handbook" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/autobindings-ii", + "content_html": "

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an\ninitialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can\npass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option exp which will call the function on the configured experiment, and global to allow the setting up\nof a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import \"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on\ngeneration of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the\nfeature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/autobindings-ii", + "title": "Compile-time Optional Application Experiments (Autobindings)", + "summary": "In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.", + "date_modified": "2023-03-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/autobindings", + "content_html": "

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/autobindings", + "title": "Autogenerating Cwtch Bindings", + "summary": "In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.", + "date_modified": "2023-02-24T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-testing-ii", + "content_html": "

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-testing-ii", + "title": "Notes on Cwtch UI Testing (II)", + "summary": "In this development log we provide more updates on automated UI integration testing!", + "date_modified": "2023-02-17T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-android-reproducibility", + "content_html": "

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-android-reproducibility", + "title": "Making Cwtch Android Bindings Reproducible", + "summary": "In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible", + "date_modified": "2023-02-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-testing-i", + "content_html": "

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like \"take a screenshot\" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-testing-i", + "title": "Notes on Cwtch UI Testing", + "summary": "In this development log we provide an update on automated UI integration testing!", + "date_modified": "2023-02-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-platform-support", + "content_html": "

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\"

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

\"🟡\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-platform-support", + "title": "Cwtch UI Platform Support", + "summary": "This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.", + "date_modified": "2023-01-27T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-bindings-reproducible", + "content_html": "

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/cwtch-bindings-reproducible", + "title": "Making Cwtch Bindings Reproducible", + "summary": "How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.", + "date_modified": "2023-01-20T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/cwtch-stable-api-design", + "content_html": "

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • \"Unencrypted\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \"unencrypted\".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
", + "url": "https://docs.cwtch.im/es/blog/cwtch-stable-api-design", + "title": "Cwtch Stable API Design", + "summary": "The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ", + "date_modified": "2023-01-13T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning", + "api" + ] + }, + { + "id": "https://docs.cwtch.im/es/blog/path-to-cwtch-stable", + "content_html": "

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/es/blog/path-to-cwtch-stable", + "title": "Path to Cwtch Stable", + "summary": "The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.", + "date_modified": "2023-01-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + } + ] +} \ No newline at end of file diff --git a/build-staging/es/blog/index.html b/build-staging/es/blog/index.html new file mode 100644 index 00000000..24b8abcc --- /dev/null +++ b/build-staging/es/blog/index.html @@ -0,0 +1,26 @@ + + + + + +Development Log | The Cwtch Handbook + + + + + + + + + + + + +
+

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· Lectura de 2 minutos
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 3 minutos
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 2 minutos
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/page/2/index.html b/build-staging/es/blog/page/2/index.html new file mode 100644 index 00000000..1b13f90f --- /dev/null +++ b/build-staging/es/blog/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +Development Log | The Cwtch Handbook + + + + + + + + + + + + +
+

· Lectura de 5 minutos
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· Lectura de 11 minutos
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· Lectura de 18 minutos
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· Lectura de 10 minutos
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/path-to-cwtch-stable/index.html b/build-staging/es/blog/path-to-cwtch-stable/index.html new file mode 100644 index 00000000..4c920445 --- /dev/null +++ b/build-staging/es/blog/path-to-cwtch-stable/index.html @@ -0,0 +1,24 @@ + + + + + +Path to Cwtch Stable | The Cwtch Handbook + + + + + + + + + + + + +
+

Path to Cwtch Stable

· Lectura de 10 minutos
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/rss.xml b/build-staging/es/blog/rss.xml new file mode 100644 index 00000000..9a39d355 --- /dev/null +++ b/build-staging/es/blog/rss.xml @@ -0,0 +1,227 @@ + + + + Cwtch Development Log + https://docs.cwtch.im/es/blog + The latest insight into Cwtch Development and what the Cwtch team are working on + Fri, 30 Jun 2023 00:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + es + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update-june + https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update-june + Fri, 30 Jun 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/es/blog/cwtch-nightly-1-12 + https://docs.cwtch.im/es/blog/cwtch-nightly-1-12 + Fri, 16 Jun 2023 00:00:00 GMT + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/es/blog/cwtch-nightly-v.11-74 + https://docs.cwtch.im/es/blog/cwtch-nightly-v.11-74 + Wed, 07 Jun 2023 00:00:00 GMT + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/es/blog/cwtch-developer-documentation + https://docs.cwtch.im/es/blog/cwtch-developer-documentation + Fri, 28 Apr 2023 00:00:00 GMT + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/es/blog/availability-status-profile-attributes + https://docs.cwtch.im/es/blog/availability-status-profile-attributes + Thu, 06 Apr 2023 00:00:00 GMT + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + nightly +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update + https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update + Fri, 31 Mar 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/es/blog/cwtch-nightly-1-11 + https://docs.cwtch.im/es/blog/cwtch-nightly-1-11 + Wed, 29 Mar 2023 00:00:00 GMT + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/es/blog/cwtch-documentation + https://docs.cwtch.im/es/blog/cwtch-documentation + Fri, 10 Mar 2023 00:00:00 GMT + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + documentation + security-handbook +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/es/blog/autobindings-ii + https://docs.cwtch.im/es/blog/autobindings-ii + Fri, 03 Mar 2023 00:00:00 GMT + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/es/blog/autobindings + https://docs.cwtch.im/es/blog/autobindings + Fri, 24 Feb 2023 00:00:00 GMT + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/es/blog/cwtch-testing-ii + https://docs.cwtch.im/es/blog/cwtch-testing-ii + Fri, 17 Feb 2023 00:00:00 GMT + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/es/blog/cwtch-android-reproducibility + https://docs.cwtch.im/es/blog/cwtch-android-reproducibility + Fri, 10 Feb 2023 00:00:00 GMT + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/es/blog/cwtch-testing-i + https://docs.cwtch.im/es/blog/cwtch-testing-i + Fri, 03 Feb 2023 00:00:00 GMT + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/es/blog/cwtch-platform-support + https://docs.cwtch.im/es/blog/cwtch-platform-support + Fri, 27 Jan 2023 00:00:00 GMT + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/es/blog/cwtch-bindings-reproducible + https://docs.cwtch.im/es/blog/cwtch-bindings-reproducible + Fri, 20 Jan 2023 00:00:00 GMT + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/es/blog/cwtch-stable-api-design + https://docs.cwtch.im/es/blog/cwtch-stable-api-design + Fri, 13 Jan 2023 00:00:00 GMT + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ cwtch + cwtch-stable + planning + api +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/es/blog/path-to-cwtch-stable + https://docs.cwtch.im/es/blog/path-to-cwtch-stable + Fri, 06 Jan 2023 00:00:00 GMT + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+
+
\ No newline at end of file diff --git a/build-staging/es/blog/tags/api/index.html b/build-staging/es/blog/tags/api/index.html new file mode 100644 index 00000000..3fa510e2 --- /dev/null +++ b/build-staging/es/blog/tags/api/index.html @@ -0,0 +1,24 @@ + + + + + +Un artículo etiquetados con "api" | The Cwtch Handbook + + + + + + + + + + + + +
+

Un artículo etiquetados con "api"

Ver Todas Las Etiquetas

· Lectura de 18 minutos
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/autobindings/index.html b/build-staging/es/blog/tags/autobindings/index.html new file mode 100644 index 00000000..53db968e --- /dev/null +++ b/build-staging/es/blog/tags/autobindings/index.html @@ -0,0 +1,25 @@ + + + + + +2 artículos etiquetados con "autobindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "autobindings"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/bindings/index.html b/build-staging/es/blog/tags/bindings/index.html new file mode 100644 index 00000000..adb71542 --- /dev/null +++ b/build-staging/es/blog/tags/bindings/index.html @@ -0,0 +1,25 @@ + + + + + +4 artículos etiquetados con "bindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 artículos etiquetados con "bindings"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/cwtch-stable/index.html b/build-staging/es/blog/tags/cwtch-stable/index.html new file mode 100644 index 00000000..65f2e0ec --- /dev/null +++ b/build-staging/es/blog/tags/cwtch-stable/index.html @@ -0,0 +1,26 @@ + + + + + +17 artículos etiquetados con "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 artículos etiquetados con "cwtch-stable"

Ver Todas Las Etiquetas

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· Lectura de 2 minutos
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 3 minutos
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 2 minutos
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/cwtch-stable/page/2/index.html b/build-staging/es/blog/tags/cwtch-stable/page/2/index.html new file mode 100644 index 00000000..5416e739 --- /dev/null +++ b/build-staging/es/blog/tags/cwtch-stable/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 artículos etiquetados con "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 artículos etiquetados con "cwtch-stable"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· Lectura de 11 minutos
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· Lectura de 18 minutos
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· Lectura de 10 minutos
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/cwtch/index.html b/build-staging/es/blog/tags/cwtch/index.html new file mode 100644 index 00000000..32be264b --- /dev/null +++ b/build-staging/es/blog/tags/cwtch/index.html @@ -0,0 +1,26 @@ + + + + + +17 artículos etiquetados con "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 artículos etiquetados con "cwtch"

Ver Todas Las Etiquetas

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· Lectura de 2 minutos
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 3 minutos
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 2 minutos
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/cwtch/page/2/index.html b/build-staging/es/blog/tags/cwtch/page/2/index.html new file mode 100644 index 00000000..205b1ff5 --- /dev/null +++ b/build-staging/es/blog/tags/cwtch/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 artículos etiquetados con "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 artículos etiquetados con "cwtch"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· Lectura de 11 minutos
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· Lectura de 18 minutos
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· Lectura de 10 minutos
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/developer-documentation/index.html b/build-staging/es/blog/tags/developer-documentation/index.html new file mode 100644 index 00000000..ebdb3fc9 --- /dev/null +++ b/build-staging/es/blog/tags/developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +2 artículos etiquetados con "developer-documentation" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "developer-documentation"

Ver Todas Las Etiquetas

· Lectura de 2 minutos
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· Lectura de 3 minutos
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/documentation/index.html b/build-staging/es/blog/tags/documentation/index.html new file mode 100644 index 00000000..387e3d9b --- /dev/null +++ b/build-staging/es/blog/tags/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Un artículo etiquetados con "documentation" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/index.html b/build-staging/es/blog/tags/index.html new file mode 100644 index 00000000..4666fa4c --- /dev/null +++ b/build-staging/es/blog/tags/index.html @@ -0,0 +1,24 @@ + + + + + +Tags | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/libcwtch/index.html b/build-staging/es/blog/tags/libcwtch/index.html new file mode 100644 index 00000000..137eb589 --- /dev/null +++ b/build-staging/es/blog/tags/libcwtch/index.html @@ -0,0 +1,25 @@ + + + + + +2 artículos etiquetados con "libcwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "libcwtch"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· Lectura de 5 minutos
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/nightly/index.html b/build-staging/es/blog/tags/nightly/index.html new file mode 100644 index 00000000..a6ca1335 --- /dev/null +++ b/build-staging/es/blog/tags/nightly/index.html @@ -0,0 +1,25 @@ + + + + + +Un artículo etiquetados con "nightly" | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/planning/index.html b/build-staging/es/blog/tags/planning/index.html new file mode 100644 index 00000000..60d43ad5 --- /dev/null +++ b/build-staging/es/blog/tags/planning/index.html @@ -0,0 +1,24 @@ + + + + + +4 artículos etiquetados con "planning" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 artículos etiquetados con "planning"

Ver Todas Las Etiquetas

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 6 minutos
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· Lectura de 18 minutos
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· Lectura de 10 minutos
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/release/index.html b/build-staging/es/blog/tags/release/index.html new file mode 100644 index 00000000..07060150 --- /dev/null +++ b/build-staging/es/blog/tags/release/index.html @@ -0,0 +1,24 @@ + + + + + +2 artículos etiquetados con "release" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "release"

Ver Todas Las Etiquetas

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· Lectura de 3 minutos
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/repliqate/index.html b/build-staging/es/blog/tags/repliqate/index.html new file mode 100644 index 00000000..e5718613 --- /dev/null +++ b/build-staging/es/blog/tags/repliqate/index.html @@ -0,0 +1,24 @@ + + + + + +2 artículos etiquetados con "repliqate" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "repliqate"

Ver Todas Las Etiquetas

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/reproducible-builds/index.html b/build-staging/es/blog/tags/reproducible-builds/index.html new file mode 100644 index 00000000..890f50c8 --- /dev/null +++ b/build-staging/es/blog/tags/reproducible-builds/index.html @@ -0,0 +1,24 @@ + + + + + +2 artículos etiquetados con "reproducible-builds" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "reproducible-builds"

Ver Todas Las Etiquetas

· Lectura de 8 minutos
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/security-handbook/index.html b/build-staging/es/blog/tags/security-handbook/index.html new file mode 100644 index 00000000..1e371358 --- /dev/null +++ b/build-staging/es/blog/tags/security-handbook/index.html @@ -0,0 +1,24 @@ + + + + + +Un artículo etiquetados con "security-handbook" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/support/index.html b/build-staging/es/blog/tags/support/index.html new file mode 100644 index 00000000..d088fe01 --- /dev/null +++ b/build-staging/es/blog/tags/support/index.html @@ -0,0 +1,24 @@ + + + + + +3 artículos etiquetados con "support" | The Cwtch Handbook + + + + + + + + + + + + +
+

3 artículos etiquetados con "support"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· Lectura de 11 minutos
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

+ + + + \ No newline at end of file diff --git a/build-staging/es/blog/tags/testing/index.html b/build-staging/es/blog/tags/testing/index.html new file mode 100644 index 00000000..abccd386 --- /dev/null +++ b/build-staging/es/blog/tags/testing/index.html @@ -0,0 +1,24 @@ + + + + + +2 artículos etiquetados con "testing" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 artículos etiquetados con "testing"

Ver Todas Las Etiquetas

· Lectura de 5 minutos
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

+ + + + \ No newline at end of file diff --git a/build-staging/es/developing/building-a-cwtch-app/building-an-echobot/index.html b/build-staging/es/developing/building-a-cwtch-app/building-an-echobot/index.html new file mode 100644 index 00000000..01edb352 --- /dev/null +++ b/build-staging/es/developing/building-a-cwtch-app/building-an-echobot/index.html @@ -0,0 +1,25 @@ + + + + + +Building a Cwtch Echobot | The Cwtch Handbook + + + + + + + + + + + + +
+

Building a Cwtch Echobot

In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.

For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or +framework.

Using CwtchBot (Go)

CwtchBot Framework

This tutorial uses the CwtchBot framework.

Start by creating a new Go project, and a file main.go. In the main function:

package main

import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
"fmt"
"git.openprivacy.ca/sarah/cwtchbot"
_ "github.com/mutecomm/go-sqlcipher/v4"
"os/user"
"path"
)

func main() {
user, _ := user.Current()
cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")
cwtchbot.Launch()

// Set Some Profile Information
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")

fmt.Printf("echobot address: %v\n", cwtchbot.Peer.GetOnion())

for {
message := cwtchbot.Queue.Next()
cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])
switch message.EventType {
case event.NewMessageFromPeer:
msg := cwtchbot.UnpackMessage(message.Data[event.Data])
fmt.Printf("Message: %v\n", msg)
reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))
cwtchbot.Peer.SendMessage(cid.ID, reply)
case event.ContactCreated:
fmt.Printf("Auto approving stranger %v %v\n", cid, message.Data[event.RemotePeer])
// accept the stranger as a new contact
cwtchbot.Peer.AcceptConversation(cid.ID)
// Send Hello...
reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))
cwtchbot.Peer.SendMessage(cid.ID, reply)
}
}
}

Using Imp (Rust)

Imp (Rust) Bot Framework

This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.

use std::borrow::BorrowMut;
use std::thread;
use chrono::{DateTime, FixedOffset};
use libcwtch;
use libcwtch::CwtchLib;
use libcwtch::structs::*;
use libcwtch::event::*;
use cwtch_imp::imp;
use cwtch_imp::behaviour::*;
use cwtch_imp::imp::Imp;

const BOT_HOME: &str = "~/.cwtch/bots/echobot";
const BOT_NAME: &str = "echobot";

struct Echobot {}

fn main() {
let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();
let event_loop_handle = thread::spawn(move || {
let mut echobot = Echobot {};
let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());
bot.event_loop::<Echobot>(echobot.borrow_mut());
});
event_loop_handle.join().expect("Error running event loop");
}

impl imp::EventHandler for Echobot {
fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {
let response = Message {
o: MessageType::TextMessage,
d: message.d,
};
cwtch.send_message(&profile.profile_id, conversation_id, &response);
}

fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {
match event {
Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {
println!(
"\n***** {} at {} *****\n",
name, profile_id.as_str()
);
}
_ => (),
};
}
}
+ + + + \ No newline at end of file diff --git a/build-staging/es/developing/building-a-cwtch-app/core-concepts/index.html b/build-staging/es/developing/building-a-cwtch-app/core-concepts/index.html new file mode 100644 index 00000000..f7471348 --- /dev/null +++ b/build-staging/es/developing/building-a-cwtch-app/core-concepts/index.html @@ -0,0 +1,24 @@ + + + + + +Core Concepts | The Cwtch Handbook + + + + + + + + + + + + +
+

Core Concepts

This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.

Cwtch Home Directory

Often referred to as $CWTCH_HOME, the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application.

Profiles

Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations.

The Event Bus

Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. NewMessageFromPeer and setup an event handler to run code in response to such a message.

For an example see the Echo Bot tutorial.

Settings

Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration.

Experiments

Certain Cwtch features are gated behind experiments. These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all.

+ + + + \ No newline at end of file diff --git a/build-staging/es/developing/building-a-cwtch-app/intro/index.html b/build-staging/es/developing/building-a-cwtch-app/intro/index.html new file mode 100644 index 00000000..c9b92585 --- /dev/null +++ b/build-staging/es/developing/building-a-cwtch-app/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Getting Started | The Cwtch Handbook + + + + + + + + + + + + +
+

Getting Started

Choosing A Cwtch Library

Cwtch Go Lib

The official Cwtch library is written in Go and can be found at https://git.openprivacy.ca/cwtch.im/cwtch. This library allows access to all Cwtch functionality.

CwtchBot

We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the building an echobot tutorial.

Autobindings (C-bindings)

The official c-bindings for Cwtch are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI.

libCwtch-rs (Rust)

An experimental rust-fied version of Cwtch Autobindings is available in libCwtch-rs. While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem.

+ + + + \ No newline at end of file diff --git a/build-staging/es/developing/category/building-a-cwtch-app/index.html b/build-staging/es/developing/category/building-a-cwtch-app/index.html new file mode 100644 index 00000000..18f94b9b --- /dev/null +++ b/build-staging/es/developing/category/building-a-cwtch-app/index.html @@ -0,0 +1,24 @@ + + + + + +Building a Cwtch App | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/developing/intro/index.html b/build-staging/es/developing/intro/index.html new file mode 100644 index 00000000..14e6801f --- /dev/null +++ b/build-staging/es/developing/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Introduction to Cwtch Development | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/developing/release/index.html b/build-staging/es/developing/release/index.html new file mode 100644 index 00000000..e847f3da --- /dev/null +++ b/build-staging/es/developing/release/index.html @@ -0,0 +1,24 @@ + + + + + +Release and Packaging Process | The Cwtch Handbook + + + + + + + + + + + + +
+

Release and Packaging Process

Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.

Automated Testing

Drone carries out a suite of automated tests at various stages of the release pipeline.

Test SuiteRepositoryNotes
Integration Testcwtch.im/cwtchA full exercise of peer-to-peer and group messaging
File Sharing Testcwtch.im/cwtchTests that file sharing and image downloading work as expected
Automated Download Testcwtch.im/cwtchTests that automated image downloading (e.g. profile pictures) work as expected
UI Integration Testcwtch.im/cwtch-uiA suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings

Cwtch Autobindings

Drone produces the following build artifacts for all Cwtch autobindings builds.

Build ArtifactPlatformNotes
android/cwtch-sources.jarAndroidgomobile derived source code for the Android Cwtch library
android/cwtch.aarAndroidAndroid Cwtch library. Supports arm, arm64, and amd64.
linux/libCwtch.hLinuxC header file
linux/libCwtch.soLinuxx64 shared library
windows/libCwtch.hWindowsC header file
windows/libCwtch.dllWindowsx64 bit shared library
macos/libCwtch.arm64.dylibMacOSArm64 shared library
macos/libCwtch.x64.dylibMacOSx64 shared library

UI Nightly Builds

We make unreleased versions of Cwtch available for testing as Cwtch Nightlies.

Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:

Build ArtifactPlatformNotes
cwtch-VERSION.apkAndroidSupports arm, arm64, and amd64. Can be sideloaded.
cwtch-VERSION.aabAndroidAndroid App Bundle for publishing to appstores
Cwtch-VERSION.dmgMacOS
cwtch-VERSION.tar.gzLinuxContains the code, libs, and assets in addition to install scripts for various devices
cwtch-VERSION.zipWindows
cwtch-installer-VERSION.exeWindowsNSIS powered installation wizard

Nightly builds are regularly purged from the system

Official Releases

The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps.

When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. v.1.12.0. The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder.

Reproducible Builds

We use repliqate to provide reproducible build scripts for Cwtch.

We update the repliqate-scripts repository with scripts for all official releases. Currently only Cwtch bindings are reproducible

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/appearance/index.html b/build-staging/es/docs/category/appearance/index.html new file mode 100644 index 00000000..c71a7500 --- /dev/null +++ b/build-staging/es/docs/category/appearance/index.html @@ -0,0 +1,24 @@ + + + + + +Apariencia | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/behaviour/index.html b/build-staging/es/docs/category/behaviour/index.html new file mode 100644 index 00000000..3a7068e6 --- /dev/null +++ b/build-staging/es/docs/category/behaviour/index.html @@ -0,0 +1,24 @@ + + + + + +Comportamiento | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/contribute/index.html b/build-staging/es/docs/category/contribute/index.html new file mode 100644 index 00000000..fc6c2d1b --- /dev/null +++ b/build-staging/es/docs/category/contribute/index.html @@ -0,0 +1,24 @@ + + + + + +Contribuye | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/conversations/index.html b/build-staging/es/docs/category/conversations/index.html new file mode 100644 index 00000000..7838a6ef --- /dev/null +++ b/build-staging/es/docs/category/conversations/index.html @@ -0,0 +1,24 @@ + + + + + +Conversations | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/experiments/index.html b/build-staging/es/docs/category/experiments/index.html new file mode 100644 index 00000000..34c3a606 --- /dev/null +++ b/build-staging/es/docs/category/experiments/index.html @@ -0,0 +1,24 @@ + + + + + +Experiments | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/getting-started/index.html b/build-staging/es/docs/category/getting-started/index.html new file mode 100644 index 00000000..1dc9f632 --- /dev/null +++ b/build-staging/es/docs/category/getting-started/index.html @@ -0,0 +1,24 @@ + + + + + +Getting started | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/groups/index.html b/build-staging/es/docs/category/groups/index.html new file mode 100644 index 00000000..0d65b27e --- /dev/null +++ b/build-staging/es/docs/category/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Groups | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/platforms/index.html b/build-staging/es/docs/category/platforms/index.html new file mode 100644 index 00000000..ec67ce2c --- /dev/null +++ b/build-staging/es/docs/category/platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Platforms | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/profiles/index.html b/build-staging/es/docs/category/profiles/index.html new file mode 100644 index 00000000..2431d0de --- /dev/null +++ b/build-staging/es/docs/category/profiles/index.html @@ -0,0 +1,24 @@ + + + + + +Perfiles | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/servers/index.html b/build-staging/es/docs/category/servers/index.html new file mode 100644 index 00000000..b7be0993 --- /dev/null +++ b/build-staging/es/docs/category/servers/index.html @@ -0,0 +1,24 @@ + + + + + +Servers | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/category/settings/index.html b/build-staging/es/docs/category/settings/index.html new file mode 100644 index 00000000..8d01cb13 --- /dev/null +++ b/build-staging/es/docs/category/settings/index.html @@ -0,0 +1,24 @@ + + + + + +Configuración | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/accept-deny-new-conversation/index.html b/build-staging/es/docs/chat/accept-deny-new-conversation/index.html new file mode 100644 index 00000000..12e2b8de --- /dev/null +++ b/build-staging/es/docs/chat/accept-deny-new-conversation/index.html @@ -0,0 +1,24 @@ + + + + + +Aceptar/denegar nuevas conversaciones | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/add-contact/index.html b/build-staging/es/docs/chat/add-contact/index.html new file mode 100644 index 00000000..bccaa097 --- /dev/null +++ b/build-staging/es/docs/chat/add-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Starting a New Conversation | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/block-contact/index.html b/build-staging/es/docs/chat/block-contact/index.html new file mode 100644 index 00000000..98f019f3 --- /dev/null +++ b/build-staging/es/docs/chat/block-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Bloquear un contacto | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/conversation-settings/index.html b/build-staging/es/docs/chat/conversation-settings/index.html new file mode 100644 index 00000000..ea849b35 --- /dev/null +++ b/build-staging/es/docs/chat/conversation-settings/index.html @@ -0,0 +1,24 @@ + + + + + +Accessing Conversation Settings | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/delete-contact/index.html b/build-staging/es/docs/chat/delete-contact/index.html new file mode 100644 index 00000000..8362490d --- /dev/null +++ b/build-staging/es/docs/chat/delete-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Removing a Conversation | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/introduction/index.html b/build-staging/es/docs/chat/introduction/index.html new file mode 100644 index 00000000..513adff6 --- /dev/null +++ b/build-staging/es/docs/chat/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Una Introducción al Chat P2P de Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Una Introducción al Chat P2P de Cwtch

Cwtch usa los servicios Onion de Tor v3 para establecer conexiones anónimas, peer-to-peer entre Perfiles.

Cómo funciona el chat P2P

Para poder chatear con tus amigos en una conversación peer-to-peer, ambos deben estar en línea.

Después de una conexión exitosa, ambas partes participan en un protocolo de autenticación que:

  • Verifica que cada parte tenga acceso a la clave privada asociada a su identidad pública.
  • Genera una clave de sesión efímera usada para cifrar toda comunicación durante la sesión.

Este intercambio (documentado con más detalle en protocolo de autenticación) es negable fuera de línea i.e. es posible que cualquier parte forje transcripciones de este intercambio de protocolo después del hecho, y como tal - después del hecho - es imposible demostrar definitivamente que el intercambio ha ocurrido en absoluto.

Una vez que el proceso de autenticación haya tenido éxito, tanto tu como tu contacto pueden comunicarse con la certeza de que nadie más puede aprender nada sobre el contenido o los metadatos de su conversación.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/message-formatting/index.html b/build-staging/es/docs/chat/message-formatting/index.html new file mode 100644 index 00000000..5d6f9b50 --- /dev/null +++ b/build-staging/es/docs/chat/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Formato de mensajes | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/reply-to-message/index.html b/build-staging/es/docs/chat/reply-to-message/index.html new file mode 100644 index 00000000..c2632aad --- /dev/null +++ b/build-staging/es/docs/chat/reply-to-message/index.html @@ -0,0 +1,24 @@ + + + + + +Contestar a un mensaje | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/save-conversation-history/index.html b/build-staging/es/docs/chat/save-conversation-history/index.html new file mode 100644 index 00000000..103fb1c9 --- /dev/null +++ b/build-staging/es/docs/chat/save-conversation-history/index.html @@ -0,0 +1,24 @@ + + + + + +Guardar el historial de conversaciones | The Cwtch Handbook + + + + + + + + + + + + +
+

Guardar el historial de conversaciones

Por defecto, por privacidad, Cwtch no conserva el historial de conversaciones entre sesiones.

Para habilitar el historial de una conversación específica:

  1. En una ventana de conversación ve a Ajustes
  2. Ve a Guardar Historial
  3. Pulsa el menú desplegable
  4. Elege Guardar el Historial
  5. Ahora tu historial se guardará

El historial de conversaciones puede desactivarse en cualquier momento seleccionando "Borrar Historial" en el menú desplegable.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/share-address-with-friends/index.html b/build-staging/es/docs/chat/share-address-with-friends/index.html new file mode 100644 index 00000000..10fcae5e --- /dev/null +++ b/build-staging/es/docs/chat/share-address-with-friends/index.html @@ -0,0 +1,24 @@ + + + + + +Sharing Cwtch Addresses | The Cwtch Handbook + + + + + + + + + + + + +
+

Sharing Cwtch Addresses

There are many ways to share a Cwtch address.

Sharing Your Cwtch Address

  1. Ve a tu perfil
  2. Haz clic en el icono de copiar dirección

Ahora puedes compartir esta dirección. Las personas con esta dirección podrán añadirte como un contacto de Cwtch.

Para obtener información sobre cómo bloquear conexiones de personas que no conoces, por favor consulta Configuración: Bloquear Conexiones Desconocidas

Sharing A Friends Cwtch Address

Inside of Cwtch there is another mechanism for exchanging Cwtch addresses.

info

This documentation page is a stub. You can help by expanding it.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/share-file/index.html b/build-staging/es/docs/chat/share-file/index.html new file mode 100644 index 00000000..57318ba3 --- /dev/null +++ b/build-staging/es/docs/chat/share-file/index.html @@ -0,0 +1,24 @@ + + + + + +Compartir un archivo | The Cwtch Handbook + + + + + + + + + + + + +
+

Compartir un archivo

Experiments Required

Esta función requiere Experimentos habilitados y el Experimento de Grupos activado.

Optionally, you can enable Image Previews and Profile Pictures to see display shared image previews in the conversation window.

En una conversación,

  1. Haz clic en el icono de adjuntar archivo
  2. Encuentra el archivo que quieres enviar
  3. Confirma que quieres enviarlo

¿Cómo funciona compartir archivos con grupos? ¿Mis archivos se almacenan en algún servidor?

Los archivos se envían a través de conexiones Cwtch Onion a Onion directamente de la persona que ofrece el archivo a la persona que lo recibe. La oferta inicial de enviar un archivo se publica como un mensaje estándar de Cwtch de conversación/superposición. Para grupos, esto significa que la oferta inicial (que contiene el nombre del archivo, el tamaño, el hash y un nonce) se publica en el servidor de grupos, pero entonces cada destinatario se conecta a usted individualmente para recibir el contenido real del archivo.

¿Significa esto que tengo que estar en linea para enviar un archivo?

Sí. Si la persona que ofrece el archivo se desconecta, tendrás que esperar a que se conecte para reanudar la transferencia de archivos. El protocolo subyacente divide los archivos en fragmentos individuales y verificables, para que en una versión futura puedas "rehost" un archivo publicado en un grupo, e incluso descargar desde múltiples hosts a la vez (como bittorrent).

¿Por qué aparecen contactos nuevos en mi lista?

Esto se debe a la forma en que Cwtch maneja actualmente conexiones desde direcciones desconocidas. Puesto que publicar un archivo en un grupo resulta en que los miembros del grupo se conecten directamente contigo, algunos de esos miembros pueden no estar en tu lista de contactos y por lo tanto su conexión de descarga contigo aparecerá en tu lista como una solicitud de contacto.

¿Qué es "SHA512"?

SHA512 es una Función hash criptográfica que puede utilizarse para verificar que el archivo que descargaste es una copia correcta del archivo que se ofreció. Cwtch realiza esta verificación por ti automáticamente, ¡pero eres bienvenido a probarlo tú mismo! Ten en cuenta que incluimos una nonce aleatoria con invitacions de archivos, así que un contacto no puede pedirte cualquier hash aleatorio que tengas o archivos de conversaciones de las que no formen parte.

¿Hay un límite de tamaño de archivo?

El límite actual es de 10 gigabytes por archivo.

¿Qué son los archivos .manifest?

Los archivos .manifest se utilizan al descargar el archivo para verificar que los fragmentos individuales se reciben correctamente, y reanudar transferencias interrumpidas. También contienen la información de la oferta original de archivos. Puedes borrarlos sin problemas una vez que la descarga haya finalizado. En Android, los manifiestos se almacenan en la caché de la aplicación, y se pueden borrar a través de la configuración del sistema.

¿Qué pasa con los metadatos de archivos?

Enviamos el nombre del archivo como sugerencia y le ayudamos a distinguirlo de otras invitaciones de archivos. El camino completo se despoja antes de enviar el archivo. Debes tener cuidado con los metadatos ocultos que pueden almacenarse en el archivo en sí, que varía dependiendo del formato del archivo. Por ejemplo, las imágenes pueden contener información sobre geolocalización e información sobre la cámara que las tomó. Los archivos PDF son notorios por contener información oculta como el nombre del autor o la máquina en la que fueron creados. En general, sólo deberías enviar y recibir archivos de personas en las que confíes.

¿Puedo descargar archivos automáticamente?

If the Image Previews and Profile Pictures experiment is enabled then Cwtch will automatically download images from accepted conversations

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/chat/unblock-contact/index.html b/build-staging/es/docs/chat/unblock-contact/index.html new file mode 100644 index 00000000..8de57cf9 --- /dev/null +++ b/build-staging/es/docs/chat/unblock-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Desbloquear un contacto | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/contribute/developing/index.html b/build-staging/es/docs/contribute/developing/index.html new file mode 100644 index 00000000..15c0d3d3 --- /dev/null +++ b/build-staging/es/docs/contribute/developing/index.html @@ -0,0 +1,24 @@ + + + + + +Developing Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Developing Cwtch

This section documents some ways to get started with Cwtch Development.

Cwtch Issues Tracking Process

All Cwtch issues are tracked from the cwtch-ui git repository, even if the bug/feature originates in an upstream library. This allows us to keep everything in one place.

Issues are generally divided into 4 distinct categories:

  • Unprocessed - These are new issues that have not been discussed by the Cwtch team.
  • Scheduled - These issues have been planned for an upcoming release. They are usually tagged with the release they are expected to be fixed in e.g. cwtch-1.11. A core Cwtch team member is likely working on the issue, or is expecting to work on the issue in the coming weeks.
  • Desired - These are issues that we would like to fix but for some reason we are unable to schedule. This might be because the feature is large and requires a lot of effort, or because there is some blocker (e.g. a missing feature in Flutter or some other library) that prevents work on the feature.
  • Help Wanted - These are generally small issues that we would like to fix but that have been designated low priority. These are ideal first issues for volunteers.

If you would like to work on an open bug/feature, please comment on the issue and a member of the Cwtch team will follow up with advice on where to go from there. This helps us keep track of who is working on what problems, and reduces the amount of duplicate work. We aim to answer most queries within 24 hours, feel free to "bump" an issue if it takes longer than that.

note

Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)

Cwtch Pull-Request Process

All pull-requests must be reviewed and approved by a core Cwtch team member prior to merging. Sarah reviews all new and active pull requests multiple times a week.

Build Bot

All Cwtch projects are set up with automated builds and testing. Every pull request is expected to be able to pass through these pipelines prior to being merged. If buildbot reports a failure then Sarah will work with you to determine the issue, and any necessary fixes.

Buildbot can fail for reasons beyond your control e.g. many of our integration tests rely setting up Tor connections, these can be brittle on occasion and result in timeouts and failures. Always confirm the root cause of a test failure before deciding what to do next.

Useful Resources

note

All contributions are eligible for stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/contribute/documentation/index.html b/build-staging/es/docs/contribute/documentation/index.html new file mode 100644 index 00000000..fdac70a5 --- /dev/null +++ b/build-staging/es/docs/contribute/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Documentation Style Guide | The Cwtch Handbook + + + + + + + + + + + + +
+

Documentation Style Guide

This section documents the expected structure and quality of Cwtch documentation.

Screenshots and Cast of Characters

Most Cwtch documentation should feature at least one screenshot or animated image. Screenshots of the Cwtch application should be focused on the feature being described by the documentation.

To ensure consistency between screenshots we suggest that the profile involved should serve particular, constant, roles.

  • Alice - used to represent the primary profile.
  • Bob - the primary contact, useful when demonstrating peer-to-peer features
  • Carol - a secondary contact, useful when demonstrating group features
  • Mallory - representing a malicious peer (to be used when demonstrating blocking functionality)

Dialogue and Content

Where screenshots and demonstrations show dialogue, conversations, and/or images please keep the conversations short, on a casual topic. Examples include:

  • Organizing a picnic
  • Sharing photos from a vacation
  • Sending a document for review

Experiments

All features that rely on an experiment being enabled should all this out prominently at the top of the page e.g.:

Experiments Required

This feature requires Experiments Enabled and the Example Experiment turned on.

Risks

If a feature might result in destruction of key material or permanent deletion of state, then these should also be called out at the top of the documentation e.g.:

danger

This feature will result in irreversible deletion of key material. This cannot be undone.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/contribute/stickers/index.html b/build-staging/es/docs/contribute/stickers/index.html new file mode 100644 index 00000000..1a3c0625 --- /dev/null +++ b/build-staging/es/docs/contribute/stickers/index.html @@ -0,0 +1,24 @@ + + + + + +Stickers | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/contribute/testing/index.html b/build-staging/es/docs/contribute/testing/index.html new file mode 100644 index 00000000..a0506593 --- /dev/null +++ b/build-staging/es/docs/contribute/testing/index.html @@ -0,0 +1,24 @@ + + + + + +Pruebas de Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Pruebas de Cwtch

Esta sección documenta algunas formas de comenzar con la prueba de Cwtch.

Ejecutar Fuzzbot

FuzzBot es nuestro bot de pruebas de desarrollo. Puede añadir FuzzBot como contacto: cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad.

Ayuda de FuzzBot

Enviar a FuzzBot un mensaje de help lo activará para enviar una respuesta con todos los comandos de prueba disponibles actualmente.

Para más información sobre FuzzBot consulta nuestro Blog de desarrollo.

Únete al Grupo de Pruebas de Candidatos de Lanzamientos de Cwtch

Enviar a Fuzzbot el comando de testgroup-invite hará que FuzzBot te invite al Grupo de Testeadores de Cwtch! Ahí puedes hacer preguntas, publicar informes de errores y ofrecer comentarios.

Cwtch Nightlies

Las construcciones de Cwtch Nightly son construcciones de desarrollo que contienen nuevas características que están listas para probar.

Las versiones más recientes de desarrollo de Cwtch están disponibles en nuestro servidor de compilación.

Nosotros no recomendamos que los testers se actualicen siempre a los últimos Nightlies. En su lugar publicaremos un mensaje en el Grupo de Pruebas de Candidatos de Lanzamientos de Cwtch cuando un Nightlie significativo se encuentre disponible. Un Nightly se considera significativo si contiene una nueva característica o una corrección importante de errores.

note

All contributions are eligible for stickers

Submitting Feedback

There are three main ways of submitting testing feedback to the team:

  • Via Cwtch: Either via the Release Candidate Testers Group or directly to a Cwtch team member.
  • Via Gitea: Please open an issue in https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues - please do not worry about duplicate issues, we will de-duplicate as part of our triage process.
  • Via Email: Email team@cwtch.im with the bug report and one of our team will look into it.
note

Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/contribute/translate/index.html b/build-staging/es/docs/contribute/translate/index.html new file mode 100644 index 00000000..301f85ce --- /dev/null +++ b/build-staging/es/docs/contribute/translate/index.html @@ -0,0 +1,24 @@ + + + + + +Translating Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Translating Cwtch

Si quieres contribuir a la traducción de Cwtch o de este manual puedes aprender cómo aquí

Contributing Translations to the Cwtch Application

There are two ways to contribute to Cwtch applications.

Join our Lokalise Team

We use Lokalise for managing translations for the Cwtch application.

  1. Sign up for a Lokalise account
  2. Email team@cwtch.im with the language you are interested in translating and an email we can use to invite you to our Lokalise team.

Directly via Git

For new translations, you can make a copy of https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb and begin translating - you can then either submit pull requests or directly send updates to us (team@cwtch.im) and we will merge them in.

For adding to existing translations you can make pull requests directly on any file in https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/ and we will review and merge them in.

Manual del usuario de Cwtch

This handbook is translated through Crowdin.

To join our Crowdin project:

  1. Sign up for an account on Crowdin.
  2. Join the cwtch-users-handbook project.

We bundle up changes to the documentation in batches and sync them with the Crowdin project on a regular basis.

note

All contributions are eligible for stickers

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/getting-started/supported_platforms/index.html b/build-staging/es/docs/getting-started/supported_platforms/index.html new file mode 100644 index 00000000..4b35cbc7 --- /dev/null +++ b/build-staging/es/docs/getting-started/supported_platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Supported Platforms | The Cwtch Handbook + + + + + + + + + + + + +
+

Supported Platforms

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. If you are interested in testing Cwtch on a specific platform, or want to volunteer to help us official support a platform not listed here, then check out Contibuting to Cwtch.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOSOfficial SDK supprts arm, arm64, and amd64 architectures.
Other Android Distributions🟡🟡Testing Needed.
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/accept-group-invite/index.html b/build-staging/es/docs/groups/accept-group-invite/index.html new file mode 100644 index 00000000..0984aa26 --- /dev/null +++ b/build-staging/es/docs/groups/accept-group-invite/index.html @@ -0,0 +1,24 @@ + + + + + +Aceptar una invitación de grupo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/create-group/index.html b/build-staging/es/docs/groups/create-group/index.html new file mode 100644 index 00000000..ebecdbd3 --- /dev/null +++ b/build-staging/es/docs/groups/create-group/index.html @@ -0,0 +1,24 @@ + + + + + +Crea un grupo nuevo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/edit-group-name/index.html b/build-staging/es/docs/groups/edit-group-name/index.html new file mode 100644 index 00000000..a41f1819 --- /dev/null +++ b/build-staging/es/docs/groups/edit-group-name/index.html @@ -0,0 +1,24 @@ + + + + + +Editar Nombre de un Grupo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/introduction/index.html b/build-staging/es/docs/groups/introduction/index.html new file mode 100644 index 00000000..ebee8b86 --- /dev/null +++ b/build-staging/es/docs/groups/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Una Introducción a los Grupos de Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Una Introducción a los Grupos de Cwtch

Experimentos Requeridos

Esta función requiere Experimentos habilitados y el Experimento de Grupos activado.

Nota: la Comunicación de Grupos Resistentes a los Metadatos sigue siendo un área de investigación activa y lo que se documenta aquí probablemente cambie en el futuro.

De forma predeterminada, Cwtch sólo soporta chat de persona a persona. Para soportar conversaciones de varias personas y entrega offline, se requiere un tercero (no confiable). Llamamos a estas entidades "servidores"

Estos servidores pueden ser configurados por cualquiera y están pensados para estar siempre en línea. Lo más importante es que toda la comunicación con un servidor está diseñada de tal manera que el servidor aprenda la menor información posible sobre los contenidos o metadatos.

En muchos sentidos, la comunicación con un servidor es idéntica a la comunicación con un contacto regular de Cwtch. Se toman todos los mismos pasos, sin embargo el servidor siempre actúa como el par entrante, y el par saliente siempre utiliza par de claves efímeras - para que cada sesión del servidor esté desconectada.

Como tal, las conversaciones entre pares y servidores solo difieren en los tipos de mensajes que se envían entre las dos partes, con el servidor guardando todos los mensajes que recibe y permitiendo así que cualquier cliente busque mensajes antiguos.

The risk model associated with servers is more complicated that peer-to-peer communication, as such we currently require people who want to use servers within Cwtch to opt-in to the Group Chat experiment in order to add, manage and create groups on untrusted servers.

Cómo funcionan los Grupos en profundidad

Cuando una persona quiere iniciar una conversación grupal, primero genera aleatoriamente una clave grupal secreta. Todas las comunicaciones del grupo serán cifradas usando esta clave.

Junto con la clave de grupo, el creador del grupo también decide elServidor de Cwtch para usar como anfitrión del grupo. Para más información sobre cómo los servidores se autentican ver paquetes de claves.

Un Identificador de grupo se genera usando la clave de grupo y el servidor de grupo. Estos tres elementos se empaquetan en una invitación que puede ser enviada a los miembros potenciales del grupo (i.e a travez de las conexiones peer-to-peer existentes).

Para enviar un mensaje al grupo, un perfil se conecta al servidor que aloja al grupo (ver abajo), y encripta su mensaje usando la Clave de Grupo y genera una firma criptográfica a través de la Identificación de grupo, Servidor de Grupo y el mensaje descifrado (Ve: Formatos wire para más información).

Para recibir mensajes del grupo, un perfil debe estar conectado al servidor que aloja el grupo y descarga todos los mensajes (desde su conexión anterior). Los perfiles intentan descifrar cada mensaje usando la Clave de Grupo si logran verificar la firma (ve servidores de Cwtch, Grupos de Cwtch para una visión general de los ataques y mitigaciones).

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/leave-group/index.html b/build-staging/es/docs/groups/leave-group/index.html new file mode 100644 index 00000000..0e91d00c --- /dev/null +++ b/build-staging/es/docs/groups/leave-group/index.html @@ -0,0 +1,24 @@ + + + + + +Cómo abandonar un grupo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/manage-known-servers/index.html b/build-staging/es/docs/groups/manage-known-servers/index.html new file mode 100644 index 00000000..08639180 --- /dev/null +++ b/build-staging/es/docs/groups/manage-known-servers/index.html @@ -0,0 +1,24 @@ + + + + + +Administrar servidores | The Cwtch Handbook + + + + + + + + + + + + +
+

Administrar servidores

Experimentos Requeridos

Esta función requiere Experimentos habilitados y el Experimento de Grupos activado.

Los grupos de Cwtch están alojados en servidores no confiables. Si quieres ver los servidores que conoces, su estado y los grupos alojados en ellos:

  1. En el panel de contactos
  2. Ve al icono de administrar servidores

Importar servidor alojado localmente

  1. Para importar un servidor alojado localmente haz clic en seleccionar el servidor local
  2. Selecciona el servidor que quieras
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/groups/send-invite/index.html b/build-staging/es/docs/groups/send-invite/index.html new file mode 100644 index 00000000..69ea87ea --- /dev/null +++ b/build-staging/es/docs/groups/send-invite/index.html @@ -0,0 +1,24 @@ + + + + + +Enviar invitaciones a un Grupo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/intro/index.html b/build-staging/es/docs/intro/index.html new file mode 100644 index 00000000..e44b33ca --- /dev/null +++ b/build-staging/es/docs/intro/index.html @@ -0,0 +1,24 @@ + + + + + +¿Qué es Cwtch? | The Cwtch Handbook + + + + + + + + + + + + +
+

¿Qué es Cwtch?

Cwtch (/kʊtʃ/ - Una palabra galesa más o menos traducida a “un abrazo que crea un lugar seguro”) es una aplicación de mensajería descentralizada, que preserva la privacidad.

  • Descentralizado y Abierto: No hay "Servicio de Cwtch" o "Red de Cwtch". Los participantes en Cwtch pueden albergar sus propios espacios seguros o prestar su infraestructura a otros que buscan un espacio seguro. El protocolo Cwtch es abierto, y cualquiera es libre de construir bots, servicios e interfaces de usuario e integrar e interactuar con Cwtch.
  • Preservación de la privacidad: Toda la comunicación en Cwtch está cifrada de extremo a extremo y tiene lugar en los servicios de Onion Tor v3.
  • Resistente a los metadatos: Cwtch ha sido diseñada de tal manera que no hay información intercambiada o disponible para nadie sin su consentimiento explícito, incluyendo mensajes on-the-wire y metadatos de protocolo.

Seguridad y cifrado

Para ver en profundidad la tecnología de seguridad, privacidad y cifrado subyacente utilizada en Cwtch, por favor consulte nuestro Manual de seguridad

Primeros pasos

Puedes descargar la última versión de Cwtch desde https://cwtch.im/download/

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/platforms/tails/index.html b/build-staging/es/docs/platforms/tails/index.html new file mode 100644 index 00000000..b9576536 --- /dev/null +++ b/build-staging/es/docs/platforms/tails/index.html @@ -0,0 +1,24 @@ + + + + + +Running Cwtch on Tails | The Cwtch Handbook + + + + + + + + + + + + +
+

Running Cwtch on Tails

Nightly Feature

This functionality is currently only available in the Nightly Release builds of Cwtch.

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

The following steps require that Tails has been launched with an Administration Password.

Tails uses Onion Grater to guard access to the control port. We have packaged an oniongrater configuration cwtch-tails.yml and setup script (install-tails.sh) with Cwtch on Linux.

The tails-specific part of the script is reproduced below:

    # Tails needs to be have been setup up with an Administration account
#
# Make Auth Cookie Readable
sudo chmod o+r /var/run/tor/control.authcookie
# Copy Onion Grater Config
sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml
# Restart Onion Grater so the Config Takes effect
sudo systemctl restart onion-grater.service

When launching, Cwtch on Tails should be passed the CWTCH_TAILS=true environment variable to automatically configure Cwtch for running in a Tails-like environment:

exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch

Install Location

The above command, and the below onion grater configuration assume that Cwtch was installed in ~/.local/lib/cwtch/cwtch - if Cwtch was installed somewhere else (or if you are running directly from the download folder) then you will need to adjust the commands.

Onion Grater Configuration

The oniongrater configuration cwtch-tails.yml is reproduced below. As noted this configuration is can likely be restricted much further.

    ---
# TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern

- apparmor-profiles:
- '/home/amnesia/.local/lib/cwtch/cwtch'
users:

- 'amnesia'
commands:
AUTHCHALLENGE:

- 'SAFECOOKIE .*'
SETEVENTS:

- 'CIRC WARN ERR'
- 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'
GETINFO:

- '.*'
GETCONF:

- 'DisableNetwork'
SETCONF:

- 'DisableNetwork.*'
ADD_ONION:

- '.*'
DEL_ONION:

- '.+'
HSFETCH:

- '.+'
events:
CIRC:
suppress: true
ORCONN:
suppress: true
INFO:
suppress: true
NOTICE:
suppress: true
WARN:
suppress: true
ERR:
suppress: true
HS_DESC:
response:

- pattern: '650 HS_DESC CREATED (\S+) (\S+) (\S+) \S+ (.+)'
replacement: '650 HS_DESC CREATED {} {} {} redacted {}'

- pattern: '650 HS_DESC UPLOAD (\S+) (\S+) .*'
replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'

- pattern: '650 HS_DESC UPLOADED (\S+) (\S+) .+'
replacement: '650 HS_DESC UPLOADED {} {} redacted'

- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH'

- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'

- pattern: '650 HS_DESC RECEIVED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'

- pattern: '.*'
replacement: ''
HS_DESC_CONTENT:
suppress: true

Persistence

By default, Cwtch creates $HOME/.cwtch and saves all encrypted profiles and settings files there. In order to save any profiles/conversations in Cwtch on Tails you will have to backup this folder to a non-volatile home.

See the Tails documentation for setting up persistent storage

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/availability-status/index.html b/build-staging/es/docs/profiles/availability-status/index.html new file mode 100644 index 00000000..17bdee92 --- /dev/null +++ b/build-staging/es/docs/profiles/availability-status/index.html @@ -0,0 +1,24 @@ + + + + + +Setting Availability Status | The Cwtch Handbook + + + + + + + + + + + + +
+

Setting Availability Status

Nightly Feature

This functionality is currently only available in the Nightly Release builds of Cwtch.

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

On the conversations pane click the Status icon next to your profile picture.

A drop-down menu will appear with various options e.g. Available, Away, and Busy

When you select Away or Busy as a status the border of your profile picture will change to reflect the status

Contacts will see this change reflected in their conversations pane.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/change-name/index.html b/build-staging/es/docs/profiles/change-name/index.html new file mode 100644 index 00000000..44b1721a --- /dev/null +++ b/build-staging/es/docs/profiles/change-name/index.html @@ -0,0 +1,24 @@ + + + + + +Cambiar tu nombre para mostrar | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/change-password/index.html b/build-staging/es/docs/profiles/change-password/index.html new file mode 100644 index 00000000..b7720309 --- /dev/null +++ b/build-staging/es/docs/profiles/change-password/index.html @@ -0,0 +1,24 @@ + + + + + +Cambiar tu contraseña | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/change-profile-image/index.html b/build-staging/es/docs/profiles/change-profile-image/index.html new file mode 100644 index 00000000..50fa225a --- /dev/null +++ b/build-staging/es/docs/profiles/change-profile-image/index.html @@ -0,0 +1,24 @@ + + + + + +Cambiar tu imagen de perfil | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/create-a-profile/index.html b/build-staging/es/docs/profiles/create-a-profile/index.html new file mode 100644 index 00000000..c5f305a4 --- /dev/null +++ b/build-staging/es/docs/profiles/create-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Crear un nuevo perfil | The Cwtch Handbook + + + + + + + + + + + + +
+

Crear un nuevo perfil

  1. Pulsa el botón + en la esquina inferior derecha y selecciona "Nuevo perfil"
  2. Elije un nombre para mostrar
  3. Selecciona si deseas proteger este perfil de forma local con cifrado fuerte:
    • Contraseña: tu cuenta está protegida de otras personas que pueden usar este dispositivo
    • Sin contraseña: cualquiera que tenga acceso a este dispositivo puede acceder a este perfil
  4. Introduce tu contraseña y vuelve a introducirla
  5. Haz clic en añadir un nuevo perfil

Una nota sobre los perfiles protegidos por contraseña (cifrado)

Los perfiles se almacenan localmente en el disco y se cifran usando una clave derivada de la contraseña conocida por el usuario (a través de pbkdf2).

Note that, once encrypted and stored on disk, the only way to recover a profile is by rederiving the key from the password - as such it isn't possible to provide a full list of profiles a user might have access to until they enter a password.

Consultar: Manual de seguridad de Cwtch.: Encriptación del perfil & Almacenamiento

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/delete-profile/index.html b/build-staging/es/docs/profiles/delete-profile/index.html new file mode 100644 index 00000000..3735bfee --- /dev/null +++ b/build-staging/es/docs/profiles/delete-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Eliminar un perfil | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/exporting-profile/index.html b/build-staging/es/docs/profiles/exporting-profile/index.html new file mode 100644 index 00000000..4a5efd16 --- /dev/null +++ b/build-staging/es/docs/profiles/exporting-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Copia de seguridad o Exportación de un perfil | The Cwtch Handbook + + + + + + + + + + + + +
+

Copia de seguridad o Exportación de un perfil

En la pantalla de administración de perfiles:

  1. Pulsa el lápiz junto al perfil que quieres editar
  2. Desplázate hacia abajo hasta la parte inferior de la pantalla
  3. Selecciona "Exportar perfil"
  4. Elige una ubicación y un nombre de archivo
  5. Confirma

Una vez confirmado, Cwtch hará una copia del perfil en la ubicación dada. Este archivo está cifrado al mismo nivel que el perfil. Consulta Una nota sobre Perfiles protegidos con contraseña (cifrados) para obtener más información sobre perfiles cifrados.

Este archivo puede ser importado en otra instancia de Cwtch en cualquier dispositivo.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/importing-a-profile/index.html b/build-staging/es/docs/profiles/importing-a-profile/index.html new file mode 100644 index 00000000..4083a36c --- /dev/null +++ b/build-staging/es/docs/profiles/importing-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Importar un perfil | The Cwtch Handbook + + + + + + + + + + + + +
+

Importar un perfil

  1. Pulsa el botón + en la esquina inferior derecha y selecciona "Importar perfil"
  2. Selecciona un archivo de perfil exportado de Cwtch para importar
  3. Introduce la contraseña asociada con el perfil y confirma.

Una vez confirmado, Cwtch intentará descifrar el archivo proporcionado usando una clave derivada de la contraseña dada. Si es exitoso el perfil aparecerá en la pantalla de Administración de Perfiles y estará listo para usar.

note

Aunque un perfil puede ser importado en varios dispositivos, actualmente sólo una versión de un perfil puede estar en uso en todos los dispositivos a la vez.

Los intentos de usar el mismo perfil en varios dispositivos puede resultar en problemas de disponibilidad y fallos de mensajería.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/introduction/index.html b/build-staging/es/docs/profiles/introduction/index.html new file mode 100644 index 00000000..f864ab26 --- /dev/null +++ b/build-staging/es/docs/profiles/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Una Introducción a los Perfiles de Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Una Introducción a los Perfiles de Cwtch

Con Cwtch puedes crear uno o más Perfiles. Cada perfil genera un par de claves aleatorias ed25519 compatibles con la Red Tor.

Este es el identificador que puedes dar a tus contactos y que pueden usar para contactarte a través de Cwtch.

Cwtch te permite crear y administrar perfiles múltiples y separados. Cada perfil está asociado con un par de claves diferente que lanza un servicio de Onion diferente.

Administrar Perfiles

Al iniciarse Cwtch lanzará la pantalla Administrar Perfiles. Desde esta pantalla puedes:

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/profile-info/index.html b/build-staging/es/docs/profiles/profile-info/index.html new file mode 100644 index 00000000..21e59628 --- /dev/null +++ b/build-staging/es/docs/profiles/profile-info/index.html @@ -0,0 +1,24 @@ + + + + + +Setting Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Setting Profile Attributes

Nightly Feature

This functionality is currently only available in the Nightly Release builds of Cwtch.

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

On the profile management pane there are three free-form text fields below your profile picture.

You can fill these fields with any information your would like potential contacts to know. This information is public - do not put any information in here that you do not want to share with everyone.

Contacts will be able to see this information in conversation settings

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/profiles/unlock-profile/index.html b/build-staging/es/docs/profiles/unlock-profile/index.html new file mode 100644 index 00000000..844301a5 --- /dev/null +++ b/build-staging/es/docs/profiles/unlock-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Desbloquear perfiles cifrados | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/servers/create-server/index.html b/build-staging/es/docs/servers/create-server/index.html new file mode 100644 index 00000000..b552e5d4 --- /dev/null +++ b/build-staging/es/docs/servers/create-server/index.html @@ -0,0 +1,24 @@ + + + + + +Cómo crear un servidor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/servers/delete-server/index.html b/build-staging/es/docs/servers/delete-server/index.html new file mode 100644 index 00000000..06d3dc63 --- /dev/null +++ b/build-staging/es/docs/servers/delete-server/index.html @@ -0,0 +1,24 @@ + + + + + +Cómo eliminar un servidor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/servers/edit-server/index.html b/build-staging/es/docs/servers/edit-server/index.html new file mode 100644 index 00000000..52e567f7 --- /dev/null +++ b/build-staging/es/docs/servers/edit-server/index.html @@ -0,0 +1,24 @@ + + + + + +Cómo editar un servidor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/servers/introduction/index.html b/build-staging/es/docs/servers/introduction/index.html new file mode 100644 index 00000000..ee31e190 --- /dev/null +++ b/build-staging/es/docs/servers/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Introducción a Servidores | The Cwtch Handbook + + + + + + + + + + + + +
+

Introducción a Servidores

Experimentos Requeridos

Esta función requiere Experimentos habilitados y el Experimento de Grupos activado.

El chat de Cwtch entre dos usuarios es completamente par a par (peer-to-peer), lo que significa que si un usuario está desconectado no puedes chatear con él, y no hay un mecanismo para que múltiples personas puedan chatear.

Para dar soporte al chat de grupo (y a la entrega sin conexión) hemos creado servidores no confiables que pueden albergar mensajes para un grupo. Los mensajes se cifran con la clave del grupo, y se obtienen a través de Onions efímeros, por lo que el servidor no tiene forma de saber qué mensajes podría tener para qué grupos, o quién está accediendo a él.

Los servidores que se ejecutan actualmente en la aplicación Cwtc sólo son compatibles con la versión de Escritorio ya que la conexión a Internet de los dispositivos móviles y el entorno móvil es demasiado inestable e inadecuado para ejecutar un servidor.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/servers/share-key/index.html b/build-staging/es/docs/servers/share-key/index.html new file mode 100644 index 00000000..afdb7947 --- /dev/null +++ b/build-staging/es/docs/servers/share-key/index.html @@ -0,0 +1,24 @@ + + + + + +Cómo compartir tu Paquete de Claves del Servidor | The Cwtch Handbook + + + + + + + + + + + + +
+

Cómo compartir tu Paquete de Claves del Servidor

Experimentos Requeridos

Esta función requiere Experimentos habilitados y el Experimento de Grupos activado.

El Paquete de Claves del Servidor es el paquete de datos que una aplicación Cwtch necesita para poder usar un servidor. Si sólo quieres hacer que otros usuarios de Cwtch tengan conocimiento de tu servidor, puedes compartir ésto con ellos. Entonces tendrán la habilidad de crear sus propios grupos en el servidor.

  1. Ve al icono del servidor
  2. Selecciona el servidor que quieras
  3. Usa el icono de copiar la dirección para copiar las claves del servidor
  4. No compartas las claves con gente en la que no confías
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/servers/unlock-server/index.html b/build-staging/es/docs/servers/unlock-server/index.html new file mode 100644 index 00000000..95168371 --- /dev/null +++ b/build-staging/es/docs/servers/unlock-server/index.html @@ -0,0 +1,24 @@ + + + + + +Cómo desbloquear un servidor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/appearance/change-language/index.html b/build-staging/es/docs/settings/appearance/change-language/index.html new file mode 100644 index 00000000..bf23b34a --- /dev/null +++ b/build-staging/es/docs/settings/appearance/change-language/index.html @@ -0,0 +1,24 @@ + + + + + +Cambiar idioma | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/appearance/light-dark-mode/index.html b/build-staging/es/docs/settings/appearance/light-dark-mode/index.html new file mode 100644 index 00000000..d58ad96d --- /dev/null +++ b/build-staging/es/docs/settings/appearance/light-dark-mode/index.html @@ -0,0 +1,24 @@ + + + + + +Explicación de temas Claros/Oscuros | The Cwtch Handbook + + + + + + + + + + + + +
+

Explicación de temas Claros/Oscuros

  1. Pulsa el icono de configuración
  2. Puedes elegir tema claro u oscuro activando el interruptor de "usar temas claros"
  3. Usando el menú desplegable "temas de color", elige un tema que te guste
    1. Cwtch: tonos morados
    2. Fantasma: Tonos grises
    3. Sirena: Tonos turquesa y morados
    4. Medianoche: Tonos negros y grises
    5. Neón 1: Tonos morados y rosados
    6. Neón 2: Tonos morados y turquesa
    7. Calabaza: Tonos morados y naranjas
    8. Bruja: Tonos verdes y rosas
    9. Vampiro: Tonos morados y rojos
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/appearance/streamer-mode/index.html b/build-staging/es/docs/settings/appearance/streamer-mode/index.html new file mode 100644 index 00000000..a9cb4a5b --- /dev/null +++ b/build-staging/es/docs/settings/appearance/streamer-mode/index.html @@ -0,0 +1,24 @@ + + + + + +Modo de streaming/presentación | The Cwtch Handbook + + + + + + + + + + + + +
+

Modo de streaming/presentación

El modo de streaming / presentación hace la aplicación más visualmente privada. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens.

Esto es útil cuando se toman capturas de pantalla o cuando se muestra Cwtch de una manera más pública.

  1. Pulsa el icono de configuración
  2. Activar "Modo Streamer"
  3. Comprueba que funciona mirando tu perfil o tu lista de contactos
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/appearance/ui-columns/index.html b/build-staging/es/docs/settings/appearance/ui-columns/index.html new file mode 100644 index 00000000..e3d8fd81 --- /dev/null +++ b/build-staging/es/docs/settings/appearance/ui-columns/index.html @@ -0,0 +1,24 @@ + + + + + +Columnas de interfaz | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/behaviour/block-unknown-connections/index.html b/build-staging/es/docs/settings/behaviour/block-unknown-connections/index.html new file mode 100644 index 00000000..cb6397de --- /dev/null +++ b/build-staging/es/docs/settings/behaviour/block-unknown-connections/index.html @@ -0,0 +1,24 @@ + + + + + +Bloquear Conexiones Desconocidas | The Cwtch Handbook + + + + + + + + + + + + +
+

Bloquear Conexiones Desconocidas

By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. Puede cambiar este comportamiento a través de la configuración de Bloquear Conexiones Desconocidas.

Si está activado, Cwtch cerrará automáticamente todas las conexiones de las direcciones de Cwtch que no has añadido a tu lista de contactos. This will prevent people who have your Cwtch address from contacting you unless you also add them.

Para habilitar:

  1. Ve a la Configuración
  2. Habilita Bloquear Contactos Desconocidos
+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/behaviour/notification-content/index.html b/build-staging/es/docs/settings/behaviour/notification-content/index.html new file mode 100644 index 00000000..6c4ad105 --- /dev/null +++ b/build-staging/es/docs/settings/behaviour/notification-content/index.html @@ -0,0 +1,24 @@ + + + + + +Contenido de notificaciones | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/behaviour/notification-policy/index.html b/build-staging/es/docs/settings/behaviour/notification-policy/index.html new file mode 100644 index 00000000..9b4f5629 --- /dev/null +++ b/build-staging/es/docs/settings/behaviour/notification-policy/index.html @@ -0,0 +1,24 @@ + + + + + +Política de notificaciones | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/clickable-links/index.html b/build-staging/es/docs/settings/experiments/clickable-links/index.html new file mode 100644 index 00000000..65c3a546 --- /dev/null +++ b/build-staging/es/docs/settings/experiments/clickable-links/index.html @@ -0,0 +1,24 @@ + + + + + +Experimento de Enlaces Cliqueables | The Cwtch Handbook + + + + + + + + + + + + +
+

Experimento de Enlaces Cliqueables

danger

Esta función, si está activada, presenta un riesgo de desanonimización.

no abras las URLs de personas en las que no confías. Los enlaces enviados a través de Cwtch se abren a través del navegador predeterminado en el sistema. La mayoría de los navegadores web no pueden proporcionar anonimato.

Activa el Experimento de Enlaces Cliqueables

Los enlaces cliqueables no están habilitados por defecto. Para permitir a Cwtch abrir enlaces en mensajes:

  1. Ir a Configuración
  2. Habilitar Experimentos
  3. Activa el Experimento de Enlaces Cliqueables

Riesgos

Los enlaces cliqueables en los mensajes son una característica muy útil, sin embargo, hay riesgos que debes tener en cuenta si decides activar esta función.

Para prevenir la activación accidental, después de hacer clic en un enlace en un mensaje, Cwtch abrirá primero un aviso adicional con dos opciones:

  1. Copia la URL al portapapeles
  2. Abre la URL en el navegador web predeterminado

Puedes usar el botón de retroceso de tu dispositivo o hacer clic lejos de este aviso para evitar seleccionar cualquiera de las dos opciones.

Cwtch No puede protegerte si abres enlaces maliciosos.

La URL se abre en el navegador web predeterminado el cual es probable, como mínimo, que exponga tu dirección IP al servidor que aloja la URL. Las páginas web también pueden usar otras vulnerabilidades del navegador para obtener información adicional, o aprovecharse aún más de tu equipo.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/file-sharing/index.html b/build-staging/es/docs/settings/experiments/file-sharing/index.html new file mode 100644 index 00000000..4475c6fd --- /dev/null +++ b/build-staging/es/docs/settings/experiments/file-sharing/index.html @@ -0,0 +1,24 @@ + + + + + +Compartir Archivos | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/group-experiment/index.html b/build-staging/es/docs/settings/experiments/group-experiment/index.html new file mode 100644 index 00000000..f3d641b6 --- /dev/null +++ b/build-staging/es/docs/settings/experiments/group-experiment/index.html @@ -0,0 +1,24 @@ + + + + + +Groups Experiment | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/image-previews-and-profile-pictures/index.html b/build-staging/es/docs/settings/experiments/image-previews-and-profile-pictures/index.html new file mode 100644 index 00000000..92b04079 --- /dev/null +++ b/build-staging/es/docs/settings/experiments/image-previews-and-profile-pictures/index.html @@ -0,0 +1,24 @@ + + + + + +Vista previa de imágenes y fotos de perfil | The Cwtch Handbook + + + + + + + + + + + + +
+

Vista previa de imágenes y fotos de perfil

caution

This experiment requires the File Sharing experiment enabled.

When enabled, Cwtch will download image files automatically, display image previews in the conversation window, and enable the Profile Pictures feature;

On Desktop, enabling this experiment will allow access to an additional setting "Download Folder` which can be changed to tell Cwtch where to (automatically) download pictures.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/message-formatting/index.html b/build-staging/es/docs/settings/experiments/message-formatting/index.html new file mode 100644 index 00000000..c9db8fae --- /dev/null +++ b/build-staging/es/docs/settings/experiments/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Formato de mensajes | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/qrcodes/index.html b/build-staging/es/docs/settings/experiments/qrcodes/index.html new file mode 100644 index 00000000..93cb83d8 --- /dev/null +++ b/build-staging/es/docs/settings/experiments/qrcodes/index.html @@ -0,0 +1,24 @@ + + + + + +QR Codes | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/experiments/server-hosting/index.html b/build-staging/es/docs/settings/experiments/server-hosting/index.html new file mode 100644 index 00000000..c58d2e7c --- /dev/null +++ b/build-staging/es/docs/settings/experiments/server-hosting/index.html @@ -0,0 +1,24 @@ + + + + + +Alojamiento de servidor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/docs/settings/introduction/index.html b/build-staging/es/docs/settings/introduction/index.html new file mode 100644 index 00000000..63332a5b --- /dev/null +++ b/build-staging/es/docs/settings/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Una Introducción a la configuración de Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Una Introducción a la configuración de Cwtch

Apariencia

These are settings which effect how Cwtch looks, including themes and localization.

Comportamiento

These settings impact how Cwtch responds to certain events e.g. notifications for new messages, or requests from unknown public addresses.

Experimentos

Hay muchas características en Cwtch que a los usuarios les gustaría tener pero cuya implementación requiere metadatos adicionales, o riesgo, más allá del mínimo que Cwtch requiere para operaciones básicas.

Como tal en Experimentos encontrarás un número de ajustes opcionales que, cuando se activan, proporcionan características adicionales como chat de grupo, intercambio de archivos o formato de mensaje.

Deberías pensar detenidamente al habilitar estas características sobre los nuevos riesgos que podrían implicar, y si estás cómodo optando por esos riesgos. Para muchos, los beneficios de compartir archivos, las previsualizaciones de imágenes y el chat de grupo superan con creces los daños potenciales - pero para otros requerimos que los usuarios opten por usar estas características.

Puede optar por no hacerlo en cualquier momento, todas las características se implementan localmente dentro de la aplicación Cwtch.

+ + + + \ No newline at end of file diff --git a/build-staging/es/docs/tor/index.html b/build-staging/es/docs/tor/index.html new file mode 100644 index 00000000..f334674c --- /dev/null +++ b/build-staging/es/docs/tor/index.html @@ -0,0 +1,24 @@ + + + + + +Tor | The Cwtch Handbook + + + + + + + + + + + + +
+

Tor

Cwtch utiliza Tor para proporcionar enrutamiento y conexiones. Usar servicios ocultos de Tor para albergar perfiles y conexiones "efímeras" proporciona fuertes garantías de anonimato a los usuarios de Cwtch a la hora de hacer conexiones.

Panel de Tor

Dado que estamos añadiendo una capa de red adicional a Cwtch, proporcionamos un panel para ver el estado de la red Tor y hacer cambios. Para acceder a él

  1. Desde el panel de lista de perfiles, haz clic en el icono de Tor icono de tor
  2. Ver el estado de la red tor
Estado de Tor: en línea
Versión Tor: 0.4.6.9

Reiniciar Tor

La red Tor puede ocasionalmente tener conexiones obsoletas que no son detectadas inmediatamente por Tor o por Cwtch (siempre estamos intentando mejorar esto). A veces un usuario puede encontrar contactos o grupos que aparecen fuera de línea que deberían estar en línea. Si quieres reiniciar todas las conexiones de red en Cwtch, proporcionamos un mecanismo para reiniciar tor desde el app. El botón Reiniciar reiniciará Tor desde la aplicación de Cwtch.

Consenso de Caché de Tor

Por defecto iniciamos un proceso nuevo de Tor cada vez que arranca la aplicación, y requiere descargar un estado de red de Tor antes de poder comenzar. Este proceso no es instantáneo. Si quieres acelerar el arranque de Cwtch, puedes habilitar Caché de Conflictos de Tor para acelerar futuros arranques. Si te encuentras con un problema de arranque en el que los datos son obsoletos o corruptos y el reporte de Cwtch no puede arrancar Tor, desactiva esta función y reinicia tor de nuevo, y debería funcionar.

Configuración avanzada de Tor

Ofrecemos la posibilidad de proporcionar avanzadamente la opción de configuración de Tor en esta sección permitiéndote

  • Especificar un puerto SOCKS personalizado para conectarse a una conexión Tor existente
  • Especifique un puerto de control personalizado para conectarse a una conexión Tor existente
  • y especificar opciones adicionales introduciendo opciones torrc personalizadas
+ + + + \ No newline at end of file diff --git a/build-staging/es/img/1.10.midnight.png b/build-staging/es/img/1.10.midnight.png new file mode 100644 index 00000000..e706a501 Binary files /dev/null and b/build-staging/es/img/1.10.midnight.png differ diff --git a/build-staging/es/img/1.png b/build-staging/es/img/1.png new file mode 100644 index 00000000..65538ea1 Binary files /dev/null and b/build-staging/es/img/1.png differ diff --git a/build-staging/es/img/2.png b/build-staging/es/img/2.png new file mode 100644 index 00000000..4de6eb1c Binary files /dev/null and b/build-staging/es/img/2.png differ diff --git a/build-staging/es/img/3.png b/build-staging/es/img/3.png new file mode 100644 index 00000000..7aac7c0a Binary files /dev/null and b/build-staging/es/img/3.png differ diff --git a/build-staging/es/img/4.png b/build-staging/es/img/4.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/es/img/4.png differ diff --git a/build-staging/es/img/5_year_banner.png b/build-staging/es/img/5_year_banner.png new file mode 100644 index 00000000..ecc179a9 Binary files /dev/null and b/build-staging/es/img/5_year_banner.png differ diff --git a/build-staging/es/img/Anti-Spam_1.svg b/build-staging/es/img/Anti-Spam_1.svg new file mode 100644 index 00000000..3860cbfb --- /dev/null +++ b/build-staging/es/img/Anti-Spam_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Anti-Spam_2.svg b/build-staging/es/img/Anti-Spam_2.svg new file mode 100644 index 00000000..eb7a90b7 --- /dev/null +++ b/build-staging/es/img/Anti-Spam_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Anti-Spam_3.svg b/build-staging/es/img/Anti-Spam_3.svg new file mode 100644 index 00000000..df33b751 --- /dev/null +++ b/build-staging/es/img/Anti-Spam_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/BASE_0.png b/build-staging/es/img/BASE_0.png new file mode 100644 index 00000000..384cbefa Binary files /dev/null and b/build-staging/es/img/BASE_0.png differ diff --git a/build-staging/es/img/BASE_1.png b/build-staging/es/img/BASE_1.png new file mode 100644 index 00000000..0adb8240 Binary files /dev/null and b/build-staging/es/img/BASE_1.png differ diff --git a/build-staging/es/img/BASE_2.png b/build-staging/es/img/BASE_2.png new file mode 100644 index 00000000..d1cbb8e5 Binary files /dev/null and b/build-staging/es/img/BASE_2.png differ diff --git a/build-staging/es/img/BASE_3.png b/build-staging/es/img/BASE_3.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/es/img/BASE_3.png differ diff --git a/build-staging/es/img/BASE_5.png b/build-staging/es/img/BASE_5.png new file mode 100644 index 00000000..0330d03b Binary files /dev/null and b/build-staging/es/img/BASE_5.png differ diff --git a/build-staging/es/img/BASE_6.png b/build-staging/es/img/BASE_6.png new file mode 100644 index 00000000..3de5d899 Binary files /dev/null and b/build-staging/es/img/BASE_6.png differ diff --git a/build-staging/es/img/BASE_7.png b/build-staging/es/img/BASE_7.png new file mode 100644 index 00000000..00f730ad Binary files /dev/null and b/build-staging/es/img/BASE_7.png differ diff --git a/build-staging/es/img/BASE_8.png b/build-staging/es/img/BASE_8.png new file mode 100644 index 00000000..3881065e Binary files /dev/null and b/build-staging/es/img/BASE_8.png differ diff --git a/build-staging/es/img/Create_group.svg b/build-staging/es/img/Create_group.svg new file mode 100644 index 00000000..47001a56 --- /dev/null +++ b/build-staging/es/img/Create_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Eye_Closed.svg b/build-staging/es/img/Eye_Closed.svg new file mode 100644 index 00000000..01e6e0b0 --- /dev/null +++ b/build-staging/es/img/Eye_Closed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Eye_Open.svg b/build-staging/es/img/Eye_Open.svg new file mode 100644 index 00000000..3f29f7e1 --- /dev/null +++ b/build-staging/es/img/Eye_Open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/HB_svg_1.svg b/build-staging/es/img/HB_svg_1.svg new file mode 100644 index 00000000..4dd29705 --- /dev/null +++ b/build-staging/es/img/HB_svg_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/HB_svg_2.svg b/build-staging/es/img/HB_svg_2.svg new file mode 100644 index 00000000..4a4f36d3 --- /dev/null +++ b/build-staging/es/img/HB_svg_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/HB_svg_3.svg b/build-staging/es/img/HB_svg_3.svg new file mode 100644 index 00000000..f385b41a --- /dev/null +++ b/build-staging/es/img/HB_svg_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/HB_svg_4.svg b/build-staging/es/img/HB_svg_4.svg new file mode 100644 index 00000000..cf7ee829 --- /dev/null +++ b/build-staging/es/img/HB_svg_4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/OP_eye.svg b/build-staging/es/img/OP_eye.svg new file mode 100644 index 00000000..f12b17e5 --- /dev/null +++ b/build-staging/es/img/OP_eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Onion_Waiting.svg b/build-staging/es/img/Onion_Waiting.svg new file mode 100644 index 00000000..1f4f8005 --- /dev/null +++ b/build-staging/es/img/Onion_Waiting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Onion_off.svg b/build-staging/es/img/Onion_off.svg new file mode 100644 index 00000000..8075d469 --- /dev/null +++ b/build-staging/es/img/Onion_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Onion_on.svg b/build-staging/es/img/Onion_on.svg new file mode 100644 index 00000000..51771b97 --- /dev/null +++ b/build-staging/es/img/Onion_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Screenshot_2022-06-17_13-42-19.png b/build-staging/es/img/Screenshot_2022-06-17_13-42-19.png new file mode 100644 index 00000000..f3bd84ac Binary files /dev/null and b/build-staging/es/img/Screenshot_2022-06-17_13-42-19.png differ diff --git a/build-staging/es/img/Tor_Booting_up.svg b/build-staging/es/img/Tor_Booting_up.svg new file mode 100644 index 00000000..2df93fe0 --- /dev/null +++ b/build-staging/es/img/Tor_Booting_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Tor_OFF.svg b/build-staging/es/img/Tor_OFF.svg new file mode 100644 index 00000000..fd2a714c --- /dev/null +++ b/build-staging/es/img/Tor_OFF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/Tor_icon.png b/build-staging/es/img/Tor_icon.png new file mode 100644 index 00000000..0c871e9f Binary files /dev/null and b/build-staging/es/img/Tor_icon.png differ diff --git a/build-staging/es/img/View_replies.svg b/build-staging/es/img/View_replies.svg new file mode 100644 index 00000000..03cae418 --- /dev/null +++ b/build-staging/es/img/View_replies.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/aar-diff.png b/build-staging/es/img/aar-diff.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/es/img/aar-diff.png differ diff --git a/build-staging/es/img/account_blocked.svg b/build-staging/es/img/account_blocked.svg new file mode 100644 index 00000000..412efcff --- /dev/null +++ b/build-staging/es/img/account_blocked.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/build-staging/es/img/account_circle-24px.svg b/build-staging/es/img/account_circle-24px.svg new file mode 100644 index 00000000..013a30af --- /dev/null +++ b/build-staging/es/img/account_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/account_circle-24px_lines.svg b/build-staging/es/img/account_circle-24px_lines.svg new file mode 100644 index 00000000..9fec981a --- /dev/null +++ b/build-staging/es/img/account_circle-24px_lines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/account_circle-24px_lines_thin - blocked.svg b/build-staging/es/img/account_circle-24px_lines_thin - blocked.svg new file mode 100644 index 00000000..5c3b9b7a --- /dev/null +++ b/build-staging/es/img/account_circle-24px_lines_thin - blocked.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/build-staging/es/img/account_circle-24px_lines_thin.svg b/build-staging/es/img/account_circle-24px_lines_thin.svg new file mode 100644 index 00000000..7ded72ff --- /dev/null +++ b/build-staging/es/img/account_circle-24px_lines_thin.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/build-staging/es/img/account_circle-24px_negative_space.svg b/build-staging/es/img/account_circle-24px_negative_space.svg new file mode 100644 index 00000000..c9c4f83c --- /dev/null +++ b/build-staging/es/img/account_circle-24px_negative_space.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/build-staging/es/img/account_circle-24px_user.svg b/build-staging/es/img/account_circle-24px_user.svg new file mode 100644 index 00000000..3eb8ffc7 --- /dev/null +++ b/build-staging/es/img/account_circle-24px_user.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/build-staging/es/img/add_circle-24px.svg b/build-staging/es/img/add_circle-24px.svg new file mode 100644 index 00000000..e8e583ad --- /dev/null +++ b/build-staging/es/img/add_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/add_group.svg b/build-staging/es/img/add_group.svg new file mode 100644 index 00000000..c4a8658e --- /dev/null +++ b/build-staging/es/img/add_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/add_peer.svg b/build-staging/es/img/add_peer.svg new file mode 100644 index 00000000..0b15edbd --- /dev/null +++ b/build-staging/es/img/add_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/android.png b/build-staging/es/img/android.png new file mode 100644 index 00000000..afee7fce Binary files /dev/null and b/build-staging/es/img/android.png differ diff --git a/build-staging/es/img/android.svg b/build-staging/es/img/android.svg new file mode 100644 index 00000000..f743813f --- /dev/null +++ b/build-staging/es/img/android.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/build-staging/es/img/apple.svg b/build-staging/es/img/apple.svg new file mode 100644 index 00000000..a090c68e --- /dev/null +++ b/build-staging/es/img/apple.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/build-staging/es/img/attach_file-24px.svg b/build-staging/es/img/attach_file-24px.svg new file mode 100644 index 00000000..471fb991 --- /dev/null +++ b/build-staging/es/img/attach_file-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/attached-file-2.svg b/build-staging/es/img/attached-file-2.svg new file mode 100644 index 00000000..0f7b9eb3 --- /dev/null +++ b/build-staging/es/img/attached-file-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/attached-file-3.svg b/build-staging/es/img/attached-file-3.svg new file mode 100644 index 00000000..37e2f74a --- /dev/null +++ b/build-staging/es/img/attached-file-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/attached-file.svg b/build-staging/es/img/attached-file.svg new file mode 100644 index 00000000..28ea8263 --- /dev/null +++ b/build-staging/es/img/attached-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/block-24px.svg b/build-staging/es/img/block-24px.svg new file mode 100644 index 00000000..8636ff6a --- /dev/null +++ b/build-staging/es/img/block-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/block_peer.svg b/build-staging/es/img/block_peer.svg new file mode 100644 index 00000000..fb4a84e7 --- /dev/null +++ b/build-staging/es/img/block_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/block_unknown.svg b/build-staging/es/img/block_unknown.svg new file mode 100644 index 00000000..f5afc576 --- /dev/null +++ b/build-staging/es/img/block_unknown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/card_header.png b/build-staging/es/img/card_header.png new file mode 100644 index 00000000..aaa0368b Binary files /dev/null and b/build-staging/es/img/card_header.png differ diff --git a/build-staging/es/img/change_language.svg b/build-staging/es/img/change_language.svg new file mode 100644 index 00000000..d36e819b --- /dev/null +++ b/build-staging/es/img/change_language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/change_theme.svg b/build-staging/es/img/change_theme.svg new file mode 100644 index 00000000..95bf1fd4 --- /dev/null +++ b/build-staging/es/img/change_theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/check-24px.svg b/build-staging/es/img/check-24px.svg new file mode 100644 index 00000000..c5c42b66 --- /dev/null +++ b/build-staging/es/img/check-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/chevron_left-24px.svg b/build-staging/es/img/chevron_left-24px.svg new file mode 100644 index 00000000..6f78ae79 --- /dev/null +++ b/build-staging/es/img/chevron_left-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/clear-24px.svg b/build-staging/es/img/clear-24px.svg new file mode 100644 index 00000000..08149461 --- /dev/null +++ b/build-staging/es/img/clear-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/clickable_links.png b/build-staging/es/img/clickable_links.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/es/img/clickable_links.png differ diff --git a/build-staging/es/img/clickable_links_experiment.png b/build-staging/es/img/clickable_links_experiment.png new file mode 100644 index 00000000..1d809218 Binary files /dev/null and b/build-staging/es/img/clickable_links_experiment.png differ diff --git a/build-staging/es/img/conversations/settings-full.png b/build-staging/es/img/conversations/settings-full.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/es/img/conversations/settings-full.png differ diff --git a/build-staging/es/img/conversations/settings.png b/build-staging/es/img/conversations/settings.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/es/img/conversations/settings.png differ diff --git a/build-staging/es/img/cwtch phones.png b/build-staging/es/img/cwtch phones.png new file mode 100644 index 00000000..54396db9 Binary files /dev/null and b/build-staging/es/img/cwtch phones.png differ diff --git a/build-staging/es/img/cwtch_handbook_header.jpg b/build-staging/es/img/cwtch_handbook_header.jpg new file mode 100644 index 00000000..7b75a456 Binary files /dev/null and b/build-staging/es/img/cwtch_handbook_header.jpg differ diff --git a/build-staging/es/img/cwtch_knott.svg b/build-staging/es/img/cwtch_knott.svg new file mode 100644 index 00000000..7b16f58f --- /dev/null +++ b/build-staging/es/img/cwtch_knott.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/delete-24px.svg b/build-staging/es/img/delete-24px.svg new file mode 100644 index 00000000..8f6e9a27 --- /dev/null +++ b/build-staging/es/img/delete-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/dev9-host-disabled.png b/build-staging/es/img/dev9-host-disabled.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/es/img/dev9-host-disabled.png differ diff --git a/build-staging/es/img/devlog1.jpg b/build-staging/es/img/devlog1.jpg new file mode 100644 index 00000000..639ccabd Binary files /dev/null and b/build-staging/es/img/devlog1.jpg differ diff --git a/build-staging/es/img/devlog1.png b/build-staging/es/img/devlog1.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/es/img/devlog1.png differ diff --git a/build-staging/es/img/devlog10.png b/build-staging/es/img/devlog10.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/es/img/devlog10.png differ diff --git a/build-staging/es/img/devlog10_small.png b/build-staging/es/img/devlog10_small.png new file mode 100644 index 00000000..d27ea94f Binary files /dev/null and b/build-staging/es/img/devlog10_small.png differ diff --git a/build-staging/es/img/devlog12.png b/build-staging/es/img/devlog12.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/es/img/devlog12.png differ diff --git a/build-staging/es/img/devlog12_small.png b/build-staging/es/img/devlog12_small.png new file mode 100644 index 00000000..425cd4bb Binary files /dev/null and b/build-staging/es/img/devlog12_small.png differ diff --git a/build-staging/es/img/devlog13.png b/build-staging/es/img/devlog13.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/es/img/devlog13.png differ diff --git a/build-staging/es/img/devlog13_small.png b/build-staging/es/img/devlog13_small.png new file mode 100644 index 00000000..e6de7752 Binary files /dev/null and b/build-staging/es/img/devlog13_small.png differ diff --git a/build-staging/es/img/devlog1_small.jpg b/build-staging/es/img/devlog1_small.jpg new file mode 100644 index 00000000..a7ffb46a Binary files /dev/null and b/build-staging/es/img/devlog1_small.jpg differ diff --git a/build-staging/es/img/devlog2.png b/build-staging/es/img/devlog2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/es/img/devlog2.png differ diff --git a/build-staging/es/img/devlog2_small.png b/build-staging/es/img/devlog2_small.png new file mode 100644 index 00000000..0eb53c1f Binary files /dev/null and b/build-staging/es/img/devlog2_small.png differ diff --git a/build-staging/es/img/devlog3.png b/build-staging/es/img/devlog3.png new file mode 100644 index 00000000..b1a2a9a3 Binary files /dev/null and b/build-staging/es/img/devlog3.png differ diff --git a/build-staging/es/img/devlog3_small.png b/build-staging/es/img/devlog3_small.png new file mode 100644 index 00000000..dc99bef2 Binary files /dev/null and b/build-staging/es/img/devlog3_small.png differ diff --git a/build-staging/es/img/devlog4.png b/build-staging/es/img/devlog4.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/es/img/devlog4.png differ diff --git a/build-staging/es/img/devlog4_small.png b/build-staging/es/img/devlog4_small.png new file mode 100644 index 00000000..77354e45 Binary files /dev/null and b/build-staging/es/img/devlog4_small.png differ diff --git a/build-staging/es/img/devlog5.png b/build-staging/es/img/devlog5.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/es/img/devlog5.png differ diff --git a/build-staging/es/img/devlog5_small.png b/build-staging/es/img/devlog5_small.png new file mode 100644 index 00000000..c2a4d835 Binary files /dev/null and b/build-staging/es/img/devlog5_small.png differ diff --git a/build-staging/es/img/devlog6.png b/build-staging/es/img/devlog6.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/es/img/devlog6.png differ diff --git a/build-staging/es/img/devlog6_small.png b/build-staging/es/img/devlog6_small.png new file mode 100644 index 00000000..384738b5 Binary files /dev/null and b/build-staging/es/img/devlog6_small.png differ diff --git a/build-staging/es/img/devlog7.png b/build-staging/es/img/devlog7.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/es/img/devlog7.png differ diff --git a/build-staging/es/img/devlog7_small.png b/build-staging/es/img/devlog7_small.png new file mode 100644 index 00000000..a919c58d Binary files /dev/null and b/build-staging/es/img/devlog7_small.png differ diff --git a/build-staging/es/img/devlog8.png b/build-staging/es/img/devlog8.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/es/img/devlog8.png differ diff --git a/build-staging/es/img/devlog8_small.png b/build-staging/es/img/devlog8_small.png new file mode 100644 index 00000000..64d19eab Binary files /dev/null and b/build-staging/es/img/devlog8_small.png differ diff --git a/build-staging/es/img/devlog9.png b/build-staging/es/img/devlog9.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/es/img/devlog9.png differ diff --git a/build-staging/es/img/devlog9_small.png b/build-staging/es/img/devlog9_small.png new file mode 100644 index 00000000..4a1e749f Binary files /dev/null and b/build-staging/es/img/devlog9_small.png differ diff --git a/build-staging/es/img/dl7-after.png b/build-staging/es/img/dl7-after.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/es/img/dl7-after.png differ diff --git a/build-staging/es/img/dl7-before.png b/build-staging/es/img/dl7-before.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/es/img/dl7-before.png differ diff --git a/build-staging/es/img/docusaurus.png b/build-staging/es/img/docusaurus.png new file mode 100644 index 00000000..f458149e Binary files /dev/null and b/build-staging/es/img/docusaurus.png differ diff --git a/build-staging/es/img/done-24px.svg b/build-staging/es/img/done-24px.svg new file mode 100644 index 00000000..2ee44187 --- /dev/null +++ b/build-staging/es/img/done-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/drag_indicator-24px.svg b/build-staging/es/img/drag_indicator-24px.svg new file mode 100644 index 00000000..0559cf1d --- /dev/null +++ b/build-staging/es/img/drag_indicator-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/edit-24px.svg b/build-staging/es/img/edit-24px.svg new file mode 100644 index 00000000..1a7d71c7 --- /dev/null +++ b/build-staging/es/img/edit-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/enable_experiments.svg b/build-staging/es/img/enable_experiments.svg new file mode 100644 index 00000000..c94642b6 --- /dev/null +++ b/build-staging/es/img/enable_experiments.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/enable_groups.svg b/build-staging/es/img/enable_groups.svg new file mode 100644 index 00000000..94480604 --- /dev/null +++ b/build-staging/es/img/enable_groups.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/favicon.png b/build-staging/es/img/favicon.png new file mode 100644 index 00000000..df58306b Binary files /dev/null and b/build-staging/es/img/favicon.png differ diff --git a/build-staging/es/img/favorite-24px.svg b/build-staging/es/img/favorite-24px.svg new file mode 100644 index 00000000..1c334308 --- /dev/null +++ b/build-staging/es/img/favorite-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/favorite_black_24dp_broken.svg b/build-staging/es/img/favorite_black_24dp_broken.svg new file mode 100644 index 00000000..cf82b44c --- /dev/null +++ b/build-staging/es/img/favorite_black_24dp_broken.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/build-staging/es/img/group_settings-24px.svg b/build-staging/es/img/group_settings-24px.svg new file mode 100644 index 00000000..bc8e0f60 --- /dev/null +++ b/build-staging/es/img/group_settings-24px.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/build-staging/es/img/handbook-banner.png b/build-staging/es/img/handbook-banner.png new file mode 100644 index 00000000..2ef4021b Binary files /dev/null and b/build-staging/es/img/handbook-banner.png differ diff --git a/build-staging/es/img/handbook-banner_small.jpg b/build-staging/es/img/handbook-banner_small.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/es/img/handbook-banner_small.jpg differ diff --git a/build-staging/es/img/handbook-banner_small.png b/build-staging/es/img/handbook-banner_small.png new file mode 100644 index 00000000..c232310d Binary files /dev/null and b/build-staging/es/img/handbook-banner_small.png differ diff --git a/build-staging/es/img/info-24px.svg b/build-staging/es/img/info-24px.svg new file mode 100644 index 00000000..eb2424b5 --- /dev/null +++ b/build-staging/es/img/info-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/join_group.svg b/build-staging/es/img/join_group.svg new file mode 100644 index 00000000..d42dee0a --- /dev/null +++ b/build-staging/es/img/join_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/knott.png b/build-staging/es/img/knott.png new file mode 100644 index 00000000..e50812f7 Binary files /dev/null and b/build-staging/es/img/knott.png differ diff --git a/build-staging/es/img/linux.svg b/build-staging/es/img/linux.svg new file mode 100644 index 00000000..f81c7944 --- /dev/null +++ b/build-staging/es/img/linux.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/build-staging/es/img/lock-24px.svg b/build-staging/es/img/lock-24px.svg new file mode 100644 index 00000000..472bd965 --- /dev/null +++ b/build-staging/es/img/lock-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/lock_open-24px.svg b/build-staging/es/img/lock_open-24px.svg new file mode 100644 index 00000000..b26d7274 --- /dev/null +++ b/build-staging/es/img/lock_open-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/lock_open-24px.webp b/build-staging/es/img/lock_open-24px.webp new file mode 100644 index 00000000..a913757a Binary files /dev/null and b/build-staging/es/img/lock_open-24px.webp differ diff --git a/build-staging/es/img/logo.svg b/build-staging/es/img/logo.svg new file mode 100644 index 00000000..9db6d0d0 --- /dev/null +++ b/build-staging/es/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/manage_files.svg b/build-staging/es/img/manage_files.svg new file mode 100644 index 00000000..13edcfe6 --- /dev/null +++ b/build-staging/es/img/manage_files.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/menu-24px.svg b/build-staging/es/img/menu-24px.svg new file mode 100644 index 00000000..8525078d --- /dev/null +++ b/build-staging/es/img/menu-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/mood-24px.svg b/build-staging/es/img/mood-24px.svg new file mode 100644 index 00000000..655863fa --- /dev/null +++ b/build-staging/es/img/mood-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/more_vert-24px.svg b/build-staging/es/img/more_vert-24px.svg new file mode 100644 index 00000000..49c84995 --- /dev/null +++ b/build-staging/es/img/more_vert-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/negative_heart_24px.svg b/build-staging/es/img/negative_heart_24px.svg new file mode 100644 index 00000000..05f00c83 --- /dev/null +++ b/build-staging/es/img/negative_heart_24px.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/build-staging/es/img/peer_history.svg b/build-staging/es/img/peer_history.svg new file mode 100644 index 00000000..3c618c50 --- /dev/null +++ b/build-staging/es/img/peer_history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/peer_settings-24px.svg b/build-staging/es/img/peer_settings-24px.svg new file mode 100644 index 00000000..86d1c94f --- /dev/null +++ b/build-staging/es/img/peer_settings-24px.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/build-staging/es/img/person_add_alt_1-24px.svg b/build-staging/es/img/person_add_alt_1-24px.svg new file mode 100644 index 00000000..d9f3f0f2 --- /dev/null +++ b/build-staging/es/img/person_add_alt_1-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/picnic.png b/build-staging/es/img/picnic.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/es/img/picnic.png differ diff --git a/build-staging/es/img/picnic1.12.png b/build-staging/es/img/picnic1.12.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/es/img/picnic1.12.png differ diff --git a/build-staging/es/img/profiles/attributes-contact.png b/build-staging/es/img/profiles/attributes-contact.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/es/img/profiles/attributes-contact.png differ diff --git a/build-staging/es/img/profiles/attributes-empty.png b/build-staging/es/img/profiles/attributes-empty.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/es/img/profiles/attributes-empty.png differ diff --git a/build-staging/es/img/profiles/attributes-set.png b/build-staging/es/img/profiles/attributes-set.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/es/img/profiles/attributes-set.png differ diff --git a/build-staging/es/img/profiles/status-busy.png b/build-staging/es/img/profiles/status-busy.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/es/img/profiles/status-busy.png differ diff --git a/build-staging/es/img/profiles/status-tooltip-busy-set.png b/build-staging/es/img/profiles/status-tooltip-busy-set.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/es/img/profiles/status-tooltip-busy-set.png differ diff --git a/build-staging/es/img/profiles/status-tooltip-busy.png b/build-staging/es/img/profiles/status-tooltip-busy.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/es/img/profiles/status-tooltip-busy.png differ diff --git a/build-staging/es/img/profiles/status-tooltip.png b/build-staging/es/img/profiles/status-tooltip.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/es/img/profiles/status-tooltip.png differ diff --git a/build-staging/es/img/sarah.jpg b/build-staging/es/img/sarah.jpg new file mode 100644 index 00000000..ef603626 Binary files /dev/null and b/build-staging/es/img/sarah.jpg differ diff --git a/build-staging/es/img/search-24px.svg b/build-staging/es/img/search-24px.svg new file mode 100644 index 00000000..45ea1457 --- /dev/null +++ b/build-staging/es/img/search-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/send-24px.svg b/build-staging/es/img/send-24px.svg new file mode 100644 index 00000000..ba848bae --- /dev/null +++ b/build-staging/es/img/send-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/signal_cellular_4_bar-24px.svg b/build-staging/es/img/signal_cellular_4_bar-24px.svg new file mode 100644 index 00000000..7fa91cd3 --- /dev/null +++ b/build-staging/es/img/signal_cellular_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/signal_cellular_connected_no_internet_4_bar-24px.svg b/build-staging/es/img/signal_cellular_connected_no_internet_4_bar-24px.svg new file mode 100644 index 00000000..76788f92 --- /dev/null +++ b/build-staging/es/img/signal_cellular_connected_no_internet_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/signal_cellular_off-24px.svg b/build-staging/es/img/signal_cellular_off-24px.svg new file mode 100644 index 00000000..53a569e8 --- /dev/null +++ b/build-staging/es/img/signal_cellular_off-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/stickers-new.jpg b/build-staging/es/img/stickers-new.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/es/img/stickers-new.jpg differ diff --git a/build-staging/es/img/streamer_bunnymask.svg b/build-staging/es/img/streamer_bunnymask.svg new file mode 100644 index 00000000..345e3eae --- /dev/null +++ b/build-staging/es/img/streamer_bunnymask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/streamer_ghost.svg b/build-staging/es/img/streamer_ghost.svg new file mode 100644 index 00000000..c47a41e8 --- /dev/null +++ b/build-staging/es/img/streamer_ghost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/sync-24px.svg b/build-staging/es/img/sync-24px.svg new file mode 100644 index 00000000..514301f8 --- /dev/null +++ b/build-staging/es/img/sync-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/sync_disabled-24px.svg b/build-staging/es/img/sync_disabled-24px.svg new file mode 100644 index 00000000..36a97cbf --- /dev/null +++ b/build-staging/es/img/sync_disabled-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/sync_problem-24px.svg b/build-staging/es/img/sync_problem-24px.svg new file mode 100644 index 00000000..9eb870b0 --- /dev/null +++ b/build-staging/es/img/sync_problem-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/syncing-01.svg b/build-staging/es/img/syncing-01.svg new file mode 100644 index 00000000..f9eb9791 --- /dev/null +++ b/build-staging/es/img/syncing-01.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/es/img/syncing-02.svg b/build-staging/es/img/syncing-02.svg new file mode 100644 index 00000000..4ae41d5c --- /dev/null +++ b/build-staging/es/img/syncing-02.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/es/img/syncing-03.svg b/build-staging/es/img/syncing-03.svg new file mode 100644 index 00000000..d4313757 --- /dev/null +++ b/build-staging/es/img/syncing-03.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/es/img/toggle_on-24px.svg b/build-staging/es/img/toggle_on-24px.svg new file mode 100644 index 00000000..5da416c4 --- /dev/null +++ b/build-staging/es/img/toggle_on-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/es/img/undraw_docusaurus_mountain.svg b/build-staging/es/img/undraw_docusaurus_mountain.svg new file mode 100644 index 00000000..af961c49 --- /dev/null +++ b/build-staging/es/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/es/img/undraw_docusaurus_react.svg b/build-staging/es/img/undraw_docusaurus_react.svg new file mode 100644 index 00000000..94b5cf08 --- /dev/null +++ b/build-staging/es/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/es/img/undraw_docusaurus_tree.svg b/build-staging/es/img/undraw_docusaurus_tree.svg new file mode 100644 index 00000000..d9161d33 --- /dev/null +++ b/build-staging/es/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/es/img/windows.png b/build-staging/es/img/windows.png new file mode 100644 index 00000000..e3ffef93 Binary files /dev/null and b/build-staging/es/img/windows.png differ diff --git a/build-staging/es/img/windows.svg b/build-staging/es/img/windows.svg new file mode 100644 index 00000000..ad0ad190 --- /dev/null +++ b/build-staging/es/img/windows.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + diff --git a/build-staging/es/index.html b/build-staging/es/index.html new file mode 100644 index 00000000..35c5b466 --- /dev/null +++ b/build-staging/es/index.html @@ -0,0 +1,24 @@ + + + + + +The Cwtch Handbook | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/katex/fonts/KaTeX_AMS-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_AMS-Regular.ttf new file mode 100644 index 00000000..c6f9a5e7 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_AMS-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_AMS-Regular.woff b/build-staging/es/katex/fonts/KaTeX_AMS-Regular.woff new file mode 100644 index 00000000..b804d7b3 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_AMS-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_AMS-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 00000000..0acaaff0 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_AMS-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.ttf b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.ttf new file mode 100644 index 00000000..9ff4a5e0 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.woff b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.woff new file mode 100644 index 00000000..9759710d Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.woff2 b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.woff2 new file mode 100644 index 00000000..f390922e Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Bold.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.ttf new file mode 100644 index 00000000..f522294f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.woff new file mode 100644 index 00000000..9bdd534f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 00000000..75344a1f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Caligraphic-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.ttf b/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.ttf new file mode 100644 index 00000000..4e98259c Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.woff b/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.woff new file mode 100644 index 00000000..e7730f66 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 00000000..395f28be Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Fraktur-Bold.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.ttf new file mode 100644 index 00000000..b8461b27 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.woff new file mode 100644 index 00000000..acab069f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.woff2 new file mode 100644 index 00000000..735f6948 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Fraktur-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Bold.ttf b/build-staging/es/katex/fonts/KaTeX_Main-Bold.ttf new file mode 100644 index 00000000..4060e627 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Bold.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Bold.woff b/build-staging/es/katex/fonts/KaTeX_Main-Bold.woff new file mode 100644 index 00000000..f38136ac Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Bold.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Bold.woff2 b/build-staging/es/katex/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 00000000..ab2ad21d Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Bold.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.ttf b/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.ttf new file mode 100644 index 00000000..dc007977 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.woff b/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.woff new file mode 100644 index 00000000..67807b0b Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.woff2 b/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.woff2 new file mode 100644 index 00000000..5931794d Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-BoldItalic.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Italic.ttf b/build-staging/es/katex/fonts/KaTeX_Main-Italic.ttf new file mode 100644 index 00000000..0e9b0f35 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Italic.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Italic.woff b/build-staging/es/katex/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 00000000..6f43b594 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Italic.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Italic.woff2 b/build-staging/es/katex/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 00000000..b50920e1 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Italic.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Main-Regular.ttf new file mode 100644 index 00000000..dd45e1ed Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Main-Regular.woff new file mode 100644 index 00000000..21f58129 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Main-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 00000000..eb24a7ba Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Main-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.ttf b/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.ttf new file mode 100644 index 00000000..728ce7a1 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.woff b/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 00000000..0ae390d7 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 00000000..29657023 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Math-BoldItalic.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Math-Italic.ttf b/build-staging/es/katex/fonts/KaTeX_Math-Italic.ttf new file mode 100644 index 00000000..70d559b4 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Math-Italic.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Math-Italic.woff b/build-staging/es/katex/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 00000000..eb5159d4 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Math-Italic.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Math-Italic.woff2 b/build-staging/es/katex/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 00000000..215c143f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Math-Italic.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.ttf b/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.ttf new file mode 100644 index 00000000..2f65a8a3 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.woff b/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.woff new file mode 100644 index 00000000..8d47c02d Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 00000000..cfaa3bda Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Bold.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.ttf b/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.ttf new file mode 100644 index 00000000..d5850df9 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.woff b/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 00000000..7e02df96 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.woff2 b/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 00000000..349c06dc Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Italic.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.ttf new file mode 100644 index 00000000..537279f6 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.woff b/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.woff new file mode 100644 index 00000000..31b84829 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 00000000..a90eea85 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_SansSerif-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Script-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Script-Regular.ttf new file mode 100644 index 00000000..fd679bf3 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Script-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Script-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 00000000..0e7da821 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Script-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Script-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 00000000..b3048fc1 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Script-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size1-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Size1-Regular.ttf new file mode 100644 index 00000000..871fd7d1 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size1-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size1-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Size1-Regular.woff new file mode 100644 index 00000000..7f292d91 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size1-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size1-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 00000000..c5a8462f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size1-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size2-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Size2-Regular.ttf new file mode 100644 index 00000000..7a212caf Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size2-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size2-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Size2-Regular.woff new file mode 100644 index 00000000..d241d9be Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size2-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size2-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 00000000..e1bccfe2 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size2-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size3-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Size3-Regular.ttf new file mode 100644 index 00000000..00bff349 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size3-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size3-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Size3-Regular.woff new file mode 100644 index 00000000..e6e9b658 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size3-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size3-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Size3-Regular.woff2 new file mode 100644 index 00000000..249a2866 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size3-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size4-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Size4-Regular.ttf new file mode 100644 index 00000000..74f08921 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size4-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size4-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 00000000..e1ec5457 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size4-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Size4-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 00000000..680c1308 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Size4-Regular.woff2 differ diff --git a/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.ttf b/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.ttf new file mode 100644 index 00000000..c83252c5 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.ttf differ diff --git a/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.woff b/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 00000000..2432419f Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.woff differ diff --git a/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.woff2 b/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 00000000..771f1af7 Binary files /dev/null and b/build-staging/es/katex/fonts/KaTeX_Typewriter-Regular.woff2 differ diff --git a/build-staging/es/katex/katex.min.css b/build-staging/es/katex/katex.min.css new file mode 100644 index 00000000..f7ebca1f --- /dev/null +++ b/build-staging/es/katex/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.13.24"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/build-staging/es/katex/katex.min.js b/build-staging/es/katex/katex.min.js new file mode 100644 index 00000000..2d04ed3b --- /dev/null +++ b/build-staging/es/katex/katex.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return _n}});var r=function e(t,r){this.position=void 0;var n,a="KaTeX parse error: "+t,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;n=i.start;var s=i.end;n===o.length?a+=" at end of input: ":a+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332");a+=(n>15?"\u2026"+o.slice(n-15,n):o.slice(0,n))+l+(s+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;var s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(o,(function(e){return i[e]}))},hyphenate:function(e){return e.replace(a,"-$1").toLowerCase()},getBaseElem:s,isCharacterBox:function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"}},h=function(){function e(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},this.displayMode=l.deflt(e.displayMode,!1),this.output=l.deflt(e.output,"htmlAndMathml"),this.leqno=l.deflt(e.leqno,!1),this.fleqn=l.deflt(e.fleqn,!1),this.throwOnError=l.deflt(e.throwOnError,!0),this.errorColor=l.deflt(e.errorColor,"#cc0000"),this.macros=e.macros||{},this.minRuleThickness=Math.max(0,l.deflt(e.minRuleThickness,0)),this.colorIsTextColor=l.deflt(e.colorIsTextColor,!1),this.strict=l.deflt(e.strict,"warn"),this.trust=l.deflt(e.trust,!1),this.maxSize=Math.max(0,l.deflt(e.maxSize,1/0)),this.maxExpand=Math.max(0,l.deflt(e.maxExpand,1e3)),this.globalGroup=l.deflt(e.globalGroup,!1)}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=l.protocolFromUrl(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),m=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return c[u[this.id]]},t.sub=function(){return c[p[this.id]]},t.fracNum=function(){return c[d[this.id]]},t.fracDen=function(){return c[f[this.id]]},t.cramp=function(){return c[g[this.id]]},t.text=function(){return c[v[this.id]]},t.isTight=function(){return this.size>=2},e}(),c=[new m(0,0,!1),new m(1,0,!0),new m(2,1,!1),new m(3,1,!0),new m(4,2,!1),new m(5,2,!0),new m(6,3,!1),new m(7,3,!0)],u=[4,5,4,5,6,7,6,7],p=[5,5,5,5,7,7,7,7],d=[2,3,4,5,6,7,6,7],f=[3,3,5,5,7,7,7,7],g=[1,1,3,3,5,5,7,7],v=[0,1,2,3,2,3,2,3],b={DISPLAY:c[0],TEXT:c[2],SCRIPT:c[4],SCRIPTSCRIPT:c[6]},y=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var x=[];function w(e){for(var t=0;t=x[t]&&e<=x[t+1])return!0;return!1}y.forEach((function(e){return e.blocks.forEach((function(e){return x.push.apply(x,e)}))}));var k=80,S={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},M=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=q[t]={cssEmPerMu:A.quad[t]/18};for(var n in A)A.hasOwnProperty(n)&&(r[n]=A[n][t])}return q[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();R.BASESIZE=6;var O=R,E={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},H={ex:!0,em:!0,mu:!0},L=function(e){return"string"!=typeof e&&(e=e.unit),e in E||e in H||"ex"===e},D=function(e,t){var r;if(e.unit in E)r=E[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},P=function(e){return+e.toFixed(4)+"em"},F=function(e){return e.filter((function(e){return e})).join(" ")},V=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},G=function(e){var t=document.createElement(e);for(var r in t.className=F(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},Y=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"span")},t.toMarkup=function(){return U.call(this,"span")},e}(),W=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"a")},t.toMarkup=function(){return U.call(this,"a")},e}(),X=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+"=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=_[this.text])}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=P(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=F(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=l.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');var a=l.escape(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),$=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r":""},e}(),K=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e="","\\gt",!0),ne(ae,oe,ge,"\u2208","\\in",!0),ne(ae,oe,ge,"\ue020","\\@not"),ne(ae,oe,ge,"\u2282","\\subset",!0),ne(ae,oe,ge,"\u2283","\\supset",!0),ne(ae,oe,ge,"\u2286","\\subseteq",!0),ne(ae,oe,ge,"\u2287","\\supseteq",!0),ne(ae,se,ge,"\u2288","\\nsubseteq",!0),ne(ae,se,ge,"\u2289","\\nsupseteq",!0),ne(ae,oe,ge,"\u22a8","\\models"),ne(ae,oe,ge,"\u2190","\\leftarrow",!0),ne(ae,oe,ge,"\u2264","\\le"),ne(ae,oe,ge,"\u2264","\\leq",!0),ne(ae,oe,ge,"<","\\lt",!0),ne(ae,oe,ge,"\u2192","\\rightarrow",!0),ne(ae,oe,ge,"\u2192","\\to"),ne(ae,se,ge,"\u2271","\\ngeq",!0),ne(ae,se,ge,"\u2270","\\nleq",!0),ne(ae,oe,ve,"\xa0","\\ "),ne(ae,oe,ve,"\xa0","\\space"),ne(ae,oe,ve,"\xa0","\\nobreakspace"),ne(ie,oe,ve,"\xa0","\\ "),ne(ie,oe,ve,"\xa0"," "),ne(ie,oe,ve,"\xa0","\\space"),ne(ie,oe,ve,"\xa0","\\nobreakspace"),ne(ae,oe,ve,null,"\\nobreak"),ne(ae,oe,ve,null,"\\allowbreak"),ne(ae,oe,fe,",",","),ne(ae,oe,fe,";",";"),ne(ae,se,he,"\u22bc","\\barwedge",!0),ne(ae,se,he,"\u22bb","\\veebar",!0),ne(ae,oe,he,"\u2299","\\odot",!0),ne(ae,oe,he,"\u2295","\\oplus",!0),ne(ae,oe,he,"\u2297","\\otimes",!0),ne(ae,oe,be,"\u2202","\\partial",!0),ne(ae,oe,he,"\u2298","\\oslash",!0),ne(ae,se,he,"\u229a","\\circledcirc",!0),ne(ae,se,he,"\u22a1","\\boxdot",!0),ne(ae,oe,he,"\u25b3","\\bigtriangleup"),ne(ae,oe,he,"\u25bd","\\bigtriangledown"),ne(ae,oe,he,"\u2020","\\dagger"),ne(ae,oe,he,"\u22c4","\\diamond"),ne(ae,oe,he,"\u22c6","\\star"),ne(ae,oe,he,"\u25c3","\\triangleleft"),ne(ae,oe,he,"\u25b9","\\triangleright"),ne(ae,oe,de,"{","\\{"),ne(ie,oe,be,"{","\\{"),ne(ie,oe,be,"{","\\textbraceleft"),ne(ae,oe,me,"}","\\}"),ne(ie,oe,be,"}","\\}"),ne(ie,oe,be,"}","\\textbraceright"),ne(ae,oe,de,"{","\\lbrace"),ne(ae,oe,me,"}","\\rbrace"),ne(ae,oe,de,"[","\\lbrack",!0),ne(ie,oe,be,"[","\\lbrack",!0),ne(ae,oe,me,"]","\\rbrack",!0),ne(ie,oe,be,"]","\\rbrack",!0),ne(ae,oe,de,"(","\\lparen",!0),ne(ae,oe,me,")","\\rparen",!0),ne(ie,oe,be,"<","\\textless",!0),ne(ie,oe,be,">","\\textgreater",!0),ne(ae,oe,de,"\u230a","\\lfloor",!0),ne(ae,oe,me,"\u230b","\\rfloor",!0),ne(ae,oe,de,"\u2308","\\lceil",!0),ne(ae,oe,me,"\u2309","\\rceil",!0),ne(ae,oe,be,"\\","\\backslash"),ne(ae,oe,be,"\u2223","|"),ne(ae,oe,be,"\u2223","\\vert"),ne(ie,oe,be,"|","\\textbar",!0),ne(ae,oe,be,"\u2225","\\|"),ne(ae,oe,be,"\u2225","\\Vert"),ne(ie,oe,be,"\u2225","\\textbardbl"),ne(ie,oe,be,"~","\\textasciitilde"),ne(ie,oe,be,"\\","\\textbackslash"),ne(ie,oe,be,"^","\\textasciicircum"),ne(ae,oe,ge,"\u2191","\\uparrow",!0),ne(ae,oe,ge,"\u21d1","\\Uparrow",!0),ne(ae,oe,ge,"\u2193","\\downarrow",!0),ne(ae,oe,ge,"\u21d3","\\Downarrow",!0),ne(ae,oe,ge,"\u2195","\\updownarrow",!0),ne(ae,oe,ge,"\u21d5","\\Updownarrow",!0),ne(ae,oe,pe,"\u2210","\\coprod"),ne(ae,oe,pe,"\u22c1","\\bigvee"),ne(ae,oe,pe,"\u22c0","\\bigwedge"),ne(ae,oe,pe,"\u2a04","\\biguplus"),ne(ae,oe,pe,"\u22c2","\\bigcap"),ne(ae,oe,pe,"\u22c3","\\bigcup"),ne(ae,oe,pe,"\u222b","\\int"),ne(ae,oe,pe,"\u222b","\\intop"),ne(ae,oe,pe,"\u222c","\\iint"),ne(ae,oe,pe,"\u222d","\\iiint"),ne(ae,oe,pe,"\u220f","\\prod"),ne(ae,oe,pe,"\u2211","\\sum"),ne(ae,oe,pe,"\u2a02","\\bigotimes"),ne(ae,oe,pe,"\u2a01","\\bigoplus"),ne(ae,oe,pe,"\u2a00","\\bigodot"),ne(ae,oe,pe,"\u222e","\\oint"),ne(ae,oe,pe,"\u222f","\\oiint"),ne(ae,oe,pe,"\u2230","\\oiiint"),ne(ae,oe,pe,"\u2a06","\\bigsqcup"),ne(ae,oe,pe,"\u222b","\\smallint"),ne(ie,oe,ce,"\u2026","\\textellipsis"),ne(ae,oe,ce,"\u2026","\\mathellipsis"),ne(ie,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u22ef","\\@cdots",!0),ne(ae,oe,ce,"\u22f1","\\ddots",!0),ne(ae,oe,be,"\u22ee","\\varvdots"),ne(ae,oe,le,"\u02ca","\\acute"),ne(ae,oe,le,"\u02cb","\\grave"),ne(ae,oe,le,"\xa8","\\ddot"),ne(ae,oe,le,"~","\\tilde"),ne(ae,oe,le,"\u02c9","\\bar"),ne(ae,oe,le,"\u02d8","\\breve"),ne(ae,oe,le,"\u02c7","\\check"),ne(ae,oe,le,"^","\\hat"),ne(ae,oe,le,"\u20d7","\\vec"),ne(ae,oe,le,"\u02d9","\\dot"),ne(ae,oe,le,"\u02da","\\mathring"),ne(ae,oe,ue,"\ue131","\\@imath"),ne(ae,oe,ue,"\ue237","\\@jmath"),ne(ae,oe,be,"\u0131","\u0131"),ne(ae,oe,be,"\u0237","\u0237"),ne(ie,oe,be,"\u0131","\\i",!0),ne(ie,oe,be,"\u0237","\\j",!0),ne(ie,oe,be,"\xdf","\\ss",!0),ne(ie,oe,be,"\xe6","\\ae",!0),ne(ie,oe,be,"\u0153","\\oe",!0),ne(ie,oe,be,"\xf8","\\o",!0),ne(ie,oe,be,"\xc6","\\AE",!0),ne(ie,oe,be,"\u0152","\\OE",!0),ne(ie,oe,be,"\xd8","\\O",!0),ne(ie,oe,le,"\u02ca","\\'"),ne(ie,oe,le,"\u02cb","\\`"),ne(ie,oe,le,"\u02c6","\\^"),ne(ie,oe,le,"\u02dc","\\~"),ne(ie,oe,le,"\u02c9","\\="),ne(ie,oe,le,"\u02d8","\\u"),ne(ie,oe,le,"\u02d9","\\."),ne(ie,oe,le,"\xb8","\\c"),ne(ie,oe,le,"\u02da","\\r"),ne(ie,oe,le,"\u02c7","\\v"),ne(ie,oe,le,"\xa8",'\\"'),ne(ie,oe,le,"\u02dd","\\H"),ne(ie,oe,le,"\u25ef","\\textcircled");var ye={"--":!0,"---":!0,"``":!0,"''":!0};ne(ie,oe,be,"\u2013","--",!0),ne(ie,oe,be,"\u2013","\\textendash"),ne(ie,oe,be,"\u2014","---",!0),ne(ie,oe,be,"\u2014","\\textemdash"),ne(ie,oe,be,"\u2018","`",!0),ne(ie,oe,be,"\u2018","\\textquoteleft"),ne(ie,oe,be,"\u2019","'",!0),ne(ie,oe,be,"\u2019","\\textquoteright"),ne(ie,oe,be,"\u201c","``",!0),ne(ie,oe,be,"\u201c","\\textquotedblleft"),ne(ie,oe,be,"\u201d","''",!0),ne(ie,oe,be,"\u201d","\\textquotedblright"),ne(ae,oe,be,"\xb0","\\degree",!0),ne(ie,oe,be,"\xb0","\\degree"),ne(ie,oe,be,"\xb0","\\textdegree",!0),ne(ae,oe,be,"\xa3","\\pounds"),ne(ae,oe,be,"\xa3","\\mathsterling",!0),ne(ie,oe,be,"\xa3","\\pounds"),ne(ie,oe,be,"\xa3","\\textsterling",!0),ne(ae,se,be,"\u2720","\\maltese"),ne(ie,se,be,"\u2720","\\maltese");for(var xe='0123456789/@."',we=0;wet&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Ue=function(e,t,r,n){var a=new Y(e,t,r,n);return Ge(a),a},Ye=function(e,t,r,n){return new Y(e,t,r,n)},We=function(e){var t=new M(e);return Ge(t),t},Xe=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},_e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},je={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},$e={fontMap:_e,makeSymbol:Fe,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Pe(e,"Main-Bold",t).metrics?Fe(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===re[t][e].font?Fe(e,"Main-Regular",t,r,n):Fe(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:Ue,makeSvgSpan:Ye,makeLineSpan:function(e,t,r){var n=Ue([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=P(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new W(e,t,r,n);return Ge(a),a},makeFragment:We,wrapFragment:function(e,t){return e instanceof M?Ue([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(xt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(xt(s,t)),r?((i=xt(pt(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var m=lt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=P(m.height+m.depth),m.depth&&(c.style.verticalAlign=P(-m.depth))}return m}function kt(e){return new M(e)}var St=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=F(this.classes));for(var r=0;r0&&(e+=' class ="'+l.escape(F(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),Mt=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return l.escape(this.toText())},t.toText=function(){return this.text},e}(),zt={MathNode:St,TextNode:Mt,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",P(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:kt},At=function(e,t,r){return!re[t][e]||!re[t][e].replace||55349===e.charCodeAt(0)||ye.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(e=re[t][e].replace),new zt.TextNode(e)},Tt=function(e){return 1===e.length?e[0]:new zt.MathNode("mrow",e)},Bt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l.contains(["\\imath","\\jmath"],a)?null:(re[n][a]&&re[n][a].replace&&(a=re[n][a].replace),B(a,$e.fontMap[r].fontName,n)?$e.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var n=Ct(e[0],t);return r&&n instanceof St&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},Nt=function(e,t,r){return Tt(qt(e,t,r))},Ct=function(e,t){if(!e)return new zt.MathNode("mrow");if(nt[e.type])return nt[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function It(e,t,r,n,a){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof St&&l.contains(["mrow","mtable"],o[0].type)?o[0]:new zt.MathNode("mrow",o);var s=new zt.MathNode("annotation",[new zt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new zt.MathNode("semantics",[i,s]),m=new zt.MathNode("math",[h]);m.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&m.setAttribute("display","block");var c=a?"katex":"katex-mathml";return $e.makeSpan([c],[m])}var Rt=function(e){return new O({style:e.displayMode?b.DISPLAY:b.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Ot=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=$e.makeSpan(r,[e])}return e},Et=function(e,t,r){var n,a=Rt(r);if("mathml"===r.output)return It(e,t,a,r.displayMode,!0);if("html"===r.output){var i=wt(e,a);n=$e.makeSpan(["katex"],[i])}else{var o=It(e,t,a,r.displayMode,!1),s=wt(e,a);n=$e.makeSpan(["katex"],[o,s])}return Ot(n,r)},Ht={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Lt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Dt=function(e,t,r,n,a){var i,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(i=$e.makeSpan(["stretchy",t],[],a),"fbox"===t){var s=a.color&&a.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new K({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new K({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new $(l,{width:"100%",height:P(o)});i=$e.makeSvgSpan([],[h],a)}return i.height=o,i.style.height=P(o),i},Pt=function(e){var t=new zt.MathNode("mo",[new zt.TextNode(Ht[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var r=function(){var r=4e5,n=e.label.substr(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var m=new Z(i),c=new $([m],{width:"100%",height:P(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:$e.makeSvgSpan([],[c],t),minWidth:0,height:o}}var u,p,d,f=[],g=Lt[n],v=g[0],b=g[1],y=g[2],x=y/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=P(a)),n};function Vt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Gt(e){var t=Ut(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Ut(e){return e&&("atom"===e.type||ee.hasOwnProperty(e.type))?e:null}var Yt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Vt(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof Y)return e;throw new Error("Expected span but got "+String(e)+".")}(yt(e,t)),e.base=n):r=(n=Vt(e,"accent")).base;var i=yt(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&l.isCharacterBox(r)){var s=l.getBaseElem(r);o=J(yt(s,t.havingCrampedStyle())).skew}var h,m="\\c"===n.label,c=m?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)h=Ft(n,t),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+P(2*o)+")",marginLeft:P(2*o)}:void 0}]},t);else{var u,p;"\\vec"===n.label?(u=$e.staticSvg("vec",t),p=$e.svgData.vec[1]):((u=J(u=$e.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,p=u.width,m&&(c+=u.depth)),h=$e.makeSpan(["accent-body"],[u]);var d="\\textcircled"===n.label;d&&(h.classes.push("accent-full"),c=i.height);var f=o;d||(f-=p/2),h.style.left=P(f),"\\textcircled"===n.label&&(h.style.top=".2em"),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}var g=$e.makeSpan(["mord","accent"],[h],t);return a?(a.children[0]=g,a.height=Math.max(g.height,a.height),a.classes[0]="mord",a):g},Wt=function(e,t){var r=e.isStretchy?Pt(e.label):new zt.MathNode("mo",[At(e.label,e.mode)]),n=new zt.MathNode("mover",[Ct(e.base,t),r]);return n.setAttribute("accent","true"),n},Xt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));at({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=ot(t[0]),n=!Xt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=yt(e.base,t),n=Ft(e,t),a="\\utilde"===e.label?.12:0,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Pt(e.label),n=new zt.MathNode("munder",[Ct(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var _t=function(e){var t=new zt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};at({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=$e.wrapFragment(yt(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=$e.wrapFragment(yt(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),$e.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Pt(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=_t(Ct(e.body,t));if(e.below){var i=_t(Ct(e.below,t));r=new zt.MathNode("munderover",[n,i,a])}else r=new zt.MathNode("mover",[n,a])}else if(e.below){var o=_t(Ct(e.below,t));r=new zt.MathNode("munder",[n,o])}else r=_t(),r=new zt.MathNode("mover",[n,r]);return r}});var jt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},$t=function(e){return"textord"===e.type&&"@"===e.text};function Zt(e,t,r){var n=jt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}at({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=$e.wrapFragment(yt(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=P(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new zt.MathNode("mrow",[Ct(e.label,t)]);return(r=new zt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new zt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),at({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=$e.wrapFragment(yt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new zt.MathNode("mrow",[Ct(e.fragment,t)])}}),at({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Vt(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var Kt=function(e,t){var r=pt(e.body,t.withColor(e.color),!1);return $e.makeFragment(r)},Jt=function(e,t){var r=qt(e.body,t.withColor(e.color)),n=new zt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};at({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Vt(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:st(a)}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Vt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=r[0],i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Vt(a,"size").value}},htmlBuilder:function(e,t){var r=$e.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=P(D(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new zt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",P(D(e.size,t)))),r}});var Qt={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},er=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},tr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};at({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(Qt[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=Qt[a.text]),Vt(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),at({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===Qt[r]),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return tr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return tr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var rr=function(e,t,r){var n=B(re.math[e]&&re.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},nr=function(e,t,r,n){var a=r.havingBaseStyle(t),i=$e.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},ar=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=P(a),e.height-=a,e.depth+=a},ir=function(e,t,r,n,a,i){var o=function(e,t,r,n){return $e.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=nr($e.makeSpan(["delimsizing","size"+t],[o],n),b.TEXT,n,i);return r&&ar(s,n,b.TEXT),s},or=function(e,t,r){var n;return n="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:$e.makeSpan(["delimsizinginner",n],[$e.makeSpan([],[$e.makeSymbol(e,t,r)])])}},sr=function(e,t,r){var n=z["Size4-Regular"][e.charCodeAt(0)]?z["Size4-Regular"][e.charCodeAt(0)][4]:z["Size1-Regular"][e.charCodeAt(0)][4],a=new Z("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new $([a],{width:P(n),height:P(t),style:"width:"+P(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=$e.makeSvgSpan([],[i],r);return o.height=t,o.style.height=P(t),o.style.width=P(n),{type:"elem",elem:o}},lr={type:"kern",size:-.008},hr=["|","\\lvert","\\rvert","\\vert"],mr=["\\|","\\lVert","\\rVert","\\Vert"],cr=function(e,t,r,n,a,i){var o,s,h,m;o=h=m=e,s=null;var c="Size1-Regular";"\\uparrow"===e?h=m="\u23d0":"\\Uparrow"===e?h=m="\u2016":"\\downarrow"===e?o=h="\u23d0":"\\Downarrow"===e?o=h="\u2016":"\\updownarrow"===e?(o="\\uparrow",h="\u23d0",m="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="\u2016",m="\\Downarrow"):l.contains(hr,e)?h="\u2223":l.contains(mr,e)?h="\u2225":"["===e||"\\lbrack"===e?(o="\u23a1",h="\u23a2",m="\u23a3",c="Size4-Regular"):"]"===e||"\\rbrack"===e?(o="\u23a4",h="\u23a5",m="\u23a6",c="Size4-Regular"):"\\lfloor"===e||"\u230a"===e?(h=o="\u23a2",m="\u23a3",c="Size4-Regular"):"\\lceil"===e||"\u2308"===e?(o="\u23a1",h=m="\u23a2",c="Size4-Regular"):"\\rfloor"===e||"\u230b"===e?(h=o="\u23a5",m="\u23a6",c="Size4-Regular"):"\\rceil"===e||"\u2309"===e?(o="\u23a4",h=m="\u23a5",c="Size4-Regular"):"("===e||"\\lparen"===e?(o="\u239b",h="\u239c",m="\u239d",c="Size4-Regular"):")"===e||"\\rparen"===e?(o="\u239e",h="\u239f",m="\u23a0",c="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",m="\u23a9",h="\u23aa",c="Size4-Regular");var u=rr(o,c,a),p=u.height+u.depth,d=rr(h,c,a),f=d.height+d.depth,g=rr(m,c,a),v=g.height+g.depth,y=0,x=1;if(null!==s){var w=rr(s,c,a);y=w.height+w.depth,x=2}var k=p+v+y,S=k+Math.max(0,Math.ceil((t-k)/(x*f)))*x*f,M=n.fontMetrics().axisHeight;r&&(M*=n.sizeMultiplier);var z=S/2-M,A=[];if(A.push(or(m,c,a)),A.push(lr),null===s){var T=S-p-v+.016;A.push(sr(h,T,n))}else{var B=(S-p-v-y)/2+.016;A.push(sr(h,B,n)),A.push(lr),A.push(or(s,c,a)),A.push(lr),A.push(sr(h,B,n))}A.push(lr),A.push(or(o,c,a));var q=n.havingBaseStyle(b.TEXT),N=$e.makeVList({positionType:"bottom",positionData:z,children:A},q);return nr($e.makeSpan(["delimsizing","mult"],[N],q),b.TEXT,n,i)},ur=.08,pr=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,k);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,k,r)}return n}(e,n,r),o=new Z(e,i),s=new $([o],{width:"400em",height:P(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return $e.makeSvgSpan(["hide-tail"],[s],a)},dr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],fr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],gr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],vr=[0,1.2,1.8,2.4,3],br=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],yr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"stack"}],xr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],wr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},kr=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},Sr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=l.contains(gr,e)?br:l.contains(dr,e)?xr:yr;var s=kr(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=$e.makeSymbol(e,"Main-Regular",a,n),s=nr(o,t,n,i);return r&&ar(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?ir(e,s.size,r,n,a,i):cr(e,t,r,n,a,i)},Mr={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=kr("\\surd",e*a.sizeMultiplier,xr,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=pr("sqrtMain",l=(1+s+ur)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(m=1080*vr[i.size],h=(vr[i.size]+s)/o,l=(vr[i.size]+s+ur)/o,(r=pr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+ur,h=e+s,m=Math.floor(1e3*e+s)+80,(r=pr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=P(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(dr,e)||l.contains(gr,e))return ir(e,t,!1,r,a,i);if(l.contains(fr,e))return cr(e,vr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:vr,customSizedDelim:Sr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Sr(e,h,!0,n,a,i)}},zr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Ar=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Tr(e,t){var r=Ut(e);if(r&&l.contains(Ar,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Br(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}at({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Tr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:zr[e.funcName].size,mclass:zr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?$e.makeSpan([e.mclass]):Mr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(At(e.delim,e.mode));var r=new zt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=P(Mr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),at({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Tr(t[0],e).text,color:r}}}),at({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Tr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Vt(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){Br(e);for(var r,n,a=pt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Ct(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};at({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=Vt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),at({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Cr={};function Ir(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!c)&&g.pop(),b.length0&&(x+=.25),m.push({pos:x,isDashed:e[t]})}for(w(o[0]),r=0;r0&&(M<(B+=y)&&(M=B),B=0),e.addJot&&(M+=f),z.height=S,z.depth=M,x+=S,z.pos=x,x+=M+B,h[r]=z,w(o[r+1])}var q,N,C=x/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],O=[];if(e.addEqnNum)for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=l.deflt(F.pregap,p))&&((q=$e.makeSpan(["arraycolsep"],[])).style.width=P(W),R.push(q));var X=[];for(r=0;r0){for(var Z=$e.makeLineSpan("hline",t,c),K=$e.makeLineSpan("hdashline",t,c),J=[{type:"elem",elem:h,shift:0}];m.length>0;){var Q=m.pop(),ee=Q.pos-C;Q.isDashed?J.push({type:"elem",elem:K,shift:ee}):J.push({type:"elem",elem:Z,shift:ee})}h=$e.makeVList({positionType:"individualShift",children:J},t)}if(e.addEqnNum){var te=$e.makeVList({positionType:"individualShift",children:O},t);return te=$e.makeSpan(["tag"],[te],t),$e.makeFragment([h,te])}return $e.makeSpan(["mord"],[h],t)},Dr={c:"center ",l:"left ",r:"right "},Pr=function(e,t){for(var r=[],n=new zt.MathNode("mtd",[],["mtr-glue"]),a=new zt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(c+="top ",g=1),"separator"===p[p.length-1].type&&(c+="bottom ",v-=1);for(var b=g;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o=Er(e.parser,{cols:a,addJot:!0,addEqnNum:"align"===e.envName||"alignat"===e.envName,emptySingleRow:!0,colSeparationType:i,maxNumCols:"split"===e.envName?2:void 0,leqno:e.parser.settings.leqno},"display"),s=0,l={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var h="",m=0;m0&&c&&(d=1),a[u]={type:"align",align:p,pregap:d,postgap:0}}return o.colSeparationType=c?"align":"alignat",o};Ir({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Er(e.parser,a,Hr(e.envName))},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Er(e.parser,a,Hr(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Er(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Hr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l.contains(["gather","gather*"],e.envName)&&Or(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",addEqnNum:"gather"===e.envName,emptySingleRow:!0,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Or(e);var t={addEqnNum:"equation"===e.envName,emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Or(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var f=!0,g=c+1;g=b.SCRIPT.id?r.text():b.DISPLAY:"text"===e&&r.size===b.DISPLAY.size?r=b.TEXT:"script"===e?r=b.SCRIPT:"scriptscript"===e&&(r=b.SCRIPTSCRIPT),r},Zr=function(e,t){var r,n=$r(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=yt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(u=t.fontMetrics().num2,p=c):(u=t.fontMetrics().num3,p=3*c),d=t.fontMetrics().denom2),h){var w=t.fontMetrics().axisHeight;u-o.depth-(w+.5*m)0&&(t="."===(t=e)?null:t),t};at({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=ot(t[0]),s="atom"===o.type&&"open"===o.family?Qr(o.text):null,l=ot(t[1]),h="atom"===l.type&&"close"===l.family?Qr(l.text):null,m=Vt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Vt(p.body[0],"textord");u=Jr[Number(d.text)]}}else p=Vt(p,"textord"),u=Jr[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:Zr,mathmlBuilder:Kr}),at({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Vt(t[0],"size").value,token:n}}}),at({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Vt(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Zr,mathmlBuilder:Kr});var en=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?yt(e.sup,t.havingStyle(a.sup()),t):yt(e.sub,t.havingStyle(a.sub()),t),n=Vt(e.base,"horizBrace")):n=Vt(e,"horizBrace");var i,o=yt(n.base,t.havingBaseStyle(b.DISPLAY)),s=Ft(n,t);if(n.isOver?(i=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=$e.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=$e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):$e.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return $e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};at({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:en,mathmlBuilder:function(e,t){var r=Pt(e.label);return new zt.MathNode(e.isOver?"mover":"munder",[Ct(e.base,t),r])}}),at({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Vt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:st(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=pt(e.body,t,!1);return $e.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=Nt(e.body,t);return r instanceof St||(r=new St("mrow",[r])),r.setAttribute("href",e.href),r}}),at({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Vt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=D(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=D(e.width,t));var i={height:P(r+n)};a>0&&(i.width=P(a)),n>0&&(i.verticalAlign=P(-n));var o=new X(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new zt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=D(e.height,t),a=0;if(e.totalheight.number>0&&(a=D(e.totalheight,t)-n,r.setAttribute("valign",P(-a))),r.setAttribute("height",P(n+a)),e.width.number>0){var i=D(e.width,t);r.setAttribute("width",P(i))}return r.setAttribute("src",e.src),r}}),at({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Vt(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return $e.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=D(e.dimension,t);return new zt.SpaceNode(r)}}),at({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=$e.makeSpan([],[yt(e.body,t)]),r=$e.makeSpan(["inner"],[r],t)):r=$e.makeSpan(["inner"],[yt(e.body,t)]);var n=$e.makeSpan(["fix"],[]),a=$e.makeSpan([e.alignment],[r,n],t),i=$e.makeSpan(["strut"]);return i.style.height=P(a.height+a.depth),a.depth&&(i.style.verticalAlign=P(-a.depth)),a.children.unshift(i),a=$e.makeSpan(["thinbox"],[a],t),$e.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mpadded",[Ct(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),at({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),at({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var rn=function(e,t){switch(t.style.size){case b.DISPLAY.size:return e.display;case b.TEXT.size:return e.text;case b.SCRIPT.size:return e.script;case b.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};at({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:st(t[0]),text:st(t[1]),script:st(t[2]),scriptscript:st(t[3])}},htmlBuilder:function(e,t){var r=rn(e,t),n=pt(r,t,!1);return $e.makeFragment(n)},mathmlBuilder:function(e,t){var r=rn(e,t);return Nt(r,t)}});var nn=function(e,t,r,n,a,i,o){e=$e.makeSpan([],[e]);var s,h,m,c=r&&l.isCharacterBox(r);if(t){var u=yt(t,n.havingStyle(a.sup()),n);h={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-u.depth)}}if(r){var p=yt(r,n.havingStyle(a.sub()),n);s={elem:p,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-p.height)}}if(h&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;m=$e.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!h)return e;var g=e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[m];if(s&&0!==i&&!c){var b=$e.makeSpan(["mspace"],[],n);b.style.marginRight=P(i),v.unshift(b)}return $e.makeSpan(["mop","op-limits"],v,n)},an=["\\smallint"],on=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Vt(e.base,"op"),i=!0):a=Vt(e,"op");var o,s=t.style,h=!1;if(s.size===b.DISPLAY.size&&a.symbol&&!l.contains(an,a.name)&&(h=!0),a.symbol){var m=h?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(c=a.name.substr(1),a.name="oiint"===c?"\\iint":"\\iiint"),o=$e.makeSymbol(a.name,m,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),c.length>0){var u=o.italic,p=$e.staticSvg(c+"Size"+(h?"2":"1"),t);o=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+c,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=pt(a.body,t,!0);1===d.length&&d[0]instanceof j?(o=d[0]).classes[0]="mop":o=$e.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=pt(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",P(a)):(s.setAttribute("height",P(a)),s.setAttribute("depth",P(-a))),s.setAttribute("voffset",P(a)),s}});var dn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];at({type:"sizing",names:dn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:dn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return pn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=qt(e.body,r),a=new zt.MathNode("mstyle",n);return a.setAttribute("mathsize",P(r.sizeMultiplier)),a}}),at({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Vt(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=P(m);var p=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(b.SCRIPTSCRIPT),f=yt(e.index,d,t),g=.6*(p.height-p.depth),v=$e.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),y=$e.makeSpan(["root"],[v]);return $e.makeSpan(["mord","sqrt"],[y,p],t)}return $e.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new zt.MathNode("mroot",[Ct(r,t),Ct(n,t)]):new zt.MathNode("msqrt",[Ct(r,t)])}});var fn={display:b.DISPLAY,text:b.TEXT,script:b.SCRIPT,scriptscript:b.SCRIPTSCRIPT};at({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r).withFont("");return pn(e.body,n,t)},mathmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r),a=qt(e.body,n),i=new zt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});var gn=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===b.DISPLAY.size||r.alwaysHandleSupSub)?on:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===b.DISPLAY.size||r.limits)?un:null:"accent"===r.type?l.isCharacterBox(r.base)?Yt:null:"horizBrace"===r.type&&!e.sub===r.isOver?en:null:null};it({type:"supsub",htmlBuilder:function(e,t){var r=gn(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,h=e.sub,m=yt(o,t),c=t.fontMetrics(),u=0,p=0,d=o&&l.isCharacterBox(o);if(s){var f=t.havingStyle(t.style.sup());n=yt(s,f,t),d||(u=m.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(h){var g=t.havingStyle(t.style.sub());a=yt(h,g,t),d||(p=m.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===b.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,y=t.sizeMultiplier,x=P(.5/c.ptPerEm/y),w=null;if(a){var k=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(m instanceof j||k)&&(w=P(-m.italic))}if(n&&a){u=Math.max(u,i,n.depth+.25*c.xHeight),p=Math.max(p,c.sub2);var S=4*c.defaultRuleThickness;if(u-n.depth-(a.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:a,shift:p,marginRight:x,marginLeft:w},{type:"elem",elem:n,shift:-u,marginRight:x}];v=$e.makeVList({positionType:"individualShift",children:z},t)}else if(a){p=Math.max(p,c.sub1,a.height-.8*c.xHeight);var A=[{type:"elem",elem:a,marginLeft:w,marginRight:x}];v=$e.makeVList({positionType:"shift",positionData:p,children:A},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,n.depth+.25*c.xHeight),v=$e.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:n,marginRight:x}]},t)}var T=vt(m,"right")||"mord";return $e.makeSpan([T],[m,$e.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Ct(e.base,t)];if(e.sub&&i.push(Ct(e.sub,t)),e.sup&&i.push(Ct(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===b.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===b.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===b.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===b.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===b.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===b.DISPLAY)?"mover":"msup"}return new zt.MathNode(a,i)}}),it({type:"atom",htmlBuilder:function(e,t){return $e.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[At(e.text,e.mode)]);if("bin"===e.family){var n=Bt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var vn={mi:"italic",mn:"normal",mtext:"normal"};it({type:"mathord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new zt.MathNode("mi",[At(e.text,e.mode,t)]),n=Bt(e,t)||"italic";return n!==vn[r.type]&&r.setAttribute("mathvariant",n),r}}),it({type:"textord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=At(e.text,e.mode,t),a=Bt(e,t)||"normal";return r="text"===e.mode?new zt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new zt.MathNode("mn",[n]):"\\prime"===e.text?new zt.MathNode("mo",[n]):new zt.MathNode("mi",[n]),a!==vn[r.type]&&r.setAttribute("mathvariant",a),r}});var bn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},yn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};it({type:"spacing",htmlBuilder:function(e,t){if(yn.hasOwnProperty(e.text)){var r=yn[e.text].className||"";if("text"===e.mode){var a=$e.makeOrd(e,t,"textord");return a.classes.push(r),a}return $e.makeSpan(["mspace",r],[$e.mathsym(e.text,e.mode,t)],t)}if(bn.hasOwnProperty(e.text))return $e.makeSpan(["mspace",bn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!yn.hasOwnProperty(e.text)){if(bn.hasOwnProperty(e.text))return new zt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new zt.MathNode("mtext",[new zt.TextNode("\xa0")])}});var xn=function(){var e=new zt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};it({type:"tag",mathmlBuilder:function(e,t){var r=new zt.MathNode("mtable",[new zt.MathNode("mtr",[xn(),new zt.MathNode("mtd",[Nt(e.body,t)]),xn(),new zt.MathNode("mtd",[Nt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},kn={"\\textbf":"textbf","\\textmd":"textmd"},Sn={"\\textit":"textit","\\textup":"textup"},Mn=function(e,t){var r=e.font;return r?wn[r]?t.withTextFontFamily(wn[r]):kn[r]?t.withTextFontWeight(kn[r]):t.withTextFontShape(Sn[r]):t};at({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:st(a),font:n}},htmlBuilder:function(e,t){var r=Mn(e,t),n=pt(e.body,r,!0);return $e.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Mn(e,t);return Nt(e.body,r)}}),at({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=$e.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[new zt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var n=new zt.MathNode("munder",[Ct(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),at({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return $e.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new zt.MathNode("mpadded",[Ct(e.body,t)],["vcenter"])}}),at({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=zn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}this.current[e]=t},e}(),In=mn;cn("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),cn("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),cn("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),cn("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),cn("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),cn("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),cn("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Rn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};cn("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Rn[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=Rn[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};cn("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in En?t=En[r]:("\\not"===r.substr(0,4)||r in re.math&&l.contains(["bin","rel"],re.math[r].group))&&(t="\\dotsb"),t}));var Hn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};cn("\\dotso",(function(e){return e.future().text in Hn?"\\ldots\\,":"\\ldots"})),cn("\\dotsc",(function(e){var t=e.future().text;return t in Hn&&","!==t?"\\ldots\\,":"\\ldots"})),cn("\\cdots",(function(e){return e.future().text in Hn?"\\@cdots\\,":"\\@cdots"})),cn("\\dotsb","\\cdots"),cn("\\dotsm","\\cdots"),cn("\\dotsi","\\!\\cdots"),cn("\\dotsx","\\ldots\\,"),cn("\\DOTSI","\\relax"),cn("\\DOTSB","\\relax"),cn("\\DOTSX","\\relax"),cn("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),cn("\\,","\\tmspace+{3mu}{.1667em}"),cn("\\thinspace","\\,"),cn("\\>","\\mskip{4mu}"),cn("\\:","\\tmspace+{4mu}{.2222em}"),cn("\\medspace","\\:"),cn("\\;","\\tmspace+{5mu}{.2777em}"),cn("\\thickspace","\\;"),cn("\\!","\\tmspace-{3mu}{.1667em}"),cn("\\negthinspace","\\!"),cn("\\negmedspace","\\tmspace-{4mu}{.2222em}"),cn("\\negthickspace","\\tmspace-{5mu}{.277em}"),cn("\\enspace","\\kern.5em "),cn("\\enskip","\\hskip.5em\\relax"),cn("\\quad","\\hskip1em\\relax"),cn("\\qquad","\\hskip2em\\relax"),cn("\\tag","\\@ifstar\\tag@literal\\tag@paren"),cn("\\tag@paren","\\tag@literal{({#1})}"),cn("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),cn("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),cn("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),cn("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),cn("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),cn("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),cn("\\newline","\\\\\\relax"),cn("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Ln=P(z["Main-Regular"]["T".charCodeAt(0)][1]-.7*z["Main-Regular"]["A".charCodeAt(0)][1]);cn("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),cn("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),cn("\\hspace","\\@ifstar\\@hspacer\\@hspace"),cn("\\@hspace","\\hskip #1\\relax"),cn("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),cn("\\ordinarycolon",":"),cn("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),cn("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),cn("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),cn("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),cn("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),cn("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),cn("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),cn("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),cn("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),cn("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),cn("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),cn("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),cn("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),cn("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),cn("\u2237","\\dblcolon"),cn("\u2239","\\eqcolon"),cn("\u2254","\\coloneqq"),cn("\u2255","\\eqqcolon"),cn("\u2a74","\\Coloneqq"),cn("\\ratio","\\vcentcolon"),cn("\\coloncolon","\\dblcolon"),cn("\\colonequals","\\coloneqq"),cn("\\coloncolonequals","\\Coloneqq"),cn("\\equalscolon","\\eqqcolon"),cn("\\equalscoloncolon","\\Eqqcolon"),cn("\\colonminus","\\coloneq"),cn("\\coloncolonminus","\\Coloneq"),cn("\\minuscolon","\\eqcolon"),cn("\\minuscoloncolon","\\Eqcolon"),cn("\\coloncolonapprox","\\Colonapprox"),cn("\\coloncolonsim","\\Colonsim"),cn("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),cn("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),cn("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),cn("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),cn("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),cn("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),cn("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),cn("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),cn("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),cn("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),cn("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),cn("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),cn("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),cn("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),cn("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),cn("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),cn("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),cn("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),cn("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),cn("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),cn("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),cn("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),cn("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),cn("\\imath","\\html@mathml{\\@imath}{\u0131}"),cn("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),cn("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),cn("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),cn("\u27e6","\\llbracket"),cn("\u27e7","\\rrbracket"),cn("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),cn("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),cn("\u2983","\\lBrace"),cn("\u2984","\\rBrace"),cn("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),cn("\u29b5","\\minuso"),cn("\\darr","\\downarrow"),cn("\\dArr","\\Downarrow"),cn("\\Darr","\\Downarrow"),cn("\\lang","\\langle"),cn("\\rang","\\rangle"),cn("\\uarr","\\uparrow"),cn("\\uArr","\\Uparrow"),cn("\\Uarr","\\Uparrow"),cn("\\N","\\mathbb{N}"),cn("\\R","\\mathbb{R}"),cn("\\Z","\\mathbb{Z}"),cn("\\alef","\\aleph"),cn("\\alefsym","\\aleph"),cn("\\Alpha","\\mathrm{A}"),cn("\\Beta","\\mathrm{B}"),cn("\\bull","\\bullet"),cn("\\Chi","\\mathrm{X}"),cn("\\clubs","\\clubsuit"),cn("\\cnums","\\mathbb{C}"),cn("\\Complex","\\mathbb{C}"),cn("\\Dagger","\\ddagger"),cn("\\diamonds","\\diamondsuit"),cn("\\empty","\\emptyset"),cn("\\Epsilon","\\mathrm{E}"),cn("\\Eta","\\mathrm{H}"),cn("\\exist","\\exists"),cn("\\harr","\\leftrightarrow"),cn("\\hArr","\\Leftrightarrow"),cn("\\Harr","\\Leftrightarrow"),cn("\\hearts","\\heartsuit"),cn("\\image","\\Im"),cn("\\infin","\\infty"),cn("\\Iota","\\mathrm{I}"),cn("\\isin","\\in"),cn("\\Kappa","\\mathrm{K}"),cn("\\larr","\\leftarrow"),cn("\\lArr","\\Leftarrow"),cn("\\Larr","\\Leftarrow"),cn("\\lrarr","\\leftrightarrow"),cn("\\lrArr","\\Leftrightarrow"),cn("\\Lrarr","\\Leftrightarrow"),cn("\\Mu","\\mathrm{M}"),cn("\\natnums","\\mathbb{N}"),cn("\\Nu","\\mathrm{N}"),cn("\\Omicron","\\mathrm{O}"),cn("\\plusmn","\\pm"),cn("\\rarr","\\rightarrow"),cn("\\rArr","\\Rightarrow"),cn("\\Rarr","\\Rightarrow"),cn("\\real","\\Re"),cn("\\reals","\\mathbb{R}"),cn("\\Reals","\\mathbb{R}"),cn("\\Rho","\\mathrm{P}"),cn("\\sdot","\\cdot"),cn("\\sect","\\S"),cn("\\spades","\\spadesuit"),cn("\\sub","\\subset"),cn("\\sube","\\subseteq"),cn("\\supe","\\supseteq"),cn("\\Tau","\\mathrm{T}"),cn("\\thetasym","\\vartheta"),cn("\\weierp","\\wp"),cn("\\Zeta","\\mathrm{Z}"),cn("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),cn("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),cn("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),cn("\\bra","\\mathinner{\\langle{#1}|}"),cn("\\ket","\\mathinner{|{#1}\\rangle}"),cn("\\braket","\\mathinner{\\langle{#1}\\rangle}"),cn("\\Bra","\\left\\langle#1\\right|"),cn("\\Ket","\\left|#1\\right\\rangle"),cn("\\angln","{\\angl n}"),cn("\\blue","\\textcolor{##6495ed}{#1}"),cn("\\orange","\\textcolor{##ffa500}{#1}"),cn("\\pink","\\textcolor{##ff00af}{#1}"),cn("\\red","\\textcolor{##df0030}{#1}"),cn("\\green","\\textcolor{##28ae7b}{#1}"),cn("\\gray","\\textcolor{gray}{#1}"),cn("\\purple","\\textcolor{##9d38bd}{#1}"),cn("\\blueA","\\textcolor{##ccfaff}{#1}"),cn("\\blueB","\\textcolor{##80f6ff}{#1}"),cn("\\blueC","\\textcolor{##63d9ea}{#1}"),cn("\\blueD","\\textcolor{##11accd}{#1}"),cn("\\blueE","\\textcolor{##0c7f99}{#1}"),cn("\\tealA","\\textcolor{##94fff5}{#1}"),cn("\\tealB","\\textcolor{##26edd5}{#1}"),cn("\\tealC","\\textcolor{##01d1c1}{#1}"),cn("\\tealD","\\textcolor{##01a995}{#1}"),cn("\\tealE","\\textcolor{##208170}{#1}"),cn("\\greenA","\\textcolor{##b6ffb0}{#1}"),cn("\\greenB","\\textcolor{##8af281}{#1}"),cn("\\greenC","\\textcolor{##74cf70}{#1}"),cn("\\greenD","\\textcolor{##1fab54}{#1}"),cn("\\greenE","\\textcolor{##0d923f}{#1}"),cn("\\goldA","\\textcolor{##ffd0a9}{#1}"),cn("\\goldB","\\textcolor{##ffbb71}{#1}"),cn("\\goldC","\\textcolor{##ff9c39}{#1}"),cn("\\goldD","\\textcolor{##e07d10}{#1}"),cn("\\goldE","\\textcolor{##a75a05}{#1}"),cn("\\redA","\\textcolor{##fca9a9}{#1}"),cn("\\redB","\\textcolor{##ff8482}{#1}"),cn("\\redC","\\textcolor{##f9685d}{#1}"),cn("\\redD","\\textcolor{##e84d39}{#1}"),cn("\\redE","\\textcolor{##bc2612}{#1}"),cn("\\maroonA","\\textcolor{##ffbde0}{#1}"),cn("\\maroonB","\\textcolor{##ff92c6}{#1}"),cn("\\maroonC","\\textcolor{##ed5fa6}{#1}"),cn("\\maroonD","\\textcolor{##ca337c}{#1}"),cn("\\maroonE","\\textcolor{##9e034e}{#1}"),cn("\\purpleA","\\textcolor{##ddd7ff}{#1}"),cn("\\purpleB","\\textcolor{##c6b9fc}{#1}"),cn("\\purpleC","\\textcolor{##aa87ff}{#1}"),cn("\\purpleD","\\textcolor{##7854ab}{#1}"),cn("\\purpleE","\\textcolor{##543b78}{#1}"),cn("\\mintA","\\textcolor{##f5f9e8}{#1}"),cn("\\mintB","\\textcolor{##edf2df}{#1}"),cn("\\mintC","\\textcolor{##e0e5cc}{#1}"),cn("\\grayA","\\textcolor{##f6f7f7}{#1}"),cn("\\grayB","\\textcolor{##f0f1f2}{#1}"),cn("\\grayC","\\textcolor{##e3e5e6}{#1}"),cn("\\grayD","\\textcolor{##d6d8da}{#1}"),cn("\\grayE","\\textcolor{##babec2}{#1}"),cn("\\grayF","\\textcolor{##888d93}{#1}"),cn("\\grayG","\\textcolor{##626569}{#1}"),cn("\\grayH","\\textcolor{##3b3e40}{#1}"),cn("\\grayI","\\textcolor{##21242c}{#1}"),cn("\\kaBlue","\\textcolor{##314453}{#1}"),cn("\\kaGreen","\\textcolor{##71B307}{#1}");var Dn={"\\relax":!0,"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Pn=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Cn(In,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new Nn(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Bn("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof Bn){if("\\relax"!==e.text&&!e.treatAsRelax)return this.stack.pop();this.stack.pop()}}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Bn(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof Bn&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new Nn(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||An.hasOwnProperty(e)||re.math.hasOwnProperty(e)||re.text.hasOwnProperty(e)||Dn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:An.hasOwnProperty(e)&&!An[e].primitive},e}(),Fn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Vn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Gn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Pn(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&An[a.text]&&An[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=re[this.mode][t].group,h=Tn.range(e);if(Q.hasOwnProperty(l)){var m=l;s={type:"atom",mode:this.mode,family:m,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(w(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Tn.range(e),text:t}}if(this.consume(),o)for(var c=0;c + + + + +Connectivity & Tor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/security/category/cwtch-components/index.html b/build-staging/es/security/category/cwtch-components/index.html new file mode 100644 index 00000000..fbeda2ca --- /dev/null +++ b/build-staging/es/security/category/cwtch-components/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Components | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/security/category/cwtch-ui/index.html b/build-staging/es/security/category/cwtch-ui/index.html new file mode 100644 index 00000000..df5c94e1 --- /dev/null +++ b/build-staging/es/security/category/cwtch-ui/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/es/security/category/cwtch/index.html b/build-staging/es/security/category/cwtch/index.html new file mode 100644 index 00000000..5eee6507 --- /dev/null +++ b/build-staging/es/security/category/cwtch/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/security/category/tapir/index.html b/build-staging/es/security/category/tapir/index.html new file mode 100644 index 00000000..9906c4b9 --- /dev/null +++ b/build-staging/es/security/category/tapir/index.html @@ -0,0 +1,24 @@ + + + + + +Tapir | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/es/security/components/connectivity/intro/index.html b/build-staging/es/security/components/connectivity/intro/index.html new file mode 100644 index 00000000..356ab959 --- /dev/null +++ b/build-staging/es/security/components/connectivity/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Connectivity | The Cwtch Handbook + + + + + + + + + + + + +
+

Connectivity

Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.

We provide the openprivacy/connectivity package for managing the Tor daemon and setting up and tearing down onion services through Tor.

Known Risks

Private Key Exposure to the Tor Process

Status: Partially Mitigated (Requires Physical Access or Privilege Escalation to exploit)

We must pass the private key of any onion service we wish to set up to the connectivity library, through the Listen interface (and thus to the Tor process). This is one of the most critical areas that is outside of our control. Any binding to a rouge tor process or binary will result in compromise of the Onion private key.

Mitigations

Connectivity attempt to bind to the system-provided Tor process as the default, only when it has been provided with an authentication token.

Otherwise connectivity always attempts to deploy its own Tor process using a known good binary packaged with the system (outside of the scope of the connectivity package)

In the long term we hope an integrated library will become available and allow direct management through an in-process interface to prevent the private key from leaving the process boundary (or other alternative paths that allow us to maintain full control over the private key in-memory.)

Tor Process Management

Status: Partially Mitigated (Requires Physical Access or Privilege Escalation to exploit)

Many issues can arise from the management of a separate process, including the need to restart, exit and otherwise ensure appropriate management.

The ACN interface provides Restart, Close and GetBootstrapStatus interfaces to allow applications to manage the underlying Tor process. In addition the SetStatusCallback method can be used to allow an application to be notified when the status of the Tor process changes.

However, if sufficiently-privileged users wish they can interfere with this mechanism, and as such the Tor process is a more brittle component interaction than others.

Testing Status

Current connectivity has limited unit testing capabilities and none of these are run during pull requests or merges. There is no integration testing.

It is worth noting that connectivity is used by both Tapir and Cwtch in their integration tests (and so despite the lack of package level testing, it is exposed to system-wide test conditions)

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/cwtch/groups/index.html b/build-staging/es/security/components/cwtch/groups/index.html new file mode 100644 index 00000000..e2a5a3b2 --- /dev/null +++ b/build-staging/es/security/components/cwtch/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Groups | The Cwtch Handbook + + + + + + + + + + + + +
+

Groups

For the most part the Cwtch risk model for groups is split into two distinct profiles:

  • Groups made up of mutually trusted participants where peers are assumed honest.
  • Groups consisting of strangers where peers are assumed to be potentially malicious.

Most of the mitigations described in this section relate to the latter case, but naturally also impact the former. Even if assumed honest peers later turn malicious there are mechanisms that can detect such malice and prevent it from happening in the future.

Risk Overview: Key Derivation

In the ideal case we would use a protocol like OTR, the limitations preventing us from doing so right now are:

  • Offline messages are not guaranteed to reach all peers, and as such any metadata relating to key material might get lost. We need a key derivation process which is robust to missing messages or incomplete broadcast.

Risk: Malicious Peer Leaks Group Key and/or Conversation

Status: Partially Mitigated (but impossible to mitigate fully)

Whether dealing with trusted smaller groups or partially-public larger groups there is always the possibility that a malicious actor will leak group messages.

We plan to make it easy for peers to fork groups to mitigate the same key being used to encrypt lots of sensitive information and provide some level of forward secrecy for past group conversations.

Risk: Active Attacks by Group Members

Status: Partially Mitigated

Group members, who have access to the key material of the group, can conspire with a server or other group members to break transcript consistency.

While we cannot directly prevent censorship given this kind of active collusion, we have a number of mechanisms in place that should reveal the presence of censorship to honest members of the group.

Mitigations:

  • Because each message is signed by the peers public key, it should not be possible (within the cryptographic assumptions of the underlying cryptography) for one group member to imitate another.
  • Each message contains a unique identifier derived from the contents and the previous message hash - making it impossible for collaborators to include messages from non-colluding members without revealing an implicit message chain (which if they were attempting to censor other messages would reveal such censorship)

Finally: We are actively working on adding non-repudiation to Cwtch servers such that they themselves are restricted in what they can censor efficiently.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/cwtch/key_bundles/index.html b/build-staging/es/security/components/cwtch/key_bundles/index.html new file mode 100644 index 00000000..e5bed732 --- /dev/null +++ b/build-staging/es/security/components/cwtch/key_bundles/index.html @@ -0,0 +1,24 @@ + + + + + +Key Bundles | The Cwtch Handbook + + + + + + + + + + + + +
+

Key Bundles

Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant.

At the time of writing, key bundles are expected to contain 3 keys:

  1. A Tor v3 Onion Service Public Key for the Token Board (ed25519)- used to connect to the service over Tor to post and receive messages.
  2. A Tor v3 Onion Service Public Key for the Token Service (ed25519) - used to acquire tokens to post on the service via a small proof-of-work exercise.
  3. A Privacy Pass Public Key - used in the token acquisition process (a ristretto curve point) . See: OPTR2019-01

The key bundle is signed and can be verified via the first v3 onion service key, thus binding it to that particular oninon address.

Verifying Key Bundles

Profiles who import server key bundles verify them using the following trust-on-first-use (TOFU) algorithm:

  1. Verify the attached signature using the v3 onion address of the server. (If this fails, the import process is halted)
  2. Check that every key type exists. (If this fails, the import process is halted)
  3. If the profile has imported the server key bundle previously, assert that all the keys are the same. (If this fails, the import process is halted)
  4. Save the keys to the servers contact entry.

In the future this algorithm will likely be altered to allow the addition of new public keys (e.g. to allow tokens to be acquired via a Zcash address.)

Technically, at steps (2) and (3() the server can be assumed to be malicious, having signed a valid key bundle that does not conform to the specifications. When groups are moved from "experimental" to "stable" such an action will result in a warning being communicated to the profile.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/cwtch/message_formats/index.html b/build-staging/es/security/components/cwtch/message_formats/index.html new file mode 100644 index 00000000..6474f42f --- /dev/null +++ b/build-staging/es/security/components/cwtch/message_formats/index.html @@ -0,0 +1,24 @@ + + + + + +Message Formats | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Formats

Peer to Peer Messages

PeerMessage {
ID string // A unique Message ID (primarily used for acknowledgments)
Context string // A unique context identifier i.e. im.cwtch.chat
Data []byte // The context-dependent serialized data packet.
}

Context Identifiers

  • im.cwtch.raw - Data contains a plain text chat message (see: overlays for more information)

  • im.cwtch.acknowledgement - Data is empty and ID references a previously sent message

  • im.cwtch.getVal and im.cwtch.retVal - Used for requesting / returning specific information about a peer. Data contains a serialized peerGetVal structure and peerRetVal respectively.

      peerGetVal struct {
    Scope string
    Path string
    }

    type peerRetVal struct {
    Val string // Serialized path-dependent value
    Exists bool
    }

Plaintext / Decrypted Group Messages

type DecryptedGroupMessage struct {
Text string // plaintext of the message
Onion string // The Cwtch address of the sender
Timestamp uint64 // A user specified timestamp
// NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages
// We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.
// respect particular group constitutions) can be built on top of group messages, but the underlying groups are
// now agnostic to those models.
SignedGroupID []byte
PreviousMessageSig []byte // A reference to a previous message
Padding []byte // random bytes of length = 1800 - len(Text)
}

DecryptedGroupMessage contains random padding to a fixed size that is equal to the length of all fixed length fields + 1800. This ensures that all encrypted group messages are equal length.

Encrypted Group Messages

// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server
type EncryptedGroupMessage struct {
Ciphertext []byte
Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key
}

Calculating the signature requires knowing the groupID of the message, the server the group is associated with and the decrypted group message (and thus, the Group Key). It is (ed25519) signed by the sender of the message, and can be verified using their public Cwtch address key.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/cwtch/server/index.html b/build-staging/es/security/components/cwtch/server/index.html new file mode 100644 index 00000000..23496a97 --- /dev/null +++ b/build-staging/es/security/components/cwtch/server/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Server | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Server

The goal of the Cwtch protocol is to enable group communication through Untrusted Infrastructure.

Unlike in relay-based schemes where the groups assign a leader, set of leaders, or a trusted third party server to ensure that every member of the group can send and receive messages in a timely manner (even if members are offline) - untrusted infrastructure has a goal of realizing those properties without the assumption of trust.

The original Cwtch paper defined a set of properties that Cwtch Servers were expected to provide:

  • Cwtch Server may be used by multiple groups or just one.
  • A Cwtch Server, without collaboration of a group member, should never learn the identity of participants within a group.
  • A Cwtch Server should never learn the content of any communication.
  • A Cwtch Server should never be able to distinguish messages as belonging to a particular group.

We note here that these properties are a superset of the design aims of Private Information Retrieval structures.

Malicious Servers

We expect the presence of malicious entities within the Cwtch ecosystem.

We also prioritize decentralization and permissionless entry into the ecosystem and as such we do not base any security claims on the following:

  • Any non-collusion assumptions between a set of Cwtch servers
  • Any third-party defined verification process

Peers themselves are encouraged to set up and run Cwtch servers where they can guarantee more efficient properties by relaxing trust and security assumptions - however, by default, we design the protocol to be secure without these assumptions - sacrificing efficiency where necessary.

Detectable Faults

  • If a Cwtch server fails to relay a specific message to a subset of group members then there will be a detectable gap in the message tree of certain peers that can be discovered through peer-to-peer gossip.
  • A Cwtch server cannot modify any message without the key material known to the group (any attempt to do so for a subset of group members will result in identical behavior to failing to relay a message).
  • While a server can duplicate messages, these will have no impact on the group message tree (because of encryption, nonces and message identities) - the source of the duplication is not knowable to a peer.

Efficiency

As of writing, only 1 protocol is known for achieving the desired properties, naive PIR or "the server sends everything, and the peers sift through it".

This has an obvious impact on bandwidth efficiency, especially for peers using mobile devices, as such we are actively developing new protocols in which the privacy and efficiency guarantees can be traded-off in different ways.

As of writing, the servers allow both a complete download of all stored messages, and a request to download messages from a certain specified message.

All peers when they first join a group on a new server download all messages from the server, and from then on download only new messages.

Note: This behaviour does permit a mild form of metadata analysis. The server can new messages for each suspected unique profile, and then use these unique message signatures to track unique sessions over time ( via requests for new messages).

This is mitigated by 2 confounding factors:

  1. Profiles can refresh their connections at any time - resulting in fresh server session.
  2. Profiles can "resync" from a server at any time - resulting in a new call to download all messages. The most common usecase for this behaviour is to fetch older messages from a group.

In combination, these 2 mitigations place bounds on what the server is able to infer however we still cannot provide full metadata-resistance.

For potential future solutions to this problem see Niwl

Protecting the Server from Malicious Peers

The main risk to servers come in the form of spam generated by peers. In the prototype of Cwtch a spamguard mechanism was put in place that required peers to conduct some arbitrary proof of work given a server-specified parameter.

This is not a robust solution in the presence of a determined adversary with a significant amount of resources, and thus one of the main external risks to the Cwtch system becomes censorship-via-resource exhaustion.

We have outlined a potential solution to this in token based services but note that this also requires further development.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/ecosystem-overview/index.html b/build-staging/es/security/components/ecosystem-overview/index.html new file mode 100644 index 00000000..7b5352ab --- /dev/null +++ b/build-staging/es/security/components/ecosystem-overview/index.html @@ -0,0 +1,24 @@ + + + + + +Component Ecosystem Overview | The Cwtch Handbook + + + + + + + + + + + + +
+

Component Ecosystem Overview

Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem.

openprivacy/connectivity

Summary: A library providing an ACN (Anonymous Communication Network ) networking abstraction.

The goal of connectivity is to abstract away the underlying libraries/software needed to communicate with a specific ACN. Right now we only support Tor and so the job of connectivity is to:

  • Start and Stop the Tor Process
  • Provide configuration to the Tor process
  • Allow raw connections to endpoints via the Tor process (e.g. connect to onion services)
  • Host endpoints via the Tor process (e.g. host onion services)
  • Provide status updates about the underlying Tor process

For more information see connectivity

cwtch.im/tapir

Summary: Tapir is a small library for building p2p applications over anonymous communication systems.

The goal of tapir is to abstract away applications over a particular ACN. Tapir supports:

For more information see tapir

cwtch.im/cwtch

Summary: Cwtch is the main library for implementing the Cwtch protocol / system.

The goal of Cwtch is to provide implementations for cwtch-specific applications e.g. message sending, groups, and file sharing(implemented as Tapir applications), provide interfaces for managing and storing Cwtch profiles, provide an event bus for subsystem splutting and building plugins with new functionality, in addition to managing other core functionality.

The Cwtch library is also responsible for maintaining canonical model representations for wire formats and overlays.

cwtch.im/libcwtch-go

Summary: libcwtch-go provides C (including Android) bindings for Cwtch for use in UI implementations.

The goal of libcwtch-go is to bridge the gap between the backend Cwtch library and any front end systems which may be written in a different language.

The API provided by libcwtch is much more restricted than the one provided by Cwtch directly, each libcwtch API typically packages up several calls to Cwtch.

libcwtch-go is also responsible for managing UI settings and experimental gating. It is also often used as a staging ground for experimental features and code that may eventually end up in Cwtch.

cwtch-ui

Summary: A flutter based UI for Cwtch.

Cwtch UI uses libcwtch-go to provide a complete UI for Cwtch, allowing people to create and manage profiles, add contacts and groups, message people, share files (coming soon) and more.

The UI is also responsible for managing localization and translations.

For more information see Cwtch UI

Auxiliary Components

Occasionally, Open Privacy will factor out parts of Cwtch into standalone libraries that are not Cwtch specific. These are briefly summarized here:

openprivacy/log

An Open Privacy specific logging framework that is used throughout Cwtch packages.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/intro/index.html b/build-staging/es/security/components/intro/index.html new file mode 100644 index 00000000..03767a54 --- /dev/null +++ b/build-staging/es/security/components/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Technical Basics | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Technical Basics

This page presents a brief technical overview of the Cwtch protocol.

A Cwtch Profile

Users can create one of more Cwtch Profiles. Each profile generates a random ed25519 keypair compatible with Tor.

In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys + associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages).

2-party conversions: Peer to Peer

For 2 parties to engage in a peer-to-peer conversation both must be online, but only one needs to be reachable via their onion service. For the sake of clarity we often label one party the "inbound peer" (the one who hosts the onion service) and the other party the "outbound peer" (the one that connects to the onion service).

After connection both parties engage in an authentication protocol which:

  • Asserts that each party has access to the private key associated with their public identity.
  • Generates an ephemeral session key used to encrypt all further communication during the session.

This exchange (documented in further detail in authentication protocol) is offline deniable i.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the fact - it is impossible to definitely prove that the exchange happened at all.

After, the authentication protocol the two parties may exchange messages with each other freely.

Multi-party conversations: Groups and Peer to Server Communication

Note: Metadata Resistant Group Communication is still an active research area and what is documented here will likely change in the future.

When a person wants to start a group conversation they first randomly generate a secret Group Key. All group communication will be encrypted using this key.

Along with the Group Key, the group creator also decides on a Cwtch Server to use as the host of the group. For more information on how Servers authenticate themselves see key bundles.

A Group Identifier is generated using the group key and the group server and these three elements are packaged up into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections).

To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts their message using the Group Key and generates a cryptographic signature over the Group Id, Group Server and the decrypted message (see: wire formats for more information).

To receive message from the group, a profile connected to the server hosting the group and downloads all messages (since their previous connection). Profiles then attempt to decrypt each message using the Group Key and if successful attempt to verify the signature (see Cwtch Servers Cwtch Groups for an overview of attacks and mitigations).

Servers are Peers

In many respects communication with a server is identical to communication with a regular Cwtch peer, all the same steps above are taken however the server always acts as the inbound peer, and the outbound peer always uses newly generated ephemeral keypair as their "longterm identity".

As such peer-server conversations only differ in the kinds of messages that are sent between the two parties, with the server relaying all messages that it receives and also allowing any client to query for older messages.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/tapir/authentication_protocol/index.html b/build-staging/es/security/components/tapir/authentication_protocol/index.html new file mode 100644 index 00000000..7787447e --- /dev/null +++ b/build-staging/es/security/components/tapir/authentication_protocol/index.html @@ -0,0 +1,24 @@ + + + + + +Authentication Protocol | The Cwtch Handbook + + + + + + + + + + + + +
+

Authentication Protocol

Each peer, given an open connection CC:

I=InitializeIdentity()Ie=InitializeEphemeralIdentity()I,IeCP,PeCk=KDF(Pei+Pie+Peie)c=E(k,transcript.Commit())cCcpCD(k,cp)=?transcript.LatestCommit()I = \mathrm{InitializeIdentity()} \\ I_e = \mathrm{InitializeEphemeralIdentity()} \\ I,I_e \rightarrow C \\ P,P_e \leftarrow C \\ k = \mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\ c = \mathrm{E}(k, transcript.Commit()) \\ c \rightarrow C \\ c_p \leftarrow C\\ \mathrm{D}(k, c_p) \stackrel{?}{=} transcript.LatestCommit()

The above represents a sketch protocol, in reality there are a few implementation details worth pointing out:

Once derived from the key derivation function (KDF\mathrm{KDF}) the key (kk) is set on the connection, meaning the authentication app doesn't do the encryption or decryption explicitly.

The concatenation of parts of the 3DH exchange is strictly ordered:

  • DH of the Long term identity of the outbound connection by the ephemeral key of the inbound connection.
  • DH of the Long term identity of the inbound connection by the ephemeral key of the outbound connection.
  • DH of the two ephemeral identities of the inbound and outbound connections.

This strict ordering ensures both sides of the connection derive the same session key.

Cryptographic Properties

During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come from their peer (or at least, someone with possession of their peers secret key as it related to their onion address).

Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and all encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant repudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied that a single message in the transcript must have originated from a peer, there is no way of linking any other message to the session.

Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the session key is made public it can be used to forge new messages in the transcript - and as such, any standalone transcript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/tapir/packet_format/index.html b/build-staging/es/security/components/tapir/packet_format/index.html new file mode 100644 index 00000000..bde5a461 --- /dev/null +++ b/build-staging/es/security/components/tapir/packet_format/index.html @@ -0,0 +1,24 @@ + + + + + +Packet Format | The Cwtch Handbook + + + + + + + + + + + + +
+

Packet Format

All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, len bytes of data, and the rest zero padded:

| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|

Once encrypted, the entire 8192 byte data packet is encrypted using libsodium secretbox using the standard structure ( note in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)

For information on how the secret key is derived see the authentication protocol

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/ui/android/index.html b/build-staging/es/security/components/ui/android/index.html new file mode 100644 index 00000000..469830e2 --- /dev/null +++ b/build-staging/es/security/components/ui/android/index.html @@ -0,0 +1,24 @@ + + + + + +Android Service | The Cwtch Handbook + + + + + + + + + + + + +
+

Android Service

Adapted from: Discreet Log #11: Integrating FFI processes with Android services

In addition to needing to make plain ol’ method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isn’t really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service.

The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, it’s not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service.

If you’d like to follow along, our WorkManager specifications are created in the handleCwtch() method of MainActivity.kt, and the workers themselves are defined in FlwtchWorker.kt.

Our plain ol’ method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback.

One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, it’s easy for it to yield and resume as necessary while waiting for events to be generated. Cwtch’s goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately.

FlwtchWorker’s eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isn’t running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontend’s Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary.

Messages and other permanent state are stored on disk by the service, so the frontend doesn’t need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state.

Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isn’t the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:

private fun getNativeLibDir(): String {
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
"im.cwtch.flwtch", // Must be app name
PackageManager.GET_SHARED_LIBRARY_FILES)
return ainfo.nativeLibraryDir
}

…then, whenever the app is launched, we cancel any jobs that aren’t tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/ui/image_previews/index.html b/build-staging/es/security/components/ui/image_previews/index.html new file mode 100644 index 00000000..b751fe96 --- /dev/null +++ b/build-staging/es/security/components/ui/image_previews/index.html @@ -0,0 +1,24 @@ + + + + + +Image Previews | The Cwtch Handbook + + + + + + + + + + + + +
+

Image Previews

Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename’s extension (and no, we’re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they’ll go to the app’s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.

For now, we only support single-image messages, and any image editing/cropping will have to be done in a separate application. As we mention in the filesharing FAQ, image files also frequently contain significant hidden metadata, and you should only share them with people you trust.

KnownRisks

Other Applications and/or the OS Inferring Information from Images

Images must be stored somewhere, and for now we have chosen to store them unencrypted on the file system. We have done this for 2 reasons:

  1. In order to support more powerful file sharing schemes like rehosting we require the ability to efficiently scan files and deliver chunks - doing this through an encrypted database layer would harm performance.
  2. This information always has to transit the application boundary (either via display drivers, or storing and viewing the file in an external application) - there is nothing that Cwtch can do after that point in any case.

Malicious Images Crashing or otherwise Compromising Cwtch

Flutter uses Skia to render Images. While the underlying code is memory unsafe, it is extensively fuzzed as part of regular development.

We also conduct our own fuzz testing of Cwtch components. In that analysis we found a single crash bug related to a malformed GIF file that caused the renderer to allocate a ridiculous amount of memory (and eventually be refused by the kernel). To prevent this from impacting Cwtch we have adopted the policy of always enabling a maximum cacheWidth and/or cacheHeight for Image widgets.

Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata

Recently a bug was found in Apple's png parser which would cause an image to render differently on Apple devices as it would on non-Apple devices.

We conducted a few tests on our Mac builds and could not replicate this issue for Flutter (because all Flutter builds use Skia for rendering), however we will continue to include such cases in our testing corpus.

For now image previews will remain experimental and opt-in.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/ui/input/index.html b/build-staging/es/security/components/ui/input/index.html new file mode 100644 index 00000000..e95cba64 --- /dev/null +++ b/build-staging/es/security/components/ui/input/index.html @@ -0,0 +1,24 @@ + + + + + +Input | The Cwtch Handbook + + + + + + + + + + + + +
+

Input

Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices

Status: Partially Mitigated

Any component that has the potential to intercept data between a person, and the Cwtch app is a potential security risk.

One of the most likely interceptors is a 3rd party IME (Input Method Editor) commonly used by people to generate characters not natively supported by their device.

Even benign and stock IME apps may unintentionally leak information about the contents of a persons message e.g. through cloud synchronization, cloud translation or personal dictionaries.

Ultimately, this problem cannot be solved by Cwtch alone, and is a wider risk impacting the entire mobile ecosystem.

A similar risk exists on desktop through the use of similar input applications (in addition to software keyloggers), however we consider that fully outside the scope of Cwtch risk assessment (in line with other attacks on the security of the underlying operating system itself).

This is partially mitigated in Cwtch 1.2 through the use of enableIMEPersonalizedLearning: false. See this PR for more information.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/components/ui/overlays/index.html b/build-staging/es/security/components/ui/overlays/index.html new file mode 100644 index 00000000..d779e099 --- /dev/null +++ b/build-staging/es/security/components/ui/overlays/index.html @@ -0,0 +1,24 @@ + + + + + +Message Overlays | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Overlays

Adapted from: Discreet Log #8: Notes on the Cwtch Chat API

Note: This section covers overlay protocols on-top of the Cwtch protcol. For information on the Cwtch Protocol messages themselves please see Message Formats

We envision Cwtch as a platform for providing an authenticated transport layer to higher-level applications. Developers are free to make their own choices about what application layer protocols to use, whether they want bespoke binary message formats or just want to throw an HTTP library on top and call it a day. Cwtch can generate new keypairs for you (which become onion addresses; no need for any DNS registrations!) and you can REST assured that any data your application receives from the (anonymous communication) network has been authenticated already.

For our current stack, messages are wrapped in a minimal JSON frame that adds some contextual information about the message type. And because serialised JSON objects are just dictionaries, we can easily add more metadata later on as needed.

Chat overlays, lists, and bulletins

The original Cwtch alpha demoed "overlays": different ways of interpreting the same data channel, depending on the structure of the atomic data itself. We included simple checklists and BBS/classified ads as overlays that could be viewed and shared with any Cwtch contact, be it a single peer or a group. The wire format looked like this:

{o:1,d:"hey there!"}
{o:2,d:"bread",l:"groceries"}
{o:3,d:"garage sale",p:"[parent message signature]"}

Overlay field o determined if it was a chat (1), list (2), or bulletin (3) message. The data field d is overloaded, and lists/bulletins need additional information about what group/post they belong to. (We use message signatures in place of IDs to avoid things like message ordering problems and maliciously crafted IDs. This is also how the Cwtch protocol communicates to the front end which message is being acked.)

Data structure

Implementing tree-structured data on top of a sequential message store comes with obvious performance disadvantages. For example, consider the message view, which loads most-recent-messages first and only goes back far enough to fetch enough messages to fill the current viewport, in comparison with a (somewhat pathological) forum where almost every message is a child of the very first message in the history, which could have been gigs and gigs of data-ago. If the UI only displays top-level posts until the user expands them, we have to parse the entire history before we get enough info to display anything at all.

Another problem is that multiplexing all these overlays into one data store creates "holes" in the data that confuse lazy-loaded listviews and scrollbars. The message count may indicate there is a ton more information to display if the user simply scrolls, but when it actually gets fetched and parsed we might realize that none of it is relevant to the current overlay.

None of these problems are insurmountable, but they demonstrate a flaw in our initial assumptions about the nature of collaborative message flows and how we should be handling that data.

Overlay Types

As stated above, overlays are specified in a very simple JSON format with the following structure:

type ChatMessage struct {
O int `json:"o"`
D string `json:"d"`
}

Where O stands for Overlay with the current supported overlays documented below:

1: data is a chat string
2: data is a list state/delta
3: data is a bulletin state/delta
100: contact suggestion; data is a peer onion address
101: contact suggestion; data is a group invite string

Chat Messages (Overlay 1)

The most simple over is a chat message which simply contains raw, unprocessed chat message information.

{o:1,d:"got milk?"}

Invitations (Overlays 100 and 101)

Instead of receiving the invite as an incoming contact request at the profile level, new inline invites are shared with a particular contact/group, where they can be viewed and/or accepted later, even if they were initially rejected (potentially by accident).

The wire format for these are equally simple:

{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}
{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}

This represents a departure from our original "overlays" thinking to a more action-oriented representation. The chat "overlay" can communicate that someone did something, even if it's paraphrased down to "added an item to a list," and the lists and bulletins and other beautifully chaotic data can have their state precomputed and stored separately.

Lists / Bulletin Boards

Note: Expected to be Defined in Cwtch Beta 1.5

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/deployment/index.html b/build-staging/es/security/deployment/index.html new file mode 100644 index 00000000..2b58fa27 --- /dev/null +++ b/build-staging/es/security/deployment/index.html @@ -0,0 +1,24 @@ + + + + + +Deployment | The Cwtch Handbook + + + + + + + + + + + + +
+

Deployment

Risk: Binaries are replaced on the website with malicious ones

Status: Partially-mitigated

While this process is now mostly automated, should this automation ever be compromised then there is nothing in our current process that would detect this.

We need:

  • Reproducible Builds - we currently use public docker containers for all builds which should allow anyone to compare distributed builds with ones built from source.
  • Signed Releases - Open Privacy does not yet maintain a public record of staff public keys. This is likely a necessity for signing released builds and creating an audit chain backed by the organization. This process must be manual by definition.
+ + + + \ No newline at end of file diff --git a/build-staging/es/security/development/index.html b/build-staging/es/security/development/index.html new file mode 100644 index 00000000..b2ccc1ae --- /dev/null +++ b/build-staging/es/security/development/index.html @@ -0,0 +1,24 @@ + + + + + +Development | The Cwtch Handbook + + + + + + + + + + + + +
+

Development

The main process to counter malicious actors in development of Cwtch is the openness of the process.

To enhance this openness, automated builds, testing and packaging are defined as part of the repositories - improving te robustness of the code base at every stage.

While individual tests aren't perfect, and all processes have gaps, we should be committed to make it as easy as possible to contribute to Cwtch while also building pipelines and processes that catch errors (unintential or malicious) as soon as possible.

Risk: Developer Directly Pushes Malicious Code

Status: Mitigated

trunk is currently locked and only 3 Open Privacy staff members have permission to override it, in addition the responsibility of monitoring changes.

Further every new pull request and merge triggered automated builds & tests which trigger emails and audit logs.

The code is also open source and inspectable by anyone.

Risk: Code Regressions

Status: Partially Mitigated (See individual project entries in this handbook for more information)

Our automated pipelines have the ability to catch regressions when that behaviour is detectable.

The greatest challenge is in defining how such regressions are detected for the ui - where behaviour isn't as strictly defined as it is for the individual libraries.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/intro/index.html b/build-staging/es/security/intro/index.html new file mode 100644 index 00000000..e08c4043 --- /dev/null +++ b/build-staging/es/security/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Security Handbook | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Security Handbook

Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes.

What is Cwtch?

Cwtch (/kʊtʃ/ - a Welsh word roughly translating to “a hug that creates a safe place”) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications.

  • Decentralized and Open: There is no “Cwtch service” or “Cwtch network”. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch.
  • Privacy Preserving: All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services.
  • Metadata Resistant: Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.

A (Brief) History of Metadata Resistant Chat

In recent years, public awareness of the need and benefits of end-to-end encrypted solutions has increased with applications like Signal, Whatsapp and Wire now providing users with secure communications.

However, these tools require various levels of metadata exposure to function, and much of this metadata can be used to gain details about how and why a person is using a tool to communicate. [rottermanner2015privacy].

One tool that did seek to reduce metadata is Ricochet first released in 2014. Ricochet used Tor v2 onion services to provide secure end-to-end encrypted communication, and to protect the metadata of communications.

There were no centralized servers that assist in routing Ricochet conversations. No one other than the parties involved in a conversation could know that such a conversation is taking place.

Ricochet wasn't without limitations; there was no multi-device support, nor is there a mechanism for supporting group communication or for a user to send messages while a contact is offline.

This made adoption of Ricochet a difficult proposition; with even those in environments that would be served best by metadata resistance unaware that it exists [ermoshina2017can] [renaud2014doesn].

Additionally, any solution to decentralized, metadata resistant communication faces fundamental problems when it comes to efficiency, privacy and group security (as defined by transcript consensus and consistency).

Modern alternatives to Ricochet include Briar, Zbay and Ricochet Refresh - each tool seeks to optimize for a different set of trade-offs e.g. Briar seeks to allow people to communicate even when underlying network infrastructure is down while providing resistant to metadata surveillance.


The Cwtch project began in 2017 as an extension protocol for Ricochet providing group conversations via untrusted servers, with an eye to enabling decentralized, metadata resistant applications (like shared lists and bulletin board)

An alpha version of Cwtch was was launched in February 2019, and since then the Cwtch team (run by the Open Privacy Research Society) has conducted research and development into Cwtch and the underlying protocols and libraries and problem spaces.

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/references/index.html b/build-staging/es/security/references/index.html new file mode 100644 index 00000000..0f00c55a --- /dev/null +++ b/build-staging/es/security/references/index.html @@ -0,0 +1,24 @@ + + + + + +References | The Cwtch Handbook + + + + + + + + + + + + +
+

References

  • Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."

  • Brooks, John. Ricochet: Anonymous instant messaging for real privacy. https://ricochet.im. Accessed: 2018-03-10

  • Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.

  • Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.

  • Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).

  • Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata—New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.

  • Langley, Adam. Pond. https://github.com/agl/pond. Accessed: 2018-05-21.

  • Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).

  • Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).

  • Kalysch, A., Bove, D. and Müller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).

  • Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn’t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.

  • Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).

  • Unger, Nik et al. “SoK: secure messaging”. In: Security and Privacy (SP ), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232–249 link

+ + + + \ No newline at end of file diff --git a/build-staging/es/security/risk/index.html b/build-staging/es/security/risk/index.html new file mode 100644 index 00000000..3946986d --- /dev/null +++ b/build-staging/es/security/risk/index.html @@ -0,0 +1,24 @@ + + + + + +Risk Model | The Cwtch Handbook + + + + + + + + + + + + +
+

Risk Model

Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking.

Cwtch was originally conceived as an extension of the metadata resistant protocol Ricochet to support asynchronous, multi-peer group communications through the use of discardable, untrusted, anonymous infrastructure.

Since then, Cwtch has evolved into a protocol in its own right, this section will outline the various known risks that Cwtch attempts to mitigate and will be heavily referenced throughout the rest of the document when discussing the various sub-components of the Cwtch Architecture.

Threat Model

It is important to identify and understand that metadata is ubiquitous in communication protocols, it is indeed necessary for such protocols to function efficiently and at scale. However, information that is useful to facilitating peers and servers is also highly relevant to adversaries wishing to exploit such information.

For our problem definition, we will assume that the content of a communication is encrypted in such a way that an adversary is practically unable to break (see tapir and cwtch for details on the encryption that we use, a and as such we will focus to the context to the communication metadata.

We seek to protect the following communication contexts:

  • Who is involved in a communication? It may be possible to identify people or simply device or network identifiers. E.g., “this communication involves Alice, a journalist, and Bob a government employee.”.
  • Where are the participants of the conversation? E.g., “during this communication Alice was in France and Bob was in Canada.”
  • When did a conversation take place? The timing and length of communication can reveal a large amount about the nature of a call, e.g., “Bob a government employee, talked to Alice on the phone for an hour yesterday evening. This is the first time they have communicated.” *How was the conversation mediated? Whether a conversation took place over an encrypted or unencrypted email can provide useful intelligence. E.g., “Alice sent an encrypted email to Bob yesterday, whereas they usually only send plaintext emails to each other.”
  • What is the conversation about? Even if the content of the communication is encrypted it is sometimes possible to derive a probable context of a conversation without knowing exactly what is said, e.g. “a person called a pizza store at dinner time” or “someone called a known suicide hotline number at 3am.”

Beyond individual conversations, we also seek to defend against context correlation attacks, whereby multiple conversations are analyzed to derive higher level information:

  • Relationships: Discovering social relationships between a pair of entities by analyzing the frequency and length of their communications over a period of time. E.g. Carol and Eve call each other every single day for multiple hours at a time.
  • Cliques: Discovering social relationships between a group of entities that all interact with each other. E.g. Alice, Bob and Eve all communicate with each other.
  • Loosely Connected Cliques and Bridge Individuals: Discovering groups that communicate to each other through intermediaries by analyzing communication chains (e.g. everytime Alice talks to Bob she talks to Carol almost immediately after; Bob and Carol never communicate.)
  • Pattern of Life: Discovering which communications are cyclical and predictable. E.g. Alice calls Eve every Monday evening for around an hour.

Active Attacks

Misrepresentation Attacks

Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks based around misrepresentation i.e. people pretending to be other people:

A basic flow of one of these attacks is as follows, although other flows also exist:

  • Alice has a friend named Bob and another called Eve
  • Eve finds out Alice has a friend named Bob
  • Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)
  • Eve calls this new account "Eve New Account" and adds Alice as a friend.
  • Eve then changes her name on "Eve New Account" to "Bob"
  • Alice sends messages intended for "Bob" to Eve's fake Bob account

Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them is for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply won't-happen.

As such we aim to provide some user-experience hints in the ui to guide people in making choices around whether to trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users.

A note on Physical Attacks

Cwtch does not consider attacks that require physical access (or equivalent) to the users machine as practically defendable. However, in the interests of good security engineering, throughout this document we will still refer to attacks or conditions that require such privilege and point out where any mitigations we have put in place will fail.

+ + + + \ No newline at end of file diff --git a/build-staging/es/sitemap.xml b/build-staging/es/sitemap.xml new file mode 100644 index 00000000..5ef4d2bc --- /dev/null +++ b/build-staging/es/sitemap.xml @@ -0,0 +1 @@ +https://docs.cwtch.im/es/blogweekly0.5https://docs.cwtch.im/es/blog/archiveweekly0.5https://docs.cwtch.im/es/blog/autobindingsweekly0.5https://docs.cwtch.im/es/blog/autobindings-iiweekly0.5https://docs.cwtch.im/es/blog/availability-status-profile-attributesweekly0.5https://docs.cwtch.im/es/blog/cwtch-android-reproducibilityweekly0.5https://docs.cwtch.im/es/blog/cwtch-bindings-reproducibleweekly0.5https://docs.cwtch.im/es/blog/cwtch-developer-documentationweekly0.5https://docs.cwtch.im/es/blog/cwtch-documentationweekly0.5https://docs.cwtch.im/es/blog/cwtch-nightly-1-11weekly0.5https://docs.cwtch.im/es/blog/cwtch-nightly-1-12weekly0.5https://docs.cwtch.im/es/blog/cwtch-nightly-v.11-74weekly0.5https://docs.cwtch.im/es/blog/cwtch-platform-supportweekly0.5https://docs.cwtch.im/es/blog/cwtch-stable-api-designweekly0.5https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-updateweekly0.5https://docs.cwtch.im/es/blog/cwtch-stable-roadmap-update-juneweekly0.5https://docs.cwtch.im/es/blog/cwtch-testing-iweekly0.5https://docs.cwtch.im/es/blog/cwtch-testing-iiweekly0.5https://docs.cwtch.im/es/blog/page/2weekly0.5https://docs.cwtch.im/es/blog/path-to-cwtch-stableweekly0.5https://docs.cwtch.im/es/blog/tagsweekly0.5https://docs.cwtch.im/es/blog/tags/apiweekly0.5https://docs.cwtch.im/es/blog/tags/autobindingsweekly0.5https://docs.cwtch.im/es/blog/tags/bindingsweekly0.5https://docs.cwtch.im/es/blog/tags/cwtchweekly0.5https://docs.cwtch.im/es/blog/tags/cwtch-stableweekly0.5https://docs.cwtch.im/es/blog/tags/cwtch-stable/page/2weekly0.5https://docs.cwtch.im/es/blog/tags/cwtch/page/2weekly0.5https://docs.cwtch.im/es/blog/tags/developer-documentationweekly0.5https://docs.cwtch.im/es/blog/tags/documentationweekly0.5https://docs.cwtch.im/es/blog/tags/libcwtchweekly0.5https://docs.cwtch.im/es/blog/tags/nightlyweekly0.5https://docs.cwtch.im/es/blog/tags/planningweekly0.5https://docs.cwtch.im/es/blog/tags/releaseweekly0.5https://docs.cwtch.im/es/blog/tags/repliqateweekly0.5https://docs.cwtch.im/es/blog/tags/reproducible-buildsweekly0.5https://docs.cwtch.im/es/blog/tags/security-handbookweekly0.5https://docs.cwtch.im/es/blog/tags/supportweekly0.5https://docs.cwtch.im/es/blog/tags/testingweekly0.5https://docs.cwtch.im/es/developing/building-a-cwtch-app/building-an-echobotweekly0.5https://docs.cwtch.im/es/developing/building-a-cwtch-app/core-conceptsweekly0.5https://docs.cwtch.im/es/developing/building-a-cwtch-app/introweekly0.5https://docs.cwtch.im/es/developing/category/building-a-cwtch-appweekly0.5https://docs.cwtch.im/es/developing/introweekly0.5https://docs.cwtch.im/es/developing/releaseweekly0.5https://docs.cwtch.im/es/docs/category/appearanceweekly0.5https://docs.cwtch.im/es/docs/category/behaviourweekly0.5https://docs.cwtch.im/es/docs/category/contributeweekly0.5https://docs.cwtch.im/es/docs/category/conversationsweekly0.5https://docs.cwtch.im/es/docs/category/experimentsweekly0.5https://docs.cwtch.im/es/docs/category/getting-startedweekly0.5https://docs.cwtch.im/es/docs/category/groupsweekly0.5https://docs.cwtch.im/es/docs/category/platformsweekly0.5https://docs.cwtch.im/es/docs/category/profilesweekly0.5https://docs.cwtch.im/es/docs/category/serversweekly0.5https://docs.cwtch.im/es/docs/category/settingsweekly0.5https://docs.cwtch.im/es/docs/chat/accept-deny-new-conversationweekly0.5https://docs.cwtch.im/es/docs/chat/add-contactweekly0.5https://docs.cwtch.im/es/docs/chat/block-contactweekly0.5https://docs.cwtch.im/es/docs/chat/conversation-settingsweekly0.5https://docs.cwtch.im/es/docs/chat/delete-contactweekly0.5https://docs.cwtch.im/es/docs/chat/introductionweekly0.5https://docs.cwtch.im/es/docs/chat/message-formattingweekly0.5https://docs.cwtch.im/es/docs/chat/reply-to-messageweekly0.5https://docs.cwtch.im/es/docs/chat/save-conversation-historyweekly0.5https://docs.cwtch.im/es/docs/chat/share-address-with-friendsweekly0.5https://docs.cwtch.im/es/docs/chat/share-fileweekly0.5https://docs.cwtch.im/es/docs/chat/unblock-contactweekly0.5https://docs.cwtch.im/es/docs/contribute/developingweekly0.5https://docs.cwtch.im/es/docs/contribute/documentationweekly0.5https://docs.cwtch.im/es/docs/contribute/stickersweekly0.5https://docs.cwtch.im/es/docs/contribute/testingweekly0.5https://docs.cwtch.im/es/docs/contribute/translateweekly0.5https://docs.cwtch.im/es/docs/getting-started/supported_platformsweekly0.5https://docs.cwtch.im/es/docs/groups/accept-group-inviteweekly0.5https://docs.cwtch.im/es/docs/groups/create-groupweekly0.5https://docs.cwtch.im/es/docs/groups/edit-group-nameweekly0.5https://docs.cwtch.im/es/docs/groups/introductionweekly0.5https://docs.cwtch.im/es/docs/groups/leave-groupweekly0.5https://docs.cwtch.im/es/docs/groups/manage-known-serversweekly0.5https://docs.cwtch.im/es/docs/groups/send-inviteweekly0.5https://docs.cwtch.im/es/docs/introweekly0.5https://docs.cwtch.im/es/docs/platforms/tailsweekly0.5https://docs.cwtch.im/es/docs/profiles/availability-statusweekly0.5https://docs.cwtch.im/es/docs/profiles/change-nameweekly0.5https://docs.cwtch.im/es/docs/profiles/change-passwordweekly0.5https://docs.cwtch.im/es/docs/profiles/change-profile-imageweekly0.5https://docs.cwtch.im/es/docs/profiles/create-a-profileweekly0.5https://docs.cwtch.im/es/docs/profiles/delete-profileweekly0.5https://docs.cwtch.im/es/docs/profiles/exporting-profileweekly0.5https://docs.cwtch.im/es/docs/profiles/importing-a-profileweekly0.5https://docs.cwtch.im/es/docs/profiles/introductionweekly0.5https://docs.cwtch.im/es/docs/profiles/profile-infoweekly0.5https://docs.cwtch.im/es/docs/profiles/unlock-profileweekly0.5https://docs.cwtch.im/es/docs/servers/create-serverweekly0.5https://docs.cwtch.im/es/docs/servers/delete-serverweekly0.5https://docs.cwtch.im/es/docs/servers/edit-serverweekly0.5https://docs.cwtch.im/es/docs/servers/introductionweekly0.5https://docs.cwtch.im/es/docs/servers/share-keyweekly0.5https://docs.cwtch.im/es/docs/servers/unlock-serverweekly0.5https://docs.cwtch.im/es/docs/settings/appearance/change-languageweekly0.5https://docs.cwtch.im/es/docs/settings/appearance/light-dark-modeweekly0.5https://docs.cwtch.im/es/docs/settings/appearance/streamer-modeweekly0.5https://docs.cwtch.im/es/docs/settings/appearance/ui-columnsweekly0.5https://docs.cwtch.im/es/docs/settings/behaviour/block-unknown-connectionsweekly0.5https://docs.cwtch.im/es/docs/settings/behaviour/notification-contentweekly0.5https://docs.cwtch.im/es/docs/settings/behaviour/notification-policyweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/clickable-linksweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/file-sharingweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/group-experimentweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/image-previews-and-profile-picturesweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/message-formattingweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/qrcodesweekly0.5https://docs.cwtch.im/es/docs/settings/experiments/server-hostingweekly0.5https://docs.cwtch.im/es/docs/settings/introductionweekly0.5https://docs.cwtch.im/es/docs/torweekly0.5https://docs.cwtch.im/es/security/category/connectivity--torweekly0.5https://docs.cwtch.im/es/security/category/cwtchweekly0.5https://docs.cwtch.im/es/security/category/cwtch-componentsweekly0.5https://docs.cwtch.im/es/security/category/cwtch-uiweekly0.5https://docs.cwtch.im/es/security/category/tapirweekly0.5https://docs.cwtch.im/es/security/components/connectivity/introweekly0.5https://docs.cwtch.im/es/security/components/cwtch/groupsweekly0.5https://docs.cwtch.im/es/security/components/cwtch/key_bundlesweekly0.5https://docs.cwtch.im/es/security/components/cwtch/message_formatsweekly0.5https://docs.cwtch.im/es/security/components/cwtch/serverweekly0.5https://docs.cwtch.im/es/security/components/ecosystem-overviewweekly0.5https://docs.cwtch.im/es/security/components/introweekly0.5https://docs.cwtch.im/es/security/components/tapir/authentication_protocolweekly0.5https://docs.cwtch.im/es/security/components/tapir/packet_formatweekly0.5https://docs.cwtch.im/es/security/components/ui/androidweekly0.5https://docs.cwtch.im/es/security/components/ui/image_previewsweekly0.5https://docs.cwtch.im/es/security/components/ui/inputweekly0.5https://docs.cwtch.im/es/security/components/ui/overlaysweekly0.5https://docs.cwtch.im/es/security/deploymentweekly0.5https://docs.cwtch.im/es/security/developmentweekly0.5https://docs.cwtch.im/es/security/introweekly0.5https://docs.cwtch.im/es/security/referencesweekly0.5https://docs.cwtch.im/es/security/riskweekly0.5https://docs.cwtch.im/es/weekly0.5 \ No newline at end of file diff --git a/build-staging/es/video/Group_Create.mp4 b/build-staging/es/video/Group_Create.mp4 new file mode 100644 index 00000000..ae82be93 Binary files /dev/null and b/build-staging/es/video/Group_Create.mp4 differ diff --git a/build-staging/es/video/Group_Invite.mp4 b/build-staging/es/video/Group_Invite.mp4 new file mode 100644 index 00000000..cae8629e Binary files /dev/null and b/build-staging/es/video/Group_Invite.mp4 differ diff --git a/build-staging/es/video/Group_Leave.mp4 b/build-staging/es/video/Group_Leave.mp4 new file mode 100644 index 00000000..ecc5a20b Binary files /dev/null and b/build-staging/es/video/Group_Leave.mp4 differ diff --git a/build-staging/es/video/Group_acceptinvite.mp4 b/build-staging/es/video/Group_acceptinvite.mp4 new file mode 100644 index 00000000..a5d4c740 Binary files /dev/null and b/build-staging/es/video/Group_acceptinvite.mp4 differ diff --git a/build-staging/es/video/Server_Delete.mp4 b/build-staging/es/video/Server_Delete.mp4 new file mode 100644 index 00000000..14831661 Binary files /dev/null and b/build-staging/es/video/Server_Delete.mp4 differ diff --git a/build-staging/es/video/Server_Keys.mp4 b/build-staging/es/video/Server_Keys.mp4 new file mode 100644 index 00000000..d9498451 Binary files /dev/null and b/build-staging/es/video/Server_Keys.mp4 differ diff --git a/build-staging/es/video/Server_Manage.mp4 b/build-staging/es/video/Server_Manage.mp4 new file mode 100644 index 00000000..3c812baa Binary files /dev/null and b/build-staging/es/video/Server_Manage.mp4 differ diff --git a/build-staging/es/video/Server_New.mp4 b/build-staging/es/video/Server_New.mp4 new file mode 100644 index 00000000..af57ff12 Binary files /dev/null and b/build-staging/es/video/Server_New.mp4 differ diff --git a/build-staging/es/video/group_edit.mp4 b/build-staging/es/video/group_edit.mp4 new file mode 100644 index 00000000..55f6af2b Binary files /dev/null and b/build-staging/es/video/group_edit.mp4 differ diff --git a/build-staging/es/video/server_edit.mp4 b/build-staging/es/video/server_edit.mp4 new file mode 100644 index 00000000..4ef7b18c Binary files /dev/null and b/build-staging/es/video/server_edit.mp4 differ diff --git a/build-staging/img/1.10.midnight.png b/build-staging/img/1.10.midnight.png new file mode 100644 index 00000000..e706a501 Binary files /dev/null and b/build-staging/img/1.10.midnight.png differ diff --git a/build-staging/img/1.png b/build-staging/img/1.png new file mode 100644 index 00000000..65538ea1 Binary files /dev/null and b/build-staging/img/1.png differ diff --git a/build-staging/img/2.png b/build-staging/img/2.png new file mode 100644 index 00000000..4de6eb1c Binary files /dev/null and b/build-staging/img/2.png differ diff --git a/build-staging/img/3.png b/build-staging/img/3.png new file mode 100644 index 00000000..7aac7c0a Binary files /dev/null and b/build-staging/img/3.png differ diff --git a/build-staging/img/4.png b/build-staging/img/4.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/img/4.png differ diff --git a/build-staging/img/5_year_banner.png b/build-staging/img/5_year_banner.png new file mode 100644 index 00000000..ecc179a9 Binary files /dev/null and b/build-staging/img/5_year_banner.png differ diff --git a/build-staging/img/Anti-Spam_1.svg b/build-staging/img/Anti-Spam_1.svg new file mode 100644 index 00000000..3860cbfb --- /dev/null +++ b/build-staging/img/Anti-Spam_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Anti-Spam_2.svg b/build-staging/img/Anti-Spam_2.svg new file mode 100644 index 00000000..eb7a90b7 --- /dev/null +++ b/build-staging/img/Anti-Spam_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Anti-Spam_3.svg b/build-staging/img/Anti-Spam_3.svg new file mode 100644 index 00000000..df33b751 --- /dev/null +++ b/build-staging/img/Anti-Spam_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/BASE_0.png b/build-staging/img/BASE_0.png new file mode 100644 index 00000000..384cbefa Binary files /dev/null and b/build-staging/img/BASE_0.png differ diff --git a/build-staging/img/BASE_1.png b/build-staging/img/BASE_1.png new file mode 100644 index 00000000..0adb8240 Binary files /dev/null and b/build-staging/img/BASE_1.png differ diff --git a/build-staging/img/BASE_2.png b/build-staging/img/BASE_2.png new file mode 100644 index 00000000..d1cbb8e5 Binary files /dev/null and b/build-staging/img/BASE_2.png differ diff --git a/build-staging/img/BASE_3.png b/build-staging/img/BASE_3.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/img/BASE_3.png differ diff --git a/build-staging/img/BASE_5.png b/build-staging/img/BASE_5.png new file mode 100644 index 00000000..0330d03b Binary files /dev/null and b/build-staging/img/BASE_5.png differ diff --git a/build-staging/img/BASE_6.png b/build-staging/img/BASE_6.png new file mode 100644 index 00000000..3de5d899 Binary files /dev/null and b/build-staging/img/BASE_6.png differ diff --git a/build-staging/img/BASE_7.png b/build-staging/img/BASE_7.png new file mode 100644 index 00000000..00f730ad Binary files /dev/null and b/build-staging/img/BASE_7.png differ diff --git a/build-staging/img/BASE_8.png b/build-staging/img/BASE_8.png new file mode 100644 index 00000000..3881065e Binary files /dev/null and b/build-staging/img/BASE_8.png differ diff --git a/build-staging/img/Create_group.svg b/build-staging/img/Create_group.svg new file mode 100644 index 00000000..47001a56 --- /dev/null +++ b/build-staging/img/Create_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Eye_Closed.svg b/build-staging/img/Eye_Closed.svg new file mode 100644 index 00000000..01e6e0b0 --- /dev/null +++ b/build-staging/img/Eye_Closed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Eye_Open.svg b/build-staging/img/Eye_Open.svg new file mode 100644 index 00000000..3f29f7e1 --- /dev/null +++ b/build-staging/img/Eye_Open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/HB_svg_1.svg b/build-staging/img/HB_svg_1.svg new file mode 100644 index 00000000..4dd29705 --- /dev/null +++ b/build-staging/img/HB_svg_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/HB_svg_2.svg b/build-staging/img/HB_svg_2.svg new file mode 100644 index 00000000..4a4f36d3 --- /dev/null +++ b/build-staging/img/HB_svg_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/HB_svg_3.svg b/build-staging/img/HB_svg_3.svg new file mode 100644 index 00000000..f385b41a --- /dev/null +++ b/build-staging/img/HB_svg_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/HB_svg_4.svg b/build-staging/img/HB_svg_4.svg new file mode 100644 index 00000000..cf7ee829 --- /dev/null +++ b/build-staging/img/HB_svg_4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/OP_eye.svg b/build-staging/img/OP_eye.svg new file mode 100644 index 00000000..f12b17e5 --- /dev/null +++ b/build-staging/img/OP_eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Onion_Waiting.svg b/build-staging/img/Onion_Waiting.svg new file mode 100644 index 00000000..1f4f8005 --- /dev/null +++ b/build-staging/img/Onion_Waiting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Onion_off.svg b/build-staging/img/Onion_off.svg new file mode 100644 index 00000000..8075d469 --- /dev/null +++ b/build-staging/img/Onion_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Onion_on.svg b/build-staging/img/Onion_on.svg new file mode 100644 index 00000000..51771b97 --- /dev/null +++ b/build-staging/img/Onion_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Screenshot_2022-06-17_13-42-19.png b/build-staging/img/Screenshot_2022-06-17_13-42-19.png new file mode 100644 index 00000000..f3bd84ac Binary files /dev/null and b/build-staging/img/Screenshot_2022-06-17_13-42-19.png differ diff --git a/build-staging/img/Tor_Booting_up.svg b/build-staging/img/Tor_Booting_up.svg new file mode 100644 index 00000000..2df93fe0 --- /dev/null +++ b/build-staging/img/Tor_Booting_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Tor_OFF.svg b/build-staging/img/Tor_OFF.svg new file mode 100644 index 00000000..fd2a714c --- /dev/null +++ b/build-staging/img/Tor_OFF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/Tor_icon.png b/build-staging/img/Tor_icon.png new file mode 100644 index 00000000..0c871e9f Binary files /dev/null and b/build-staging/img/Tor_icon.png differ diff --git a/build-staging/img/View_replies.svg b/build-staging/img/View_replies.svg new file mode 100644 index 00000000..03cae418 --- /dev/null +++ b/build-staging/img/View_replies.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/aar-diff.png b/build-staging/img/aar-diff.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/img/aar-diff.png differ diff --git a/build-staging/img/account_blocked.svg b/build-staging/img/account_blocked.svg new file mode 100644 index 00000000..412efcff --- /dev/null +++ b/build-staging/img/account_blocked.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/build-staging/img/account_circle-24px.svg b/build-staging/img/account_circle-24px.svg new file mode 100644 index 00000000..013a30af --- /dev/null +++ b/build-staging/img/account_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/account_circle-24px_lines.svg b/build-staging/img/account_circle-24px_lines.svg new file mode 100644 index 00000000..9fec981a --- /dev/null +++ b/build-staging/img/account_circle-24px_lines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/account_circle-24px_lines_thin - blocked.svg b/build-staging/img/account_circle-24px_lines_thin - blocked.svg new file mode 100644 index 00000000..5c3b9b7a --- /dev/null +++ b/build-staging/img/account_circle-24px_lines_thin - blocked.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/build-staging/img/account_circle-24px_lines_thin.svg b/build-staging/img/account_circle-24px_lines_thin.svg new file mode 100644 index 00000000..7ded72ff --- /dev/null +++ b/build-staging/img/account_circle-24px_lines_thin.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/build-staging/img/account_circle-24px_negative_space.svg b/build-staging/img/account_circle-24px_negative_space.svg new file mode 100644 index 00000000..c9c4f83c --- /dev/null +++ b/build-staging/img/account_circle-24px_negative_space.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/build-staging/img/account_circle-24px_user.svg b/build-staging/img/account_circle-24px_user.svg new file mode 100644 index 00000000..3eb8ffc7 --- /dev/null +++ b/build-staging/img/account_circle-24px_user.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/build-staging/img/add_circle-24px.svg b/build-staging/img/add_circle-24px.svg new file mode 100644 index 00000000..e8e583ad --- /dev/null +++ b/build-staging/img/add_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/add_group.svg b/build-staging/img/add_group.svg new file mode 100644 index 00000000..c4a8658e --- /dev/null +++ b/build-staging/img/add_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/add_peer.svg b/build-staging/img/add_peer.svg new file mode 100644 index 00000000..0b15edbd --- /dev/null +++ b/build-staging/img/add_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/android.png b/build-staging/img/android.png new file mode 100644 index 00000000..afee7fce Binary files /dev/null and b/build-staging/img/android.png differ diff --git a/build-staging/img/android.svg b/build-staging/img/android.svg new file mode 100644 index 00000000..f743813f --- /dev/null +++ b/build-staging/img/android.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/build-staging/img/apple.svg b/build-staging/img/apple.svg new file mode 100644 index 00000000..a090c68e --- /dev/null +++ b/build-staging/img/apple.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/build-staging/img/attach_file-24px.svg b/build-staging/img/attach_file-24px.svg new file mode 100644 index 00000000..471fb991 --- /dev/null +++ b/build-staging/img/attach_file-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/attached-file-2.svg b/build-staging/img/attached-file-2.svg new file mode 100644 index 00000000..0f7b9eb3 --- /dev/null +++ b/build-staging/img/attached-file-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/attached-file-3.svg b/build-staging/img/attached-file-3.svg new file mode 100644 index 00000000..37e2f74a --- /dev/null +++ b/build-staging/img/attached-file-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/attached-file.svg b/build-staging/img/attached-file.svg new file mode 100644 index 00000000..28ea8263 --- /dev/null +++ b/build-staging/img/attached-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/block-24px.svg b/build-staging/img/block-24px.svg new file mode 100644 index 00000000..8636ff6a --- /dev/null +++ b/build-staging/img/block-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/block_peer.svg b/build-staging/img/block_peer.svg new file mode 100644 index 00000000..fb4a84e7 --- /dev/null +++ b/build-staging/img/block_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/block_unknown.svg b/build-staging/img/block_unknown.svg new file mode 100644 index 00000000..f5afc576 --- /dev/null +++ b/build-staging/img/block_unknown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/card_header.png b/build-staging/img/card_header.png new file mode 100644 index 00000000..aaa0368b Binary files /dev/null and b/build-staging/img/card_header.png differ diff --git a/build-staging/img/change_language.svg b/build-staging/img/change_language.svg new file mode 100644 index 00000000..d36e819b --- /dev/null +++ b/build-staging/img/change_language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/change_theme.svg b/build-staging/img/change_theme.svg new file mode 100644 index 00000000..95bf1fd4 --- /dev/null +++ b/build-staging/img/change_theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/check-24px.svg b/build-staging/img/check-24px.svg new file mode 100644 index 00000000..c5c42b66 --- /dev/null +++ b/build-staging/img/check-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/chevron_left-24px.svg b/build-staging/img/chevron_left-24px.svg new file mode 100644 index 00000000..6f78ae79 --- /dev/null +++ b/build-staging/img/chevron_left-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/clear-24px.svg b/build-staging/img/clear-24px.svg new file mode 100644 index 00000000..08149461 --- /dev/null +++ b/build-staging/img/clear-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/clickable_links.png b/build-staging/img/clickable_links.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/img/clickable_links.png differ diff --git a/build-staging/img/clickable_links_experiment.png b/build-staging/img/clickable_links_experiment.png new file mode 100644 index 00000000..1d809218 Binary files /dev/null and b/build-staging/img/clickable_links_experiment.png differ diff --git a/build-staging/img/conversations/settings-full.png b/build-staging/img/conversations/settings-full.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/img/conversations/settings-full.png differ diff --git a/build-staging/img/conversations/settings.png b/build-staging/img/conversations/settings.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/img/conversations/settings.png differ diff --git a/build-staging/img/cwtch phones.png b/build-staging/img/cwtch phones.png new file mode 100644 index 00000000..54396db9 Binary files /dev/null and b/build-staging/img/cwtch phones.png differ diff --git a/build-staging/img/cwtch_handbook_header.jpg b/build-staging/img/cwtch_handbook_header.jpg new file mode 100644 index 00000000..7b75a456 Binary files /dev/null and b/build-staging/img/cwtch_handbook_header.jpg differ diff --git a/build-staging/img/cwtch_knott.svg b/build-staging/img/cwtch_knott.svg new file mode 100644 index 00000000..7b16f58f --- /dev/null +++ b/build-staging/img/cwtch_knott.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/delete-24px.svg b/build-staging/img/delete-24px.svg new file mode 100644 index 00000000..8f6e9a27 --- /dev/null +++ b/build-staging/img/delete-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/dev9-host-disabled.png b/build-staging/img/dev9-host-disabled.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/img/dev9-host-disabled.png differ diff --git a/build-staging/img/devlog1.jpg b/build-staging/img/devlog1.jpg new file mode 100644 index 00000000..639ccabd Binary files /dev/null and b/build-staging/img/devlog1.jpg differ diff --git a/build-staging/img/devlog1.png b/build-staging/img/devlog1.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/img/devlog1.png differ diff --git a/build-staging/img/devlog10.png b/build-staging/img/devlog10.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/img/devlog10.png differ diff --git a/build-staging/img/devlog10_small.png b/build-staging/img/devlog10_small.png new file mode 100644 index 00000000..d27ea94f Binary files /dev/null and b/build-staging/img/devlog10_small.png differ diff --git a/build-staging/img/devlog12.png b/build-staging/img/devlog12.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/img/devlog12.png differ diff --git a/build-staging/img/devlog12_small.png b/build-staging/img/devlog12_small.png new file mode 100644 index 00000000..425cd4bb Binary files /dev/null and b/build-staging/img/devlog12_small.png differ diff --git a/build-staging/img/devlog13.png b/build-staging/img/devlog13.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/img/devlog13.png differ diff --git a/build-staging/img/devlog13_small.png b/build-staging/img/devlog13_small.png new file mode 100644 index 00000000..e6de7752 Binary files /dev/null and b/build-staging/img/devlog13_small.png differ diff --git a/build-staging/img/devlog1_small.jpg b/build-staging/img/devlog1_small.jpg new file mode 100644 index 00000000..a7ffb46a Binary files /dev/null and b/build-staging/img/devlog1_small.jpg differ diff --git a/build-staging/img/devlog2.png b/build-staging/img/devlog2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/img/devlog2.png differ diff --git a/build-staging/img/devlog2_small.png b/build-staging/img/devlog2_small.png new file mode 100644 index 00000000..0eb53c1f Binary files /dev/null and b/build-staging/img/devlog2_small.png differ diff --git a/build-staging/img/devlog3.png b/build-staging/img/devlog3.png new file mode 100644 index 00000000..b1a2a9a3 Binary files /dev/null and b/build-staging/img/devlog3.png differ diff --git a/build-staging/img/devlog3_small.png b/build-staging/img/devlog3_small.png new file mode 100644 index 00000000..dc99bef2 Binary files /dev/null and b/build-staging/img/devlog3_small.png differ diff --git a/build-staging/img/devlog4.png b/build-staging/img/devlog4.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/img/devlog4.png differ diff --git a/build-staging/img/devlog4_small.png b/build-staging/img/devlog4_small.png new file mode 100644 index 00000000..77354e45 Binary files /dev/null and b/build-staging/img/devlog4_small.png differ diff --git a/build-staging/img/devlog5.png b/build-staging/img/devlog5.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/img/devlog5.png differ diff --git a/build-staging/img/devlog5_small.png b/build-staging/img/devlog5_small.png new file mode 100644 index 00000000..c2a4d835 Binary files /dev/null and b/build-staging/img/devlog5_small.png differ diff --git a/build-staging/img/devlog6.png b/build-staging/img/devlog6.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/img/devlog6.png differ diff --git a/build-staging/img/devlog6_small.png b/build-staging/img/devlog6_small.png new file mode 100644 index 00000000..384738b5 Binary files /dev/null and b/build-staging/img/devlog6_small.png differ diff --git a/build-staging/img/devlog7.png b/build-staging/img/devlog7.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/img/devlog7.png differ diff --git a/build-staging/img/devlog7_small.png b/build-staging/img/devlog7_small.png new file mode 100644 index 00000000..a919c58d Binary files /dev/null and b/build-staging/img/devlog7_small.png differ diff --git a/build-staging/img/devlog8.png b/build-staging/img/devlog8.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/img/devlog8.png differ diff --git a/build-staging/img/devlog8_small.png b/build-staging/img/devlog8_small.png new file mode 100644 index 00000000..64d19eab Binary files /dev/null and b/build-staging/img/devlog8_small.png differ diff --git a/build-staging/img/devlog9.png b/build-staging/img/devlog9.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/img/devlog9.png differ diff --git a/build-staging/img/devlog9_small.png b/build-staging/img/devlog9_small.png new file mode 100644 index 00000000..4a1e749f Binary files /dev/null and b/build-staging/img/devlog9_small.png differ diff --git a/build-staging/img/dl7-after.png b/build-staging/img/dl7-after.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/img/dl7-after.png differ diff --git a/build-staging/img/dl7-before.png b/build-staging/img/dl7-before.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/img/dl7-before.png differ diff --git a/build-staging/img/docusaurus.png b/build-staging/img/docusaurus.png new file mode 100644 index 00000000..f458149e Binary files /dev/null and b/build-staging/img/docusaurus.png differ diff --git a/build-staging/img/done-24px.svg b/build-staging/img/done-24px.svg new file mode 100644 index 00000000..2ee44187 --- /dev/null +++ b/build-staging/img/done-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/drag_indicator-24px.svg b/build-staging/img/drag_indicator-24px.svg new file mode 100644 index 00000000..0559cf1d --- /dev/null +++ b/build-staging/img/drag_indicator-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/edit-24px.svg b/build-staging/img/edit-24px.svg new file mode 100644 index 00000000..1a7d71c7 --- /dev/null +++ b/build-staging/img/edit-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/enable_experiments.svg b/build-staging/img/enable_experiments.svg new file mode 100644 index 00000000..c94642b6 --- /dev/null +++ b/build-staging/img/enable_experiments.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/enable_groups.svg b/build-staging/img/enable_groups.svg new file mode 100644 index 00000000..94480604 --- /dev/null +++ b/build-staging/img/enable_groups.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/favicon.png b/build-staging/img/favicon.png new file mode 100644 index 00000000..df58306b Binary files /dev/null and b/build-staging/img/favicon.png differ diff --git a/build-staging/img/favorite-24px.svg b/build-staging/img/favorite-24px.svg new file mode 100644 index 00000000..1c334308 --- /dev/null +++ b/build-staging/img/favorite-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/favorite_black_24dp_broken.svg b/build-staging/img/favorite_black_24dp_broken.svg new file mode 100644 index 00000000..cf82b44c --- /dev/null +++ b/build-staging/img/favorite_black_24dp_broken.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/build-staging/img/group_settings-24px.svg b/build-staging/img/group_settings-24px.svg new file mode 100644 index 00000000..bc8e0f60 --- /dev/null +++ b/build-staging/img/group_settings-24px.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/build-staging/img/handbook-banner.png b/build-staging/img/handbook-banner.png new file mode 100644 index 00000000..2ef4021b Binary files /dev/null and b/build-staging/img/handbook-banner.png differ diff --git a/build-staging/img/handbook-banner_small.jpg b/build-staging/img/handbook-banner_small.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/img/handbook-banner_small.jpg differ diff --git a/build-staging/img/handbook-banner_small.png b/build-staging/img/handbook-banner_small.png new file mode 100644 index 00000000..c232310d Binary files /dev/null and b/build-staging/img/handbook-banner_small.png differ diff --git a/build-staging/img/info-24px.svg b/build-staging/img/info-24px.svg new file mode 100644 index 00000000..eb2424b5 --- /dev/null +++ b/build-staging/img/info-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/join_group.svg b/build-staging/img/join_group.svg new file mode 100644 index 00000000..d42dee0a --- /dev/null +++ b/build-staging/img/join_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/knott.png b/build-staging/img/knott.png new file mode 100644 index 00000000..e50812f7 Binary files /dev/null and b/build-staging/img/knott.png differ diff --git a/build-staging/img/linux.svg b/build-staging/img/linux.svg new file mode 100644 index 00000000..f81c7944 --- /dev/null +++ b/build-staging/img/linux.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/build-staging/img/lock-24px.svg b/build-staging/img/lock-24px.svg new file mode 100644 index 00000000..472bd965 --- /dev/null +++ b/build-staging/img/lock-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/lock_open-24px.svg b/build-staging/img/lock_open-24px.svg new file mode 100644 index 00000000..b26d7274 --- /dev/null +++ b/build-staging/img/lock_open-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/lock_open-24px.webp b/build-staging/img/lock_open-24px.webp new file mode 100644 index 00000000..a913757a Binary files /dev/null and b/build-staging/img/lock_open-24px.webp differ diff --git a/build-staging/img/logo.svg b/build-staging/img/logo.svg new file mode 100644 index 00000000..9db6d0d0 --- /dev/null +++ b/build-staging/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/manage_files.svg b/build-staging/img/manage_files.svg new file mode 100644 index 00000000..13edcfe6 --- /dev/null +++ b/build-staging/img/manage_files.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/menu-24px.svg b/build-staging/img/menu-24px.svg new file mode 100644 index 00000000..8525078d --- /dev/null +++ b/build-staging/img/menu-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/mood-24px.svg b/build-staging/img/mood-24px.svg new file mode 100644 index 00000000..655863fa --- /dev/null +++ b/build-staging/img/mood-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/more_vert-24px.svg b/build-staging/img/more_vert-24px.svg new file mode 100644 index 00000000..49c84995 --- /dev/null +++ b/build-staging/img/more_vert-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/negative_heart_24px.svg b/build-staging/img/negative_heart_24px.svg new file mode 100644 index 00000000..05f00c83 --- /dev/null +++ b/build-staging/img/negative_heart_24px.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/build-staging/img/peer_history.svg b/build-staging/img/peer_history.svg new file mode 100644 index 00000000..3c618c50 --- /dev/null +++ b/build-staging/img/peer_history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/peer_settings-24px.svg b/build-staging/img/peer_settings-24px.svg new file mode 100644 index 00000000..86d1c94f --- /dev/null +++ b/build-staging/img/peer_settings-24px.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/build-staging/img/person_add_alt_1-24px.svg b/build-staging/img/person_add_alt_1-24px.svg new file mode 100644 index 00000000..d9f3f0f2 --- /dev/null +++ b/build-staging/img/person_add_alt_1-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/picnic.png b/build-staging/img/picnic.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/img/picnic.png differ diff --git a/build-staging/img/picnic1.12.png b/build-staging/img/picnic1.12.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/img/picnic1.12.png differ diff --git a/build-staging/img/profiles/attributes-contact.png b/build-staging/img/profiles/attributes-contact.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/img/profiles/attributes-contact.png differ diff --git a/build-staging/img/profiles/attributes-empty.png b/build-staging/img/profiles/attributes-empty.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/img/profiles/attributes-empty.png differ diff --git a/build-staging/img/profiles/attributes-set.png b/build-staging/img/profiles/attributes-set.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/img/profiles/attributes-set.png differ diff --git a/build-staging/img/profiles/status-busy.png b/build-staging/img/profiles/status-busy.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/img/profiles/status-busy.png differ diff --git a/build-staging/img/profiles/status-tooltip-busy-set.png b/build-staging/img/profiles/status-tooltip-busy-set.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/img/profiles/status-tooltip-busy-set.png differ diff --git a/build-staging/img/profiles/status-tooltip-busy.png b/build-staging/img/profiles/status-tooltip-busy.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/img/profiles/status-tooltip-busy.png differ diff --git a/build-staging/img/profiles/status-tooltip.png b/build-staging/img/profiles/status-tooltip.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/img/profiles/status-tooltip.png differ diff --git a/build-staging/img/sarah.jpg b/build-staging/img/sarah.jpg new file mode 100644 index 00000000..ef603626 Binary files /dev/null and b/build-staging/img/sarah.jpg differ diff --git a/build-staging/img/search-24px.svg b/build-staging/img/search-24px.svg new file mode 100644 index 00000000..45ea1457 --- /dev/null +++ b/build-staging/img/search-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/send-24px.svg b/build-staging/img/send-24px.svg new file mode 100644 index 00000000..ba848bae --- /dev/null +++ b/build-staging/img/send-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/signal_cellular_4_bar-24px.svg b/build-staging/img/signal_cellular_4_bar-24px.svg new file mode 100644 index 00000000..7fa91cd3 --- /dev/null +++ b/build-staging/img/signal_cellular_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/signal_cellular_connected_no_internet_4_bar-24px.svg b/build-staging/img/signal_cellular_connected_no_internet_4_bar-24px.svg new file mode 100644 index 00000000..76788f92 --- /dev/null +++ b/build-staging/img/signal_cellular_connected_no_internet_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/signal_cellular_off-24px.svg b/build-staging/img/signal_cellular_off-24px.svg new file mode 100644 index 00000000..53a569e8 --- /dev/null +++ b/build-staging/img/signal_cellular_off-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/stickers-new.jpg b/build-staging/img/stickers-new.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/img/stickers-new.jpg differ diff --git a/build-staging/img/streamer_bunnymask.svg b/build-staging/img/streamer_bunnymask.svg new file mode 100644 index 00000000..345e3eae --- /dev/null +++ b/build-staging/img/streamer_bunnymask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/streamer_ghost.svg b/build-staging/img/streamer_ghost.svg new file mode 100644 index 00000000..c47a41e8 --- /dev/null +++ b/build-staging/img/streamer_ghost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/sync-24px.svg b/build-staging/img/sync-24px.svg new file mode 100644 index 00000000..514301f8 --- /dev/null +++ b/build-staging/img/sync-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/sync_disabled-24px.svg b/build-staging/img/sync_disabled-24px.svg new file mode 100644 index 00000000..36a97cbf --- /dev/null +++ b/build-staging/img/sync_disabled-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/sync_problem-24px.svg b/build-staging/img/sync_problem-24px.svg new file mode 100644 index 00000000..9eb870b0 --- /dev/null +++ b/build-staging/img/sync_problem-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/syncing-01.svg b/build-staging/img/syncing-01.svg new file mode 100644 index 00000000..f9eb9791 --- /dev/null +++ b/build-staging/img/syncing-01.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/img/syncing-02.svg b/build-staging/img/syncing-02.svg new file mode 100644 index 00000000..4ae41d5c --- /dev/null +++ b/build-staging/img/syncing-02.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/img/syncing-03.svg b/build-staging/img/syncing-03.svg new file mode 100644 index 00000000..d4313757 --- /dev/null +++ b/build-staging/img/syncing-03.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/img/toggle_on-24px.svg b/build-staging/img/toggle_on-24px.svg new file mode 100644 index 00000000..5da416c4 --- /dev/null +++ b/build-staging/img/toggle_on-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/img/undraw_docusaurus_mountain.svg b/build-staging/img/undraw_docusaurus_mountain.svg new file mode 100644 index 00000000..af961c49 --- /dev/null +++ b/build-staging/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/img/undraw_docusaurus_react.svg b/build-staging/img/undraw_docusaurus_react.svg new file mode 100644 index 00000000..94b5cf08 --- /dev/null +++ b/build-staging/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/img/undraw_docusaurus_tree.svg b/build-staging/img/undraw_docusaurus_tree.svg new file mode 100644 index 00000000..d9161d33 --- /dev/null +++ b/build-staging/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/img/windows.png b/build-staging/img/windows.png new file mode 100644 index 00000000..e3ffef93 Binary files /dev/null and b/build-staging/img/windows.png differ diff --git a/build-staging/img/windows.svg b/build-staging/img/windows.svg new file mode 100644 index 00000000..ad0ad190 --- /dev/null +++ b/build-staging/img/windows.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + diff --git a/build-staging/index.html b/build-staging/index.html new file mode 100644 index 00000000..919a650d --- /dev/null +++ b/build-staging/index.html @@ -0,0 +1,24 @@ + + + + + +The Cwtch Handbook | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/.nojekyll b/build-staging/it/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/build-staging/it/404.html b/build-staging/it/404.html new file mode 100644 index 00000000..0d30e84e --- /dev/null +++ b/build-staging/it/404.html @@ -0,0 +1,24 @@ + + + + + +Pagina non trovata | The Cwtch Handbook + + + + + + + + + + + + +
+

Pagina non trovata

Non abbiamo trovato quello che stavi cercando.

Contatta il proprietario del sito che ha linkato l'URL originario ed informalo che il collegamento non funziona.

+ + + + \ No newline at end of file diff --git a/build-staging/it/assets/css/styles.030d732c.css b/build-staging/it/assets/css/styles.030d732c.css new file mode 100644 index 00000000..1b898465 --- /dev/null +++ b/build-staging/it/assets/css/styles.030d732c.css @@ -0,0 +1,2 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center,figcaption,figure,figure p a img{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_tbUL,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.sidebar_re4s,.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_S0QG>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q>:last-child,.footer__items{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.sidebarItemTitle_pO2u,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}:root{--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#8e64a5;--ifm-font-color-base:#281831;--ifm-navbar-background-color:#fdf3fc;--ifm-code-font-size:95%;--ifm-footer-background-color:#fdf3fc;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#dfb9de;--ifm-font-color-base:#fdf3fc;--ifm-navbar-background-color:#281831;--ifm-footer-background-color:#281831;--docusaurus-highlighted-code-line-bg:#0000004d}.ui-button{background-color:#fdf3fc;height:24px;width:24px}td>img{vertical-align:sub}figcaption{font-size:10px}h1[class*=" blogPostTitle"],h1[class^=blogPostTitle],h2[class^=blogPostTitle]{font-size:2rem}[data-theme=dark] +.icon{filter:invert(1)}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_b6E3,.sidebarLogo_isFc,.themedImage_ToTc,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedImage--dark_i4oU,[data-theme=light] .themedImage--light_HNdA{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docMainContainer_gTbr,.docPage__5DB{display:flex;width:100%}.docPage__5DB{flex:1 0}.docsWrapper_BCFX{display:flex;flex:1 0 auto}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.buttons_AeoN,.features_t9lD{align-items:center;display:flex}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.heroBanner_qdFl{background:url(/it/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg) top no-repeat;color:#fdf3fc;height:670px;overflow:hidden;padding:4rem 0;position:relative;text-align:center}.heroBanner_qdFl p{color:#fdf3fc;font-weight:700;text-shadow:-1px -1px 0 #281831,1px -1px 0 #281831,-1px 1px 0 #281831,1px 1px 0 #281831}.buttons_AeoN{justify-content:center}.button_JGCe{background-color:#8e64a5;color:#fdf3fc}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.features_t9lD{padding:2rem 0;width:100%}.featureSvg_GfXr{height:200px;width:200px}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.img_ev3q{height:auto}.admonition_LlT9{margin-bottom:1em}.admonitionHeading_tbUL{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.3rem}.admonitionHeading_tbUL code{text-transform:none}.admonitionIcon_kALy{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_kALy svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.blogPostFooterDetailsFull_mRVl{flex-direction:column}.tableOfContents_bqdL{overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.searchBox_ZlJk{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_BlDH,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_m80_:focus,.expandButton_m80_:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_m80_{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_BlDH{transform:rotate(180deg)}.docSidebarContainer_b6E3{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_b3ry{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_Xe31{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_gTbr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_Uz_u{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_czyv{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media screen and (max-width:996px){.heroBanner_qdFl{padding:2rem}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/build-staging/it/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/it/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/it/assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/it/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/it/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/it/assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/it/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/it/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/it/assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/it/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/it/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/it/assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/it/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png b/build-staging/it/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/it/assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png differ diff --git a/build-staging/it/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/it/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/it/assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/it/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/it/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/it/assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/it/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/it/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/it/assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/it/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/it/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/it/assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/it/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/it/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/it/assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/it/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/it/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/it/assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/it/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/it/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/it/assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/it/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/it/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/it/assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/it/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/it/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/it/assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/it/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png b/build-staging/it/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/it/assets/images/4-698e941dd333a7200cddec8d926e9ca9.png differ diff --git a/build-staging/it/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png b/build-staging/it/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/it/assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png differ diff --git a/build-staging/it/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png b/build-staging/it/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/it/assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png differ diff --git a/build-staging/it/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png b/build-staging/it/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/it/assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png differ diff --git a/build-staging/it/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png b/build-staging/it/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/it/assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png differ diff --git a/build-staging/it/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png b/build-staging/it/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/it/assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png differ diff --git a/build-staging/it/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png b/build-staging/it/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/it/assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png differ diff --git a/build-staging/it/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png b/build-staging/it/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/it/assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png differ diff --git a/build-staging/it/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png b/build-staging/it/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/it/assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png differ diff --git a/build-staging/it/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png b/build-staging/it/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/it/assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png differ diff --git a/build-staging/it/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png b/build-staging/it/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/it/assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png differ diff --git a/build-staging/it/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png b/build-staging/it/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/it/assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png differ diff --git a/build-staging/it/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png b/build-staging/it/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/it/assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png differ diff --git a/build-staging/it/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png b/build-staging/it/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/it/assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png differ diff --git a/build-staging/it/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png b/build-staging/it/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/it/assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png differ diff --git a/build-staging/it/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png b/build-staging/it/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/it/assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png differ diff --git a/build-staging/it/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png b/build-staging/it/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/it/assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png differ diff --git a/build-staging/it/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png b/build-staging/it/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/it/assets/images/devlog8-97ac031095f463e4b5172ac973677415.png differ diff --git a/build-staging/it/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png b/build-staging/it/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/it/assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png differ diff --git a/build-staging/it/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png b/build-staging/it/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/it/assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png differ diff --git a/build-staging/it/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg b/build-staging/it/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/it/assets/images/handbook-banner_small-590e912ab259150170999d6060160909.jpg differ diff --git a/build-staging/it/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png b/build-staging/it/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/it/assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png differ diff --git a/build-staging/it/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png b/build-staging/it/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/it/assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png differ diff --git a/build-staging/it/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png b/build-staging/it/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/it/assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png differ diff --git a/build-staging/it/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png b/build-staging/it/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/it/assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png differ diff --git a/build-staging/it/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png b/build-staging/it/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/it/assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png differ diff --git a/build-staging/it/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png b/build-staging/it/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/it/assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png differ diff --git a/build-staging/it/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png b/build-staging/it/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/it/assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png differ diff --git a/build-staging/it/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png b/build-staging/it/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/it/assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png differ diff --git a/build-staging/it/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg b/build-staging/it/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/it/assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg differ diff --git a/build-staging/it/assets/js/010d07c1.ea72f1c9.js b/build-staging/it/assets/js/010d07c1.ea72f1c9.js new file mode 100644 index 00000000..7f2e8072 --- /dev/null +++ b/build-staging/it/assets/js/010d07c1.ea72f1c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8838],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>v});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=c(r),d=o,v=u["".concat(p,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(v,a(a({ref:t},l),{},{components:r})):n.createElement(v,a({ref:t},l))}));function v(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:7},a="Gestire i server",s={unversionedId:"groups/manage-known-servers",id:"groups/manage-known-servers",title:"Gestire i server",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/manage-known-servers.md",sourceDirName:"groups",slug:"/groups/manage-known-servers",permalink:"/it/docs/groups/manage-known-servers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/manage-known-servers.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Modificare il nome di un gruppo",permalink:"/it/docs/groups/edit-group-name"},next:{title:"Servers",permalink:"/it/docs/category/servers"}},p={},c=[{value:"Importa un server ospitato localmente",id:"importa-un-server-ospitato-localmente",level:2}],l={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"gestire-i-server"},"Gestire i server"),(0,o.kt)("p",null,":::attenzione Esperimenti necessari"),(0,o.kt)("p",null,"Questa funzione richiede ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,o.kt)("p",null,":::"),(0,o.kt)("p",null,"I gruppi Cwtch sono ospitati da server non affidabili. Se vuoi vedere i server di cui sei a conoscenza, il loro stato e i gruppi da essi ospitati:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Nel pannello dei tuoi contatti"),(0,o.kt)("li",{parentName:"ol"},"Vai all'icona di gestione dei server")),(0,o.kt)("h2",{id:"importa-un-server-ospitato-localmente"},"Importa un server ospitato localmente"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},'Per importare un server ospitato localmente, clicca su "seleziona server locale"'),(0,o.kt)("li",{parentName:"ol"},"Seleziona il server che desideri")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Server_Manage.mp4"}))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/01a85c17.fbcc85f1.js b/build-staging/it/assets/js/01a85c17.fbcc85f1.js new file mode 100644 index 00000000..ea8df306 --- /dev/null +++ b/build-staging/it/assets/js/01a85c17.fbcc85f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4013],{9058:(e,t,a)=>{a.d(t,{Z:()=>E});var l=a(7294),r=a(6010),n=a(7961),s=a(7524),i=a(9960),c=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function o(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,c.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function g(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(i.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function b(e){return l.createElement(u.Zo,{component:g,props:e})}function d(e){let{sidebar:t}=e;const a=(0,s.i)();return t?.items.length?"mobile"===a?l.createElement(b,{sidebar:t}):l.createElement(o,{sidebar:t}):null}function E(e){const{sidebar:t,toc:a,children:s,...i}=e,c=t&&t.items.length>0;return l.createElement(n.Z,i,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(d,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":c,"col--9 col--offset-1":!c}),itemScope:!0,itemType:"http://schema.org/Blog"},s),a&&l.createElement("div",{className:"col col--2"},a))))}},1223:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var l=a(7294),r=a(6010),n=a(5999);const s=()=>(0,n.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var i=a(1944),c=a(5281),m=a(9058),o=a(3008);const u={tag:"tag_Nnez"};function g(e){let{letterEntry:t}=e;return l.createElement("article",null,l.createElement("h2",null,t.letter),l.createElement("ul",{className:"padding--none"},t.tags.map((e=>l.createElement("li",{key:e.permalink,className:u.tag},l.createElement(o.Z,e))))),l.createElement("hr",null))}function b(e){let{tags:t}=e;const a=function(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[l]=t;return a.localeCompare(l)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}(t);return l.createElement("section",{className:"margin-vert--lg"},a.map((e=>l.createElement(g,{key:e.letter,letterEntry:e}))))}var d=a(197);function E(e){let{tags:t,sidebar:a}=e;const n=s();return l.createElement(i.FG,{className:(0,r.Z)(c.k.wrapper.blogPages,c.k.page.blogTagsListPage)},l.createElement(i.d,{title:n}),l.createElement(d.Z,{tag:"blog_tags_list"}),l.createElement(m.Z,{sidebar:a},l.createElement("h1",null,n),l.createElement(b,{tags:t})))}},3008:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(7294),r=a(6010),n=a(9960);const s={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function i(e){let{permalink:t,label:a,count:i}=e;return l.createElement(n.Z,{href:t,className:(0,r.Z)(s.tag,i?s.tagWithCount:s.tagRegular)},a,i&&l.createElement("span",null,i))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/02cf6bb5.883205f6.js b/build-staging/it/assets/js/02cf6bb5.883205f6.js new file mode 100644 index 00000000..3ce424ac --- /dev/null +++ b/build-staging/it/assets/js/02cf6bb5.883205f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9051],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var i=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=i.createContext({}),l=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return i.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||r;return n?i.createElement(f,a(a({ref:t},p),{},{components:n})):i.createElement(f,a({ref:t},p))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,a=new Array(r);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var i=n(7462),o=(n(7294),n(3905));const r={sidebar_position:1},a="Un'introduzione alle impostazioni dell'app di Cwtch",s={unversionedId:"settings/introduction",id:"settings/introduction",title:"Un'introduzione alle impostazioni dell'app di Cwtch",description:"Aspetto",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/introduction.md",sourceDirName:"settings",slug:"/settings/introduction",permalink:"/it/docs/settings/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Settings",permalink:"/it/docs/category/settings"},next:{title:"Appearance",permalink:"/it/docs/category/appearance"}},c={},l=[{value:"Aspetto",id:"aspetto",level:2},{value:"Comportamento",id:"comportamento",level:2},{value:"Esperimenti",id:"esperimenti",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"unintroduzione-alle-impostazioni-dellapp-di-cwtch"},"Un'introduzione alle impostazioni dell'app di Cwtch"),(0,o.kt)("h2",{id:"aspetto"},"Aspetto"),(0,o.kt)("p",null,"These are settings which effect how Cwtch looks, including themes and localization."),(0,o.kt)("h2",{id:"comportamento"},"Comportamento"),(0,o.kt)("p",null,"These settings impact how Cwtch responds to certain events e.g. notifications for new messages, or requests from unknown public addresses."),(0,o.kt)("h2",{id:"esperimenti"},"Esperimenti"),(0,o.kt)("p",null,"Ci sono molte funzionalit\xe1 in Cwtch che sono desiderabili ma la cui implementazione richiede metadati aggiuntivi, o un certo rischio, oltre il minimo che Cwtch richiede per le operazioni di base."),(0,o.kt)("p",null,"Di conseguenza, sotto ",(0,o.kt)("strong",{parentName:"p"},"Esperimenti")," troverete un certo numero di impostazioni ",(0,o.kt)("strong",{parentName:"p"},"opzionali")," che, quando abilitate, forniscono funzionalit\xe0 aggiuntive come conversazioni di gruppo, condivisione di file o formattazione dei messaggi."),(0,o.kt)("p",null,"Rifletti attentamente sui nuovi rischi che potrebbero essere coinvolti quando abiliti queste funzionalit\xe1, e chiediti se sei a tuo agio o meno nel momento in cui acconsenti a correre quei rischi. Per molti i vantaggi della condivisione di file, le anteprime dell'immagine e la chat di gruppo superano di gran lunga i potenziali danni - ma per tener conto e rispettare altre esigenze richiediamo a tutti di dare un consenso esplicito a queste funzionalit\xe0."),(0,o.kt)("p",null,"Puoi ritirare il tuo consensoin qualsiasi momento, tutte le funzionalit\xe0 sono implementate localmente all'interno dell'app Cwtch."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/043d4691.ff8e86cc.js b/build-staging/it/assets/js/043d4691.ff8e86cc.js new file mode 100644 index 00000000..1e2bddf4 --- /dev/null +++ b/build-staging/it/assets/js/043d4691.ff8e86cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7275],{4402:t=>{t.exports=JSON.parse('{"title":"Cwtch","slug":"/category/cwtch","permalink":"/it/security/category/cwtch","navigation":{"previous":{"title":"Authentication Protocol","permalink":"/it/security/components/tapir/authentication_protocol"},"next":{"title":"Message Formats","permalink":"/it/security/components/cwtch/message_formats"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/07eed749.e6de9ce0.js b/build-staging/it/assets/js/07eed749.e6de9ce0.js new file mode 100644 index 00000000..a53c4e52 --- /dev/null +++ b/build-staging/it/assets/js/07eed749.e6de9ce0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9010],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||o;return a?n.createElement(m,s(s({ref:t},d),{},{components:a})):n.createElement(m,s({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,s[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const o={},s="Message Overlays",i={unversionedId:"components/ui/overlays",id:"components/ui/overlays",title:"Message Overlays",description:"Adapted from Notes on the Cwtch Chat API",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/overlays.md",sourceDirName:"components/ui",slug:"/components/ui/overlays",permalink:"/it/security/components/ui/overlays",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Input",permalink:"/it/security/components/ui/input"},next:{title:"Deployment",permalink:"/it/security/deployment"}},l={},c=[{value:"Chat overlays, lists, and bulletins",id:"chat-overlays-lists-and-bulletins",level:2},{value:"Data structure",id:"data-structure",level:2},{value:"Chat Messages (Overlay 1)",id:"chat-messages-overlay-1",level:2},{value:"Invitations (Overlays 100 and 101)",id:"invitations-overlays-100-and-101",level:2},{value:"Lists / Bulletin Boards",id:"lists--bulletin-boards",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"message-overlays"},"Message Overlays"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/08-chatapi/"},"Adapted from: Discreet Log #8: Notes on the Cwtch Chat API")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note: This section covers overlay protocols on-top of the Cwtch protcol. For information on the Cwtch Protocol messages themselves please see ",(0,r.kt)("a",{parentName:"strong",href:"/it/security/components/cwtch/message_formats"},"Message Formats"))),(0,r.kt)("p",null,"We envision Cwtch as a platform for providing an authenticated transport layer to higher-level applications. Developers are free to make their own choices about what application layer protocols to use, whether they want bespoke binary message formats or just want to throw an HTTP library on top and call it a day. Cwtch can generate new keypairs for you (which become onion addresses; no need for any DNS registrations!) and you can REST assured that any data your application receives from the (anonymous communication) network has been authenticated already."),(0,r.kt)("p",null,"For our current stack, messages are wrapped in a minimal JSON frame that adds some contextual information about the message type. And because serialised JSON objects are just dictionaries, we can easily add more metadata later on as needed."),(0,r.kt)("h2",{id:"chat-overlays-lists-and-bulletins"},"Chat overlays, lists, and bulletins"),(0,r.kt)("p",null,'The original Cwtch alpha demoed "overlays": different ways of interpreting the same data channel, depending on the structure of the atomic data itself. We included simple checklists and BBS/classified ads as overlays that could be viewed and shared with any Cwtch contact, be it a single peer or a group. The wire format looked like this:'),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:1,d:"hey there!"}\n{o:2,d:"bread",l:"groceries"}\n{o:3,d:"garage sale",p:"[parent message signature]"}\n')),(0,r.kt)("p",null,"Overlay field ",(0,r.kt)("inlineCode",{parentName:"p"},"o")," determined if it was a chat (1), list (2), or bulletin (3) message. The data field ",(0,r.kt)("inlineCode",{parentName:"p"},"d")," is overloaded, and lists/bulletins need additional information about what group/post they belong to. (We use message signatures in place of IDs to avoid things like message ordering problems and maliciously crafted IDs. This is also how the Cwtch protocol communicates to the front end which message is being acked.)"),(0,r.kt)("h2",{id:"data-structure"},"Data structure"),(0,r.kt)("p",null,"Implementing tree-structured data on top of a sequential message store comes with obvious performance disadvantages. For example, consider the message view, which loads most-recent-messages first and only goes back far enough to fetch enough messages to fill the current viewport, in comparison with a (somewhat pathological) forum where almost every message is a child of the very first message in the history, which could have been gigs and gigs of data-ago. If the UI only displays top-level posts until the user expands them, we have to parse the entire history before we get enough info to display anything at all."),(0,r.kt)("p",null,'Another problem is that multiplexing all these overlays into one data store creates "holes" in the data that confuse ',(0,r.kt)("a",{parentName:"p",href:"https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html"},"lazy-loaded listviews")," and scrollbars. The message count may indicate there is a ton more information to display if the user simply scrolls, but when it actually gets fetched and parsed we might realize that none of it is relevant to the current overlay."),(0,r.kt)("p",null,"None of these problems are insurmountable, but they demonstrate a flaw in our initial assumptions about the nature of collaborative message flows and how we should be handling that data."),(0,r.kt)("h1",{id:"overlay-types"},"Overlay Types"),(0,r.kt)("p",null,"As stated above, overlays are specified in a very simple JSON format with the following structure:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'type ChatMessage struct {\n O int `json:"o"`\n D string `json:"d"`\n}\n')),(0,r.kt)("p",null,"Where O stands for ",(0,r.kt)("inlineCode",{parentName:"p"},"Overlay")," with the current supported overlays documented below:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"1: data is a chat string\n2: data is a list state/delta\n3: data is a bulletin state/delta\n100: contact suggestion; data is a peer onion address\n101: contact suggestion; data is a group invite string\n")),(0,r.kt)("h2",{id:"chat-messages-overlay-1"},"Chat Messages (Overlay 1)"),(0,r.kt)("p",null,"The most simple over is a chat message which simply contains raw, unprocessed chat message information."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:1,d:"got milk?"}\n')),(0,r.kt)("h2",{id:"invitations-overlays-100-and-101"},"Invitations (Overlays 100 and 101)"),(0,r.kt)("p",null,"Instead of receiving the invite as an incoming contact request at the profile level, new inline invites are shared with a particular contact/group, where they can be viewed and/or accepted later, even if they were initially rejected (potentially by accident)."),(0,r.kt)("p",null,"The wire format for these are equally simple:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},'{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}\n{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}\n')),(0,r.kt)("p",null,'This represents a departure from our original "overlays" thinking to a more action-oriented representation. The chat "overlay" can communicate that someone ',(0,r.kt)("em",{parentName:"p"},"did"),' something, even if it\'s paraphrased down to "added an item to a list," and the lists and bulletins and other beautifully chaotic data can have their state precomputed and stored separately.'),(0,r.kt)("h2",{id:"lists--bulletin-boards"},"Lists / Bulletin Boards"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Note: Expected to be Defined in Cwtch Beta 1.5")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/08c34551.c234e086.js b/build-staging/it/assets/js/08c34551.c234e086.js new file mode 100644 index 00000000..6a22de13 --- /dev/null +++ b/build-staging/it/assets/js/08c34551.c234e086.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9717],{7723:t=>{t.exports=JSON.parse('{"title":"Platforms","slug":"/category/platforms","permalink":"/it/docs/category/platforms","navigation":{"previous":{"title":"Stickers","permalink":"/it/docs/contribute/stickers"},"next":{"title":"Running Cwtch on Tails","permalink":"/it/docs/platforms/tails"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/08c3bd78.e7043240.js b/build-staging/it/assets/js/08c3bd78.e7043240.js new file mode 100644 index 00000000..5ce9a9d9 --- /dev/null +++ b/build-staging/it/assets/js/08c3bd78.e7043240.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4986],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var i=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=i.createContext({}),p=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=p(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var r=e.components,o=e.mdxType,n=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(r),d=o,m=u["".concat(l,".").concat(d)]||u[d]||f[d]||n;return r?i.createElement(m,a(a({ref:t},s),{},{components:r})):i.createElement(m,a({ref:t},s))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=r.length,a=new Array(n);a[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>n,metadata:()=>c,toc:()=>p});var i=r(7462),o=(r(7294),r(3905));const n={sidebar_position:1},a="Un'introduzione ai profili di Cwtch",c={unversionedId:"profiles/introduction",id:"profiles/introduction",title:"Un'introduzione ai profili di Cwtch",description:"Su Cwtch puoi creare uno o pi\xfa Profili. Ogni profilo genera una coppia di chiavi ed25519 casuale compatibile con la rete Tor.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/introduction.md",sourceDirName:"profiles",slug:"/profiles/introduction",permalink:"/it/docs/profiles/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Profiles",permalink:"/it/docs/category/profiles"},next:{title:"Creare un nuovo profilo",permalink:"/it/docs/profiles/create-a-profile"}},l={},p=[{value:"Gestire i profili",id:"gestire-i-profili",level:2}],s={toc:p},u="wrapper";function f(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,i.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"unintroduzione-ai-profili-di-cwtch"},"Un'introduzione ai profili di Cwtch"),(0,o.kt)("p",null,"Su Cwtch puoi creare uno o pi\xfa ",(0,o.kt)("strong",{parentName:"p"},"Profili"),". Ogni profilo genera una coppia di chiavi ed25519 casuale compatibile con la rete Tor."),(0,o.kt)("p",null,"Questo \xe8 l'identificatore che puoi fornire ad altre persone e che possono usare per contattarti tramite Cwtch."),(0,o.kt)("p",null,'Cwtch ti permette di creare e gestire multipli profili separati. Ogni profilo \xe8 associato a una diversa coppia di chiavi che lancia un diverso servizio "onion".'),(0,o.kt)("h2",{id:"gestire-i-profili"},"Gestire i profili"),(0,o.kt)("p",null,"All'avvio Cwtch avvier\xe0 la schermata Gestione Profili. Da questa schermata \xe8 possibile:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/create-a-profile"},"Creare un nuovo profilo")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/unlock-profile"},"Sbloccare i profili crittografati esistenti")),(0,o.kt)("li",{parentName:"ul"},"Gestire i profili caricati",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-name/"},"Cambiare il nome visualizzato di un profilo")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-password/"},"Cambiare la password di un profilo")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/delete-profile"},"Eliminare un profilo")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/change-profile-image/"},"Modificare l'immagine di un profilo"))))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0999b6aa.c4cb2bce.js b/build-staging/it/assets/js/0999b6aa.c4cb2bce.js new file mode 100644 index 00000000..33004d07 --- /dev/null +++ b/build-staging/it/assets/js/0999b6aa.c4cb2bce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3949],{4165:e=>{e.exports=JSON.parse('{"label":"repliqate","permalink":"/it/blog/tags/repliqate","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0a2b8ac2.a299c07b.js b/build-staging/it/assets/js/0a2b8ac2.a299c07b.js new file mode 100644 index 00000000..fba395e3 --- /dev/null +++ b/build-staging/it/assets/js/0a2b8ac2.a299c07b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3674],{2549:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"cwtch-stable-roadmap-update-june","metadata":{"permalink":"/it/blog/cwtch-stable-roadmap-update-june","source":"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","date":"2023-06-30T00:00:00.000Z","formattedDate":"30 giugno 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/it/blog/tags/planning"}],"readingTime":5.26,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals","slug":"cwtch-stable-roadmap-update-june","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"nextItem":{"title":"Cwtch Beta 1.12","permalink":"/it/blog/cwtch-nightly-1-12"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the Cwtch Stable Roadmap\\n\\nBack in March we extended and updated several goals from [our January roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document \u2705 - [Release Process](https://docs.cwtch.im/developing/release/#official-releases)\\n - A Cwtch Packaging Document \u2705 - [Packaging Documentation](https://docs.cwtch.im/developing/release/)\\n - Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new [documentation style guide](/docs/contribute/documentation), and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries \u2705 - [Building a Cwtch App](https://docs.cwtch.im/developing/category/building-a-cwtch-app)\\n - Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. \\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129) \ud83d\udfe1 - currently in [active development](https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information \u2705 - released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12)\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593) \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12). We now believe these changes will be complete in Cwtch Beta 1.13.\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms) \ud83d\udfe1 - we have already launched an environment for testing [Tails](/docs/platforms/tails). Other platforms are underway.\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\n\\n## Next Steps, Refinements, Additional Work\\n\\nAs you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. \\n\\nOther work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.\\n\\nHowever, [Cwtch Beta 1.12](https://docs.cwtch.im/blog/cwtch-nightly-1-12) featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.\\n\\nThe work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.\\n\\nWe are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-12","metadata":{"permalink":"/it/blog/cwtch-nightly-1-12","source":"@site/blog/2023-06-16-cwtch-1.12.md","title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","date":"2023-06-16T00:00:00.000Z","formattedDate":"16 giugno 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"release","permalink":"/it/blog/tags/release"}],"readingTime":2.455,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.12","description":"Cwtch Beta 1.12 is now available for download","slug":"cwtch-nightly-1-12","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog13_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/it/blog/cwtch-stable-roadmap-update-june"},"nextItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/it/blog/cwtch-nightly-v.11-74"}},"content":"[Cwtch 1.12 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new features like [profile attributes](https://docs.cwtch.im/docs/profiles/profile-info), support for new platforms like [Tails](https://docs.cwtch.im/docs/platforms/tails), and multiple improvements to performance and stability.\\n\\n![](/img/devlog13.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n
\\n\\n[![](/img/picnic1.12.png)](/img/picnic1.12.png)\\n\\n
A screenshot of Cwtch 1.12
\\n
\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Profile Attributes** - profiles can now be augmented with [additional public information](https://docs.cwtch.im/docs/profiles/profile-info)\\n - **Availability Status** - you can now notify contacts that you [are **away** or **busy**](https://docs.cwtch.im/docs/profiles/availability-status)\\n - **Five New Supported Localizations**: **Japanese**, **Korean**, **Slovak**, **Swahili** and **Swedish**\\n - **Support for Tails** - adds an [OnionGrater](https://docs.cwtch.im/docs/platforms/tails) configuration and a new `CWTCH_TAILS` environment variable that enables special Tor behaviour.\\n- **Bug Fixes / Improvements:**\\n - Based on Flutter 3.10\\n - Inter is now the main UI font\\n - New Font Scaling setting\\n - New Network Management code to better manage Tor on unstable networks\\n - File Sharing Experiment Fixes\\n \\t- Fix performance issues for file bubble\\n \\t- Allow restarting of file shares that have timed out\\n \\t- Fix NPE in FileBubble caused by deleting the underlying file\\n \\t- Move from RetVal to UpdateConversationAttributes to minimze UI thread issues\\n - Updates to Linux install scripts to support more distributions\\n - Add a Retry Peer connection to prioritize connection attempts for certain conversations\\n - Updates to `_FlDartProject` to allow custom setting of Flutter asset paths\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Slovak**, **Spanish**, **Swahili**, **Swedish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Japanese** (29%), **Korean** (23%), **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n## Reproducible Bindings\\n\\nCwtch 1.12 is based on libCwtch version `libCwtch-autobindings-2023-06-13-10-50-v0.0.5`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-v.11-74","metadata":{"permalink":"/it/blog/cwtch-nightly-v.11-74","source":"@site/blog/2023-06-07-new-nightly.md","title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","date":"2023-06-07T00:00:00.000Z","formattedDate":"7 giugno 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/it/blog/tags/developer-documentation"}],"readingTime":1.845,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","description":"In this development log we take a look at the new Cwtch Nightly","slug":"cwtch-nightly-v.11-74","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog10_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.12","permalink":"/it/blog/cwtch-nightly-1-12"},"nextItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/it/blog/cwtch-developer-documentation"}},"content":"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog10.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-06-05-17-36-v1.11.0-74-g0406](https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/).\\n\\nThis version has a large number of improvements and bug fixes including:\\n\\n* A new Font Scaling setting\\n* Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.\\n* Updated UI font styles\\n* Dependency updates, including a new base of Flutter 3.10.\\n* A fix for stuck file downloading notifications on Android\\n* A fix for missing profile images in certain edge cases on Android\\n* Japanese, Swedish, and Swahili translation options\\n* A new retry peer connection button for prompting Cwtch to prioritize specific connections\\n* [Tails support](/docs/platforms/tails)\\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-developer-documentation","metadata":{"permalink":"/it/blog/cwtch-developer-documentation","source":"@site/blog/2023-04-28-developer-docs.md","title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","date":"2023-04-28T00:00:00.000Z","formattedDate":"28 aprile 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"developer-documentation","permalink":"/it/blog/tags/developer-documentation"}],"readingTime":2.595,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","description":"In this development log we take a look at the new Cwtch developer docs!","slug":"cwtch-developer-documentation","tags":["cwtch","cwtch-stable","developer-documentation"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/it/blog/cwtch-nightly-v.11-74"},"nextItem":{"title":"Availability Status and Profile Attributes","permalink":"/it/blog/availability-status-profile-attributes"}},"content":"One of the larger remaining goals outlined in our [Cwtch Stable roadmap update](/blog/cwtch-stable-roadmap-update) is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. \\n\\nIn this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!\\n\\nWe are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!\\n\\nAs a reminder, the Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like ours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n![](/img/devlog9.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Cwtch Development Handbook\\n\\nWe have created a new documentation section, [the developers handbook](/developing/intro). This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).\\n\\n### Release and Packaging Process\\n\\nThe new handbook features a breakdown of [Cwtch release processes](/developing/release) - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.\\n\\n### Cwtch Application Development and Cwtchbot v0.1.0!\\n\\nFor the first time ever we now have [comprehensive documentation on how to build a Cwtch Application](/developing/category/building-a-cwtch-app). This section of the development handbook covers everything from [choosing a Cwtch library](/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library), to [building your first application](/developing/building-a-cwtch-app/building-an-echobot).\\n\\nTogether with this new documentation we have also [released version 0.1 of the Cwtchbot framework](https://git.openprivacy.ca/sarah/cwtchbot), updating calls to use the [new Cwtch Stable API](/blog/cwtch-stable-api-design).\\n\\n### New Nightly\\n\\nThere is a [new Nightly build](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. The latest nightly we recommend testing is [2023-04-26-20-57-v1.11.0-33-gb4371](https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/).\\n\\nThis version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the [in-development Tails support](/docs/platforms/tails). \\n\\nIn addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"availability-status-profile-attributes","metadata":{"permalink":"/it/blog/availability-status-profile-attributes","source":"@site/blog/2023-04-06-availability-and-profile-attributes.md","title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","date":"2023-04-06T00:00:00.000Z","formattedDate":"6 aprile 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"nightly","permalink":"/it/blog/tags/nightly"}],"readingTime":1.445,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Availability Status and Profile Attributes","description":"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.","slug":"availability-status-profile-attributes","tags":["cwtch","cwtch-stable","nightly"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/it/blog/cwtch-developer-documentation"},"nextItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/it/blog/cwtch-stable-roadmap-update"}},"content":"Two new Cwtch features are now available to test in nightly: [Availability Status](/docs/profiles/availability-status) and [Profile Information](/docs/profiles/profile-info).\\n\\nAdditionally, we have also published draft guidance on [running Cwtch on Tails](/docs/platforms/tails) that we would like volunteers to test and report back on.\\n \\nThe Open Privacy Research Society have [also announced they are want to raise $60,000 in 2023](https://openprivacy.ca/discreet-log/38-march-2023/) to help move forward projects like Cwtch. Please help support projects like\\nours with a [one-off donations](https://openprivacy.ca/donate) or [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Availability Status\\n\\nNew in this nightly is the ability to notify your conversations that you are \\"Away\\" or \\"Busy\\".\\n\\n
\\n\\n[![](/img/profiles/status-tooltip-busy-set.png)](/img/profiles/status-tooltip-busy-set.png)\\n\\n
\\n
\\n\\nRead more: [Availability Status](/docs/profiles/availability-status)\\n\\n## Profile Attributes\\n\\nAlso new is the ability to augment your profile with a few small pieces of **public** information.\\n\\n
\\n\\n[![](/img/profiles/attributes-set.png)](/img/profiles/attributes-set.png)\\n\\n
\\n
\\n\\nRead more: [Profile Information](/docs/profiles/profile-info)\\n \\n## Downloading the Nightly\\n\\n[Nightly builds](https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies) are available from our build server. Download links for **2023-04-05-18-28-v1.11.0-7-g0290** are available below.\\n\\n* Windows: [https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/)\\n* Linux: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n* Mac: [https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/)\\n* Android: [https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/](https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/)\\n\\nPlease see the contribution documentation for advice on [submitting feedback](/docs/contribute/testing#submitting-feedback)\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-roadmap-update","metadata":{"permalink":"/it/blog/cwtch-stable-roadmap-update","source":"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md","title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","date":"2023-03-31T00:00:00.000Z","formattedDate":"31 marzo 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/it/blog/tags/planning"}],"readingTime":5.61,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable Roadmap Update","description":"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more","slug":"cwtch-stable-roadmap-update","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Availability Status and Profile Attributes","permalink":"/it/blog/availability-status-profile-attributes"},"nextItem":{"title":"Cwtch Beta 1.11","permalink":"/it/blog/cwtch-nightly-1-11"}},"content":"The next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.\\n\\nThis post [revisits the Cwtch Stable roadmap](/blog/path-to-cwtch-stable) we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.\\n\\n![](/img/devlog1.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Update on the January Roadmap\\n\\nBack in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:\\n\\n(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)\\n\\n- By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705\\n- By **1st February 2023**, the Cwtch team will have [finalized a feature set that defines Cwtch Stable](/blog/cwtch-stable-api-design) and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705\\n- By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:\\n - [Security and Design Documents](/security/intro) \u2705\\n - Infrastructure and [Support](/docs/getting-started/supported_platforms) \ud83d\udfe1\\n - in addition to a new development blog. \u2705\\n- By **31st March 2023**, the Cwtch team will have created:\\n - a [style guide for documentation](/docs/contribute/documentation), and \u2705\\n - have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1\\n - with at least one screenshot (where applicable). \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have published: \\n - a Cwtch [Interface Specification Document](/blog/cwtch-stable-api-design) \u2705\\n - a Cwtch Release Process Document \ud83d\udfe1\\n - a Cwtch [Support Plan document](/blog/cwtch-platform-support) \u2705\\n - a Cwtch Packaging Document \ud83d\udfe1\\n - a document describing the [Reproducible Builds Process](/blog/cwtch-bindings-reproducible) \u2705\\n - These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1\\n- By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705\\n- By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c\\n- By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)\\n\\nWhile we didn\'t hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:\\n\\n* [Cwtch Autobindings](/blog/autobindings) with [compile-time optional experiments](/blog/autobindings-ii)\\n* [Cwtch 1.11](/blog/cwtch-nightly-1-11) - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements.\\n* [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.\\n\\n## A Timeline for Cwtch Stable\\n\\nNow for the big news, we plan on releasing a candidate Cwtch Stable release during **Summer 2023**. Here is our plan for getting there:\\n\\n- By **30th April 2023** the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:\\n - A Cwtch Release Process Document\\n - A Cwtch Packaging Document\\n - Completion of documentation of existing Cwtch features, including relevant screenshots.\\n- By **30th April 2023** the Cwtch team will have also released developer-centric documentation including:\\n - A guide to building Cwtch-apps using official libraries\\n - Automatically generated API documentation for libCwtch\\n- By **30th June 2023** the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:\\n - An implementation of [Conversation Search](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129)\\n - [Profile statuses](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27) and other associated information\\n - An update to the network handling code to allow for [better Protocol Engine management](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593)\\n- By **31st July 2023** the Cwtch team will have completed several infrastructure upgrades including:\\n - Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.\\n - Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team\\n - New testing environments for F-droid, Whonix, Raspberry Pi and other [partially supported systems](/docs/getting-started/supported_platforms)\\n- By **31st August 2023** the Cwtch team will have a released Cwtch Stable Release Candidate:\\n - At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.\\n - Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.\\n - **This does not mark an end to Cwtch development**, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.\\n\\nThis is not all we have planned for the upcoming months. Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Get Involved\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-nightly-1-11","metadata":{"permalink":"/it/blog/cwtch-nightly-1-11","source":"@site/blog/2023-03-29-cwtch-1.11.md","title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","date":"2023-03-29T00:00:00.000Z","formattedDate":"29 marzo 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"release","permalink":"/it/blog/tags/release"}],"readingTime":2.365,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Beta 1.11","description":"Cwtch Beta 1.11 is now available for download","slug":"cwtch-nightly-1-11","tags":["cwtch","cwtch-stable","release"],"image":"/img/devlog12_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable Roadmap Update","permalink":"/it/blog/cwtch-stable-roadmap-update"},"nextItem":{"title":"Updates to Cwtch Documentation","permalink":"/it/blog/cwtch-documentation"}},"content":"[Cwtch 1.11 is now available for download](https://cwtch.im/download)!\\n\\nCwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for [Cwtch Stable](/blog/path-to-cwtch-stable) including new [reproducible](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) and [automatically generated](https://docs.cwtch.im/blog/autobindings) bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.\\n\\n![](/img/devlog12.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## In This Release\\n\\n
\\n\\n[![](/img/picnic.png)](/img/picnic.png)\\n\\n
A screenshot of Cwtch 1.11
\\n
\\n\\nA special thanks to the [amazing volunteer translators](https://docs.cwtch.im/docs/contribute/translate) and [testers](https://docs.cwtch.im/docs/contribute/testing) who made this release possible.\\n\\n- **New Features:**\\n - **Based on new Reproducible Cwtch Stable Autobuilds** - this is the first release of cwtch based on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible) in addition to our new [automatically generated](https://docs.cwtch.im/blog/autobindings)\\n - **Two New Supported Localizations**: **Slovak** and **Korean**\\n- **Bug Fixes / Improvements:**\\n - When preserving a message draft, quoted messages are now also saved\\n - Layout issues caused by pathological unicode are now prevented\\n - Improved performance of message row rendering\\n - Clickable Links: Links in replies are now selectable\\n - Clickable Links: Fixed error when highlighting certain URIs \\n - File Downloading: Fixes for file downloading and exporting on 32bit Android devices\\n - Server Hosting: Fixes for several layout issues\\n - Build pipeline now runs automated UI tests\\n - Fix issues caused by scrollbar controller overriding\\n - Initial support for the Blodeuwedd Assistant (currently compile-time disabled)\\n - Cwtch Library:\\n - [New Stable Cwtch Peer API](/blog/cwtch-stable-api-design)\\n - Ported File Downloading and Image Previews experiments into Cwtch\\n- **Accessibility / UX:**\\n - Full translations for **Brazilian Portuguese**, **Dutch**, **French**, **German**, **Italian**, **Russian**, **Polish**, **Spanish**, **Turkish**, and **Welsh**\\n - Core translations for **Danish** (75%), **Norwegian** (76%), and **Romanian** (75%)\\n - Partial translations for **Luxembourgish** (22%), **Greek** (16%), and **Portuguese** (6%)\\n\\n\\n\\n## Reproducible Bindings\\n\\nCwtch 1.11 is based on libCwtch version `2023-03-16-15-07-v0.0.3-1-g50c853a`. The [repliqate scripts](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate) to reproduce these bindings from source can be found at [https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a)\\n\\n## Download the New Version \\n\\nYou can download Cwtch from [https://cwtch.im/download](https://cwtch.im/download).\\n\\nSubscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\nAlternatively we also provide a [releases-only RSS feed](https://cwtch.im/releases/index.xml).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-documentation","metadata":{"permalink":"/it/blog/cwtch-documentation","source":"@site/blog/2023-03-10-cwtch-documentation.md","title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","date":"2023-03-10T00:00:00.000Z","formattedDate":"10 marzo 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"documentation","permalink":"/it/blog/tags/documentation"},{"label":"security-handbook","permalink":"/it/blog/tags/security-handbook"}],"readingTime":2.57,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Updates to Cwtch Documentation","description":" In this development log we will highlight some of the major documentation updates over the last few weeks.","slug":"cwtch-documentation","tags":["cwtch","cwtch-stable","documentation","security-handbook"],"image":"/img/devlog9_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Beta 1.11","permalink":"/it/blog/cwtch-nightly-1-11"},"nextItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/it/blog/autobindings-ii"}},"content":"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.\\n\\n![](/img/devlog9.png)\\n \\n\x3c!--truncate--\x3e\\n\\n## Cwtch Secure Development Handbook\\n \\nOne of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.\\n\\nWe have [now ported the the handbook to this documentation site](/security/intro), along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. \\n\\n## Volunteer Development\\n\\nWe have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called [Developing Cwtch](/docs/contribute/developing) - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.\\n\\nWe also also updated our guides on [Translating Cwtch](/docs/contribute/translate) and [Testing Cwtch](/docs/contribute/testing).\\n\\nIf you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to `team@cwtch.im` (or open an issue) with any questions. All types of contributions [are eligible for stickers](/docs/contribute/stickers).\\n\\n## Next Steps\\n\\nWe still have more work to do on the documentation front:\\n\\n* Ensuring all pages [implement the new documentation style guide](/docs/contribute/documentation), and include appropriate screenshots and descriptions.\\n* Expanding the security handbook to provide information on [reproducible builds](/blog/cwtch-bindings-reproducible), [the new Cwtch Stable API](/blog/cwtch-stable-api-design) and upcoming improvements around fuzz testing.\\n* Creating new documentation sections on the [libCwtch autobindings API](/blog/autobindings) and building applications on top of Cwtch.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all aspects of Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings-ii","metadata":{"permalink":"/it/blog/autobindings-ii","source":"@site/blog/2023-03-03-autobindings-optional-experiments.md","title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","date":"2023-03-03T00:00:00.000Z","formattedDate":"3 marzo 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/it/blog/tags/bindings"},{"label":"autobindings","permalink":"/it/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/it/blog/tags/libcwtch"}],"readingTime":4.655,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Compile-time Optional Application Experiments (Autobindings)","description":"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.","slug":"autobindings-ii","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Updates to Cwtch Documentation","permalink":"/it/blog/cwtch-documentation"},"nextItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/it/blog/autobindings"}},"content":"[Last time we looked at autobindings](https://docs.cwtch.im/blog/autobindings) we mentioned that one of the next steps was introducing support for **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)**. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## The Structure of an Application Experiment\\n\\nAn application-level experiment consists of:\\n\\n1. A set of top-level APIs, e.g. `CreateServer`, `LoadServer`, `DeleteServer` - these are the APIs that we want to expose to calling applications.\\n2. An encapsulating structure for the set of APIs, e.g. `ServersFunctionality` - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.\\n3. A global variable that exists at the top level of libCwtch, e.g. `var serverExperiment *servers.ServersFunctionality servers` - our single pointer to the underlying functionality.\\n4. A set of management-related APIs, e.g. `Init`, `UpdateSettings`, `OnACNEvent` - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).\\n5. Management code within `_startCwtch` and `_reconnectCwtch` that calls the management APIs on the global variable.\\n\\nFrom a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\\nof on `application` or a specific `profile`.\\n\\nMost of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.\\n\\n### New Required Management APIs\\n\\nTo achieve this weaving, we now require application-level experiments to implement an `EventHandlerInterface` interface and expose itself via an\\ninitialize constructor `Init(acn, appDir) -> EventHandlerInterface`, and `Enable(app, acn)`.\\n\\nFor now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.\\n\\nWe can then generate, and optionally include blocks of code like:\\n\\n\\t\\t = .Init(&globalACN, appDir)\\n\\t\\teventHandler.AddModule()\\n\\t\\t.Enable(application, &globalACN)\\n\\nand place them at specific points in the code. `EventHandler` has also been extended to maintain a collection of `modules` so that it can\\npass on interesting events.\\n\\n### Adding Support for Application Experiments in the Spec File\\n\\nWe have introduced a new `!` operator which can be used to gate APIs behind a configured experiment. Along with a new\\ntemplating option `exp` which will call the function on the configured experiment, and `global` to allow the setting up\\nof a global functionality within the library.\\n\\n\\t\\t# Server Hosting Experiment\\n\\t\\t!serverExperiment import \\"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\\"\\n\\t\\t!serverExperiment global serverExperiment *servers.ServersFunctionality servers\\n\\t\\t!serverExperiment exp CreateServer application password string:description bool:autostart\\n\\t\\t!serverExperiment exp SetServerAttribute application string:handle string:key string:val\\n\\t\\t!serverExperiment exp LoadServers application acn password\\n\\t\\t!serverExperiment exp LaunchServers application acn\\n\\t\\t!serverExperiment exp LaunchServer application string:handle\\n\\t\\t!serverExperiment exp StopServer application string:handle\\n\\t\\t!serverExperiment exp StopServers application\\n\\t\\t!serverExperiment exp DestroyServers\\n\\t\\t!serverExperiment exp DeleteServer application string:handle password\\n\\n### Generation-Time Inclusion\\n\\n Without any arguments provided `generate-bindings` will not generate code for any experiments.\\n\\n In order to determine what experimental code to generate, `generate-bindings` now interprets arguments as enabled compile time experiments, e.g. `generate-bindings serverExperiment` will turn on\\n generation of server hosting code, per the spec file above.\\n\\n### Cwtch UI Integration\\n\\nThe UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. `c_LoadServers` - if it doesn\'t then the UI is safe to assume the\\nfeature is not available.\\n\\n
\\n\\n![](/img/dev9-host-disabled.png)\\n\\n
A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.
\\n
\\n\\n## Nightlies & Next Steps\\n\\nWe are now publishing [nightlies](https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/) of autobinding derived libCwtch-go, along with [Repliqate scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2) for reproducibility.\\n\\nWith application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.\\n\\nHowever, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:\\n\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs).\\n * **Documentation generation**: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"autobindings","metadata":{"permalink":"/it/blog/autobindings","source":"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md","title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","date":"2023-02-24T00:00:00.000Z","formattedDate":"24 febbraio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"bindings","permalink":"/it/blog/tags/bindings"},{"label":"autobindings","permalink":"/it/blog/tags/autobindings"},{"label":"libcwtch","permalink":"/it/blog/tags/libcwtch"}],"readingTime":4.545,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Autogenerating Cwtch Bindings","description":"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.","slug":"autobindings","tags":["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],"image":"/img/devlog8_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/it/blog/autobindings-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/it/blog/cwtch-testing-ii"}},"content":"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to **automatically generate** these bindings: [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings).\\n\\nThis this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the [path to Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable).\\n\\n![](/img/devlog8.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## A Brief History of Cwtch Bindings\\n\\nPrior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by [therecipe/qt](https://github.com/therecipe/qt). However, after encountering numerous\\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.\\n\\nAs part of early prototyping efforts for Flutter we built out a first version of [libCwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go), and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.\\n\\nThis approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular [experimental features](https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape) - handle settings, [duplication of logic between Cwtch and libCwtch-go](https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings), and [special behaviour in libCwtch-go that better belongs in the core Cwtch library](https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go).\\n\\nAs part of a broader effort to [refine the Cwtch API in preparation for Cwtch Stable](https://docs.cwtch.im/blog/cwtch-stable-api-design) we have taken the opportunity to fix many of these problems.\\n\\n## Cwtch Autobindings\\n\\nThe current `lib.go` file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the `BlockContact` API implementation is:\\n\\n\\t//export c_BlockContact\\n\\tfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\\n\\t\\tBlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\\n\\t}\\n\\n\\tfunc BlockContact(profileOnion string, conversationID int) {\\n\\t\\tprofile := application.GetPeer(profileOnion)\\n\\t\\tif profile != nil {\\n\\t\\t\\tprofile.BlockConversation(conversationID)\\n\\t\\t}\\n\\t}\\n\\nAll that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.\\n\\nIn the new [cwtch-autobindings](https://git.openprivacy.ca/cwtch.im/autobindings) we reduce these multiple lines to [a single one](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19):\\n\\n\\tprofile BlockConversation conversation\\n\\nDefining a `profile`-level function, called `BlockConversation` which takes in a single parameter of type `conversation`.\\n\\nUsing a similar boilerplate-reduction for the reset of `lib.go` yields [5-basic function prototypes](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format):\\n\\n* Application-level functions e.g. `CreateProfile`\\n* Profile-level functions e.g. `BlockConversation`\\n* Profile-level functions that return data e.g. `GetMessage`\\n* Experimental Profile-level feature functions e.g. `DownloadFile`\\n* Experimental Profile-level feature functions that return data e.g. `ShareFile`\\n\\nOnce aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be [described in fewer than 50 lines, including comments](https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec). Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).\\n\\n## Next Steps\\n\\nCwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:\\n\\n * **[Application-level experiments](https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments)** (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on `cwtch-server`). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don\'t support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.\\n* **Dart Library generation**: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the [Dart-side](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch) of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. [libcwtch-rs](https://git.openprivacy.ca/cwtch.im/libcwtch-rs)\\n * **Documentation generation**: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with [docs.cwtch.im](https://cwtch.im).\\n * **Cwtch API**: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the [Cwtch Stable API redesign](https://docs.cwtch.im/blog/cwtch-stable-api-design). In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-ii","metadata":{"permalink":"/it/blog/cwtch-testing-ii","source":"@site/blog/2023-02-17-cwtch-testing-ii.md","title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","date":"2023-02-17T00:00:00.000Z","formattedDate":"17 febbraio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"support","permalink":"/it/blog/tags/support"},{"label":"testing","permalink":"/it/blog/tags/testing"}],"readingTime":1.75,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing (II)","description":"In this development log we provide more updates on automated UI integration testing!","slug":"cwtch-testing-ii","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog7_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Autogenerating Cwtch Bindings","permalink":"/it/blog/autobindings"},"nextItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/it/blog/cwtch-android-reproducibility"}},"content":"In this development log, we investigate some text-based UI bugs encountered by [Fuzzbot](https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot), add more [automated UI tests](/blog/cwtch-testing-i) to the pipeline, and announce a new release of the Cwtchbot library.\\n\\n![](/img/devlog7.png)\\n\\n\x3c!--truncate--\x3e\\n\\n\\n## Constraining Cwtch UI Fields\\n\\nFuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\\ndoesn\'t pose a safety issue, it is unsightly.\\n\\n
\\n\\n[![](/img/dl7-before.png)](/img/dl7-before.png)\\n\\n
Screenshot demonstrating how certain strings would violate the bounds of their containers.
\\n
\\n\\nThese cases were fixed by parenting impacted elements in a `Container` with `clip: hardEdge` and `decoration:BoxDecoration()` (note that both of these are required as Container widgets in Flutter cannot set clipping logic\\nwithout an associated decoration).\\n\\n
\\n\\n[![](/img/dl7-after.png)](/img/dl7-after.png)\\n\\n
Now these clipped strings are tightly constrained to their container bounds.
\\n
\\n\\nThese fixes are available in the [latest Cwtch Nightly](/docs/contribute/testing#cwtch-nightlies), and will be officially released in Cwtch 1.11.\\n\\n## More Automated UI Tests\\n\\nWe have added two new sets of automated UI tests to our pipeline:\\n\\n- *02: Global Settings* - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. ([PR: 628](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628))\\n- *04: Profile Management* - these tests check that creating, unlocking, and deleting a profile work as expected. ([PR: 632](https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632))\\n\\n## New Release of Cwtchbot\\n\\n[Cwtchbot](https://git.openprivacy.ca/sarah/cwtchbot) has been updated to use the latest Cwtch 0.18.10 API.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-android-reproducibility","metadata":{"permalink":"/it/blog/cwtch-android-reproducibility","source":"@site/blog/2023-02-10-android-reproducibility.md","title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","date":"2023-02-10T00:00:00.000Z","formattedDate":"10 febbraio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/it/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/it/blog/tags/bindings"},{"label":"repliqate","permalink":"/it/blog/tags/repliqate"}],"readingTime":2.92,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Android Bindings Reproducible","description":"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible","slug":"cwtch-android-reproducibility","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog6_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing (II)","permalink":"/it/blog/cwtch-testing-ii"},"nextItem":{"title":"Notes on Cwtch UI Testing","permalink":"/it/blog/cwtch-testing-i"}},"content":"In this development log, we continue our previous work on [reproducible Cwtch bindings](https://docs.cwtch.im/blog/cwtch-bindings-reproducible), uncovering the final few sources of variation between our [Repliqate](https://git.openprivacy.ca/openprivacy/repliqate) scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!\\n\\n![](/img/devlog6.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Changes Necessary for Reproducible Android Bindings\\n\\nAfter a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:\\n\\n- **Insufficient path stripping introduced by Android NDK tools** - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 [changed the binutils and default linker](https://github.com/android/ndk/wiki/Changelog-r22) to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our [long term support plan](https://docs.cwtch.im/blog/cwtch-platform-support), we will be moving towards adopting the latest NDK in the future.\\n- **Paths in DWARF entries** - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.\\n\\n
\\n\\n[![](/img/aar-diff.png)](/img/aar-diff.png)\\n\\n
Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
\\n
\\n\\n- **Go Compiler Acquisition** - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there *was* a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.\\n\\n## Repliqate Scripts\\n\\nWith those issues now fixed, Cwtch Android bindings are **officially reproducible!** The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under [cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script) in the [Cwtch Repliqate scripts repository](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/).\\n\\nThis is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-testing-i","metadata":{"permalink":"/it/blog/cwtch-testing-i","source":"@site/blog/2023-02-03-cwtch-testing-i.md","title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","date":"2023-02-03T00:00:00.000Z","formattedDate":"3 febbraio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"support","permalink":"/it/blog/tags/support"},{"label":"testing","permalink":"/it/blog/tags/testing"}],"readingTime":4.74,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Notes on Cwtch UI Testing","description":"In this development log we provide an update on automated UI integration testing!","slug":"cwtch-testing-i","tags":["cwtch","cwtch-stable","support","testing"],"image":"/img/devlog5_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/it/blog/cwtch-android-reproducibility"},"nextItem":{"title":"Cwtch UI Platform Support","permalink":"/it/blog/cwtch-platform-support"}},"content":"We first [introduced UI tests last January](https://openprivacy.ca/discreet-log/23-cucumber-testing/). At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.\\n\\nOne of the main threads of work that needs to be complete early in the [Cwtch Stable roadmap](https://docs.cwtch.im/blog/path-to-cwtch-stable) is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.\\n\\n![](/img/devlog5.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Current Limitations of Flutter Gherkin\\n\\nThe original [flutter_gherkin](https://pub.dev/packages/flutter_gherkin) is under semi-active development; however, the latest published versions don\'t support using it with `flutter test`.\\n\\n- **Flutter Test** was originally intended to run single widget/unit tests for a Flutter project.\\n- **Flutter Drive** was originally intended to run integration tests *on a device or an emulator*.\\n\\nHowever, in recent releases these lines have become blurred. The new [integration_test](https://docs.flutter.dev/testing/integration-tests) package that comes built into newer Flutter releases has support for both `flutter drive` and `flutter test`. This was a great change because it decreases the required overhead to run larger integration tests (`flutter drive` sets up a host-controller model that requires a dedicated control channel to be setup, whereas `flutter test` can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).\\n\\nThere is thankfully code in the `flutter_gherkin` repository that supports running tests with `flutter test`, however this code currently has a few issues:\\n\\n- The test code generation produces code that doesn\'t compile without minor changes.\\n- Certain functionality like \\"take a screenshot\\" does not work on desktop.\\n\\nAdditionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:\\n\\n- Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.\\n- Certain Flutter widgets like `DropdownButton` are not compatible with built-in steps like `tap` because they internally contain multiple copies of the same widget.\\n\\nBecause of the above issues we have chosen to [fork flutter_gherkin](https://git.openprivacy.ca/openprivacy/flutter_gherkin) to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.\\n\\n## Integrating Tests into the Pipeline\\n\\nOne of the major limitations of `flutter test` is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.\\n\\nThankfully it is possible to use [Xfvb](https://en.wikipedia.org/wiki/Xvfb) to create a virtual framebuffer, and set `DISPLAY` to render to that buffer:\\n\\n export DISPLAY=:99\\n Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\\n\\nThis allows us to neutralize our main issue with `flutter test`, and efficiently run tests in our pipeline.\\n\\n## Catching Bugs!\\n\\nThis small amount of integration work has already caught its first bug.\\n\\nOnce we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. [02_save_load.feature](https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature) simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.\\n\\nThe cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory `$USER_HOME/Downloads` didn\'t exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.\\n\\nAs we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!\\n\\n## Next Steps\\n\\n- **More automated tests:** We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.\\n- **More platforms:** Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across [our target platforms](https://docs.cwtch.im/docs/getting-started/supported_platforms). We expect to start this work soon; expect more news in a future Cwtch Testing update!\\n\\n- **More steps:** One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the `expect to see the message` step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. `send a file` or `set profile picture`.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-platform-support","metadata":{"permalink":"/it/blog/cwtch-platform-support","source":"@site/blog/2023-01-27-platform-support.md","title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","date":"2023-01-27T00:00:00.000Z","formattedDate":"27 gennaio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"support","permalink":"/it/blog/tags/support"}],"readingTime":10.535,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch UI Platform Support","description":"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.","slug":"cwtch-platform-support","tags":["cwtch","cwtch-stable","support"],"image":"/img/devlog4_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Notes on Cwtch UI Testing","permalink":"/it/blog/cwtch-testing-i"},"nextItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/it/blog/cwtch-bindings-reproducible"}},"content":"One of the [tenets for Cwtch Stable is **Universal Availability and Cohesive Support**](https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable):\\n\\n> \\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\"\\n\\nThis development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.\\n\\nThe questions we aim to answer in this post are: \\n\\n- What systems do we currently support?\\n- How do we decide what systems are supported?\\n- How do we handle new OS versions?\\n- How does application support differ from library support?\\n- What blockers exist for systems we wish to support, but currently cannot e.g ios?\\n\\n![](/img/devlog4.png)\\n\\n\x3c!--truncate--\x3e\\n\\n## Constraints on support\\n\\nFrom CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. \\n\\nIn this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.\\n\\n### Limitations on general-purpose computing \\n\\nIn order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to *other* onion services). \\n\\nOn desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, **blocked entirely**. \\n\\nThis is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.\\n\\nWhile we expect that [Arti](https://gitlab.torproject.org/tpo/core/arti) will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. \\n\\nAs Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.\\n\\nWe encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don\'t place restrictions on what you can do with your own device.\\n\\n### Constraints introduced by the Flutter SDK\\n\\nThe Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by [platforms that are supported by the Flutter SDK](https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms).\\n\\nTo summarize, as of writing this document those platforms are:\\n\\n- Android API 16 and above (arm, arm64, and amd64)\\n- Debian-based Linux Distributions (64-bit only)\\n- macOS El Capitan (10.11) and above\\n- Windows 7 & above (64-bit only)\\n\\nTo put it plainly, without porting Cwtch UI to a different UI platform **we cannot support a 32-bit desktop version**.\\n\\n### Constraints introduced by Appstore Policy \\n\\nAs of writing, [Google is pushing applications to target API 31 or above](https://developer.android.com/google/play/requirements/target-sdk). This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.\\n\\n### CPU Architecture and Cwtch Bindings\\n\\nWe currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.\\n\\nIt is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.\\n\\n| Architecture / Platform | Windows | Linux | macOS | Android |\\n|--------------------------|---------|-----|-------| -------------|\\n| arm | \u274c | \u274c | \u274c | \u2705\ufe0f| \\n| arm64 | \u274c | \ud83d\udfe1 | \u2705 | \u2705\ufe0f | \\n| x86-64 / amd64 | \u2705 | \u2705 | \u2705\ufe0f | \u2705\ufe0f |\\n\\n\\"\ud83d\udfe1\\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).\\n\\n### Testing and official support\\n\\nAs a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the [Cwtch Release Candidate Testers](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.\\n\\nWe officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.\\n\\n### End-of-life platforms\\n\\nOperating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. [Windows 7 fell out of support on January 14, 2020](https://www.microsoft.com/en-us/windows/end-of-support), Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.\\n\\nLikewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.\\n\\nThe same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. [Cwtch currently requires libc 2.31+](https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations).\\n\\nAndroid versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our [Cwtch Release Candidate Testers groups](https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group) to help us understand the limitations of Android support across different API versions.\\n\\n## How we decide to officially support a platform\\n\\nTo help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:\\n\\n1. **The target platform needs to be officially supported by our development tools** - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.\\n2. **The target operating system needs to be supported by the Vendor** - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).\\n3. **The target platform must be backwards compatible with the most recent version in general use** - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch *may* run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).\\n4. **People want to use Cwtch on that platform** - We will generally only consider new platform support if people ask us about it. If Cwtch isn\'t available for a platform you want to use it on, then please get in touch and ask us about it!\\n\\n## Summary of official support\\n\\nThe table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). \\n\\nIn many cases we are looking for testers to confirm that various functionality works. A version of this table will be [maintained as part of the Cwtch Handbook](/docs/getting-started/supported_platforms).\\n\\n**Legend:**\\n\\n- \u2705: **Officially Supported**. Cwtch should work on these platforms without issue. Regressions are treated as high priority.\\n- \ud83d\udfe1: **Best Effort Support**. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.\\n- \u274c: **Not Supported**. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.\\n\\n\\n\\n| Platform | Official Cwtch Builds | Source Support | Notes |\\n|-----------------------------|-----------------------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------|\\n| Windows 11 | \u2705 | \u2705 | 64-bit amd64 only. |\\n| Windows 10 |\u2705 | \u2705 | 64-bit amd64 only. Not officially supported, but official builds may work. |\\n| Windows 8 and below | \u274c | \ud83d\udfe1 | Not supported. Dedicated builds from source may work. Testing Needed. |\\n| OSX 10 and below | \u274c | \ud83d\udfe1 | 64-bit Only. Official builds have been reported to work on Catalina but not High Sierra |\\n| OSX 11 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 12 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| OSX 13 | \u2705 | \u2705 | 64-bit Only. Official builds supports both arm64 and x86 architectures. |\\n| Debian 11 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Debian 10 | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. |\\n| Debian 9 and below | \ud83d\udfe1 | \u2705 | 64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies. |\\n| Ubuntu 22.04 | \u2705 | \u2705 | 64-bit amd64 Only. |\\n| Other Ubuntu | \ud83d\udfe1 | \u2705 | 64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies. | \\n| CentOS | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Gentoo | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Arch | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Whonix | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support. ](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550) |\\n| Raspian (arm64) | \ud83d\udfe1 | \u2705 | Builds from source work. |\\n| Other Linux Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n| Android 9 and below | \ud83d\udfe1 | \ud83d\udfe1 | Official builds may work. |\\n| Android 10 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 11 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 12 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| Android 13 | \u2705 | \u2705 | Official SDK supprts arm, arm64, and amd64 architectures. |\\n| LineageOS | \ud83d\udfe1 | \ud83d\udfe1 | [Known Issues. Specific changes to Cwtch are required for support.](https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607) |\\n| Other Android Distributions | \ud83d\udfe1 | \ud83d\udfe1 | Testing Needed. |\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-bindings-reproducible","metadata":{"permalink":"/it/blog/cwtch-bindings-reproducible","source":"@site/blog/2023-01-20-reproducible-builds-bindings.md","title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","date":"2023-01-20T00:00:00.000Z","formattedDate":"20 gennaio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"reproducible-builds","permalink":"/it/blog/tags/reproducible-builds"},{"label":"bindings","permalink":"/it/blog/tags/bindings"},{"label":"repliqate","permalink":"/it/blog/tags/repliqate"}],"readingTime":7.915,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Making Cwtch Bindings Reproducible","description":"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.","slug":"cwtch-bindings-reproducible","tags":["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],"image":"/img/devlog3_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch UI Platform Support","permalink":"/it/blog/cwtch-platform-support"},"nextItem":{"title":"Cwtch Stable API Design","permalink":"/it/blog/cwtch-stable-api-design"}},"content":"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.\\n\\nBut open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.\\n\\nThe whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can **independently verify** that the binaries we release are built from the Cwtch source code.\\n\\nIn this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.\\n\\n\x3c!--truncate--\x3e\\n\\n## How Cwtch Bindings are Built\\n\\nSince we launched Cwtch Beta we have used Docker containers as part of our continuous build process.\\n\\nWhen a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.\\n\\nThe Cwtch Bindings build pipeline results in four compiled libraries:\\n\\n- **libcwtch.so** \u2013 For Linux Platforms, built using the [official golang:1.19.X Docker Image](https://hub.docker.com/_/golang)\\n- **libcwtch.dll** \u2013 For Windows Platforms, built using our own [mingw-go Docker Image](https://git.openprivacy.ca/openprivacy/mingw-go)\\n- **libcwtch.ld** \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)\\n- **cwtch.aar** \u2013 For Android Platforms, built using our own [Android/GoMobile Docker Image](https://git.openprivacy.ca/openprivacy/android-go-mobile)\\n\\nThese compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.\\n\\n## Making libCwtch Reproducible\\n\\nDocker containers alone aren\'t enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:\\n\\n* **Go Build ID**: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.\\n* **Build Paths and Go Environment Variables**: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the `trimPath` option, which we now specify for all bindings builds.\\n\\n### Linux Specific Considerations\\n\\nAfter the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.\\n\\nOur Drone/Docker build environments are based on [Debian Bullseye](https://www.debian.org/releases/bullseye/) which provides [libc6-dev version 2.31](https://packages.debian.org/bullseye/i386/libc6-dev). Other development setups will likely link libc-dev 2.34+.\\n\\nlibc6-dev 2.34 is notable [because it removed dependencies on libpthread and libdl](https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread) \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.\\n\\nThis means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on [Next Steps](#next-steps) for more information).\\n\\n### Windows Specific Considerations\\n\\nThe headers of PE files technically contain a timestamp field. In recent years an [effort has been made to use this field for other purposes](https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705), but by default `go build` will still include the timestamp of the file when producing a DLL file (at least when using CGO).\\n\\nFortunately this field can be zeroed out through passing `-Xlinker \u2013no-insert-timestamp` into the `mingw32-gcc` process.\\n\\nWith that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.\\n\\n\\n### Android Specific Considerations\\n\\nWith the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:\\n\\n* Cwtch makes use of [GoMobile](https://github.com/golang/mobile) for compiling Android libraries. We pin to a specific version `43a0384520996c8376bfb8637390f12b44773e65` in our Docker containers. Unlike `go build`, the `trimpPath` parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized `/tmp/go-build*` references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.\\n* We still use [sdk-tools](https://developer.android.com/studio/releases/sdk-tools) instead of the new [commandline-tools](https://developer.android.com/studio/command-line). The latest version of sdk-tools is `4333796` and available from: [https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip](https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip). As part of our plans for Cwtch Stable we will be updating this dependency.\\n* Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated `openjdk:8` image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. \\n\\nAll of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.\\n\\n### OSX Specific Considerations\\n\\nPerhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.\\n\\nAs with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.\\n\\nIn order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.\\n\\nIn an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a [proprietary SDK](https://www.apple.com/legal/sla/docs/xcode.pdf). There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.\\n\\nBecause of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.\\n\\n## Introducing Repliqate!\\n\\nWith all the above changes, **Cwtch Bindings for Linux and Windows are fully reproducible!**\\n\\nThat alone is great, but we also want to make it easier for **you** to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.\\n\\nTo make this process accessible we are releasing a new tool called [repliqate](https://git.openprivacy.ca/openprivacy/repliqate).\\n\\nRepliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.\\n\\nRepliqate runs [build-scripts](https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script) to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from [builds.openprivacy.ca](https://build.openprivacy.ca/files/).\\n\\nWe now provide [Repliqate build-scripts](https://git.openprivacy.ca/cwtch.im/repliqate-scripts) for reproducible both [Linux libCwtch.so builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script), [Windows libCwtch.dll builds](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script)!\\n\\nWe also have a partially repeatable [Android cwtch.aar build](https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script) script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.\\n\\nYou can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.\\n\\n## Next Steps\\n\\nReproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.\\n\\nAs we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"},{"id":"cwtch-stable-api-design","metadata":{"permalink":"/it/blog/cwtch-stable-api-design","source":"@site/blog/2023-01-13-cwtch-stable-api-design.md","title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","date":"2023-01-13T00:00:00.000Z","formattedDate":"13 gennaio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/it/blog/tags/planning"},{"label":"api","permalink":"/it/blog/tags/api"}],"readingTime":17.28,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Cwtch Stable API Design","description":"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ","slug":"cwtch-stable-api-design","tags":["cwtch","cwtch-stable","planning","api"],"image":"/img/devlog2_small.png","hide_table_of_contents":false,"toc_max_heading_level":4,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Making Cwtch Bindings Reproducible","permalink":"/it/blog/cwtch-bindings-reproducible"},"nextItem":{"title":"Path to Cwtch Stable","permalink":"/it/blog/path-to-cwtch-stable"}},"content":"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. \\n\\nAs we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.\\n\\nAs we move out of Beta and [towards Cwtch Stable](https://docs.cwtch.im/blog/path-to-cwtch-stable) it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.\\n\\nIn this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.\\n\\n![](/img/devlog2.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Clarifying Terminology\\n\\nOver the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:\\n\\n- **Cwtch** refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. \\n- **Cwtchlib** refers to the [reference implementation of the Cwtch Protocol](https://git.openprivacy.ca/cwtch.im/cwtch) / Application framework, currently written in Go.\\n- **Bindings** refers to C/Java/Kotlin/Rust bindings (primarily [libcwtch-go](https://git.openprivacy.ca/cwtch.im/libcwtch-go)) that act as an interface between Cwtchlib and downstream applications.\\n- `CwtchPeer` is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).\\n- `ProtocolEngine` is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, `ProtocolEngine` is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.\\n\\n\\n### Tenets of the Cwtch API Design\\n\\nBased on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:\\n\\n- **Robustness** - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.\\n- **Completeness** - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.\\n- **Security** \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.\\n\\n### The Cwtch Experiment Landscape\\n\\nA summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.\\n\\n- **Groups** \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized `ProtocolEngine` functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. \\n - **Hybrid Groups** - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.\\n- **Filesharing** \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in `ProtocolEngine`.\\n- **Profile Images** \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.\\n- **Server Hosting** \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.\\n- **Message Formatting** \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history\\n- **Search / Microblogging** \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.\\n- **Status / Profile Metadata** \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.\\n\\n### The Problem with Experiments\\n\\nWe have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the `SendMessages` interface that only allows callers to send messages.\\n\\nWe have also worked to package experimental functionality into so-called **Gated Functionalities** that are only available if a given experiment is turned on.\\n\\nTogether, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:\\n\\n- The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. `SendMessages` \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).\\n- The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.\\n- This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.\\n\\n### Restricting Powerful Cwtch APIs\\n\\nTo carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:\\n\\n- Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through `Application` and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.\\n- Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a `RestrictedCwtchConversationInterface` which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact.\\n- Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow `CwtchPeer` to control which experiments get access to which events at a given time.\\n\\n#### Pre-Registered Hooks\\n\\nIn order to implement certain functionality actions need to take place in-between events handled by `CwtchPeer`. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).\\n\\nThis is currently only possible with invasive changes to the `CwtchPeer` interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.\\n\\nWe are introducing a new set of Cwtch APIs designed for this purpose:\\n\\n- `OnNewPeerMessage` - hooked prior to inserting the message into the database.\\n- `OnPeerMessageConfirmed` \u2013 hooked after a peer message has been inserted into the database.\\n- `OnEncryptedGroupMessage` \u2013 hooked after receiving an encrypted message from a group server.\\n- `OnGroupMessageReceived` \u2013 hooked after a successful decryption of a group message, but before inserting it into the database.\\n- `OnContactRequestValue` \u2013 hooked on request of a scoped (the permission level of the attribute e.g. `public` or `conversation` level attributes), zoned ( relating to a specific feature e.g. `filesharing` or `chat`), and keyed (the name of the attribute e.g. `name` or `manifest`) value from a contact.\\n- `OnContactReceiveValue` \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.\\n\\nIncluding the following APIs for managing hooked functionality:\\n\\n- `RegisterEvents` - returns a set of events that the extension is interested processing.\\n- `RegisterExperiments` - returns a set of experiments that the extension is interested in being notified about\\n- `OnEvent` - to be called by `CwtchPeer` whenever an event registered with `RegisterEvents` is called (assuming all experiments registered through `RegisterExperiments` is active)\\n\\n#### `ProtocolEngine` Subsystems\\n\\nAs mentioned in our experiment summary, some functionality needs to be implemented directly in the `ProtocolEngine`. The `ProtocolEngine` is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).\\n\\nSome types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a `ProtocolEngine`.\\n\\nAt the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to `ProtocolEngine` that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider `ProtocolEngine` ecosystem. \\n\\nWe are formalizing this subsystem into an interface, similar to the hooked functionality in `CwtchPeer`:\\n\\n- `RegisterEvents` - returns a set of events that the subsystem needs to consume to operate.\\n- `OnEvent` \u2013 to be called by `ProtocolEngine` whenever an event registered with `RegisterEvents` is called (when all the experiments registered through `RegisterExperiments` are active)\\n- `RegisterContexts` - returns the set of contexts that the subsystem implements e.g. `im.cwtch.filesharing`\\n\\nThis also requires a formalization of two *engine specific* events (for use on the event bus):\\n\\n- `SendCwtchMessage` \u2013 encapsulating the existing `CwtchPeerMessage` that is used internally in `ProtocolEngine` for messages between subsystems.\\n- `CwtchMessageReceived` \u2013 encapsulating the existing `handlePeerMessage` function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.\\n\\nAnd the introduction of three **additional** `ProtocolEnine` specific events:\\n\\n- `StartEngineSubsystem` \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.\\n- `StopEngineSubsystem` \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.\\n- `SubsystemStatus` \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging\\n\\nThis will allow us to move the following functionality, currently part of `ProtocolEngine` itself, into generic subsystems:\\n\\n- **Attribute Lookup Handling** - this functionality is currently part of the overloaded `handlePeerMessage` function, filtered using the `Context` parameter of the `CwtchPeerMessage`. As such it can be entirely delegated to a subsystem. \\n- **Filesharing Chunk Request Handling** \u2013 this is also part of handlePeerMessage, also filtered using the `Context` parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by `handlePeerMessage`)\\n- **Filesharing Start File Share/Stop File Share** \u2013 this is currently part of the `handleEvent` behaviour of `ProtocolEngine` and can be moved into an `OnEvent` handler of the file sharing subsystem (where such events are already processed).\\n\\nThe introduction of pre-registered hooks in combination with the formalizations of `ProtocolEngine` subsystems will allow the follow functionality, currently implemented in `CwtchPeer` or libcwtch-go to be moved to standalone packages:\\n\\n- **Filesharing** makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. \\n - Filesharing also depends on the file sharing subsystem to be enabled in a `ProtocolEngine`. This subsystem is responsible for processing chunk requests.\\n- **Profile Images** \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)\\n- **Legacy Groups** \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.\\n- **Status/Profile Metadata** \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.\\n \\n#### Impact on Enabling (Powerful) New Functionality\\n\\nNone of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:\\n\\n- **Search** \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.\\n- **Non Chat Conversation Contexts** - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.\\n\\n## Application Experiments\\n\\nOne kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers.\\n\\nThis kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library.\\n\\nThis functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.\\n\\n## Bindings\\n\\nThe last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.\\n\\nWe can split the bindings into four core areas:\\n\\n- **Application Management** - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.\\n- **Application Experiments** - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.\\n- **Core Profile Management** - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.\\n- **Experimental Profile Features** \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.\\n\\nThe flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.\\n\\nIn an ideal future, all of these bindings could be **generated automatically** from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)\\n\\nWe can define three types of C/Java/Kotlin interface function templates:\\n\\n- `ProfileMethodName(profilehandle String, args...)` \u2013 which directly resolves the Cwtch Profile and calls the function.\\n- `ProfileExperimentalMethodName(profilehandle String, args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.\\n- `ApplicationExperimentalMethodName(args...)` \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.\\n\\nAll we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context `ProfileInterface` for the first, exported methods of the various `Functionalities` for the second, and `ApplicationExperiment` definitions for the third.\\n\\n## Timelines and Next Actions\\n\\n- **Freeze any changes to the bindings interface** - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib.\\n- As part of Cwtch 1.11 and 1.12 Release Cycles\\n - Implement the `ProtocolEngine` Subsystem Design as outlined above.\\n - Implement the Hooks API.\\n - Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting).\\n - Move event handling from the bindings into Application.\\n - Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions.\\n- Once Automated UI Tests have been integrated into the Cwtch UI Repository:\\n - Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings **and** a dart calling convention library from cwtchlib and any configured application experiments libraries\\n - Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).\\n - At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.\\n\\nAs these changes are made, and these goals met we will be posting about them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, all Cwtch development.\\n\\n## Help us go further!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position to, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)\\n\\n## Appendix A: Special Behaviour Defined by libcwtch-go\\n\\nThe following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:\\n\\n- Application Settings\\n - Including Enabling / Disabling Experiment\\n- ACN Process Management - starting/stopping/restarting/configuring Tor.\\n- Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)\\n- Logging Levels - configuring appropriate logging levels (e.g. `INFO` or `DEBUG`)\\n- Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.\\n- UI Contact Structures - aggregating contact information for the main Cwtch UI.\\n- Group Experiment Functionality\\n - Experiment Gating\\n - GetServerInfoList\\n - GetServerInfo\\n - UI Server Struct Definition\\n- Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.\\n- \\"Unencrypted\\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \\"unencrypted\\".\\n- Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).\\n- Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.\\n- Cwtch Profile Engine Activation - starting/stopping a `ProtocolEngine` when requested by the UI, or in response to changes in ACN state.\\n- UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.\\n- File sharing restarts \\n- UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn\'t directly embedded within the event (e.g. converting `handle` to a `conversation id`). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.\\n- Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)"},{"id":"path-to-cwtch-stable","metadata":{"permalink":"/it/blog/path-to-cwtch-stable","source":"@site/blog/2023-01-06-path-to-cwtch-stable.md","title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","date":"2023-01-06T00:00:00.000Z","formattedDate":"6 gennaio 2023","tags":[{"label":"cwtch","permalink":"/it/blog/tags/cwtch"},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable"},{"label":"planning","permalink":"/it/blog/tags/planning"}],"readingTime":9.995,"hasTruncateMarker":true,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}],"frontMatter":{"title":"Path to Cwtch Stable","description":"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.","slug":"path-to-cwtch-stable","tags":["cwtch","cwtch-stable","planning"],"image":"/img/devlog1_small.jpg","hide_table_of_contents":false,"authors":[{"name":"Sarah Jamie Lewis","title":"Executive Director, Open Privacy Research Society","image_url":"/img/sarah.jpg","imageURL":"/img/sarah.jpg"}]},"prevItem":{"title":"Cwtch Stable API Design","permalink":"/it/blog/cwtch-stable-api-design"}},"content":"As of December 2022 we have released 10 versions of Cwtch Beta since the [initial launch, 18 months ago, in June 2021](https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/).\\n\\nThere is a consensus among the team that the next large step for the Cwtch project to take is a move from public **Beta** to **Stable** \u2013 marking a point at which we consider Cwtch to be secure and usable.\\n\\nThis post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.\\n\\n![](/img/devlog1.png)\\n\\n\x3c!--truncate--\x3e\\n\\n### Tenets of Cwtch Stable\\n\\nIt is important to state that Cwtch Stable **does not mean an end to Cwtch development**. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:\\n\\n1. **Consistent Interface** \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.\\n2. **Universal Availability and Cohesive Support** \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\\n3. **Reproducible Builds** \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.\\n4. **Proven Security** \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.\\n\\n### Known Problems\\n\\nTo begin, let\'s outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.\\n\\n1. **Lack of a Stable API for future feature development** \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)\\n2. **Special functionality in libCwtch-go** \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)\\n3. **libCwtch-rs partial support** - we currently do not officially consider [libCwtch-rs](https://lib.rs/crates/libcwtch) when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)\\n4. **Lack of Reproducible Pipelines** - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)\\n5. **Lack of up to date, and translated, Security Documentation** \u2013 the [Cwtch security handbook](https://docs.openprivacy.ca/cwtch-security-handbook/) is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)\\n6. **No Automated UI Tests** \u2013 we put a lot of work into [building out a testing framework for the UI](https://openprivacy.ca/discreet-log/23-cucumber-testing/), but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)\\n7. **Code Signing Provider** \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)\\n8. **Second-class Android Support** - while we have put [a lot of effort behind Android support](https://openprivacy.ca/discreet-log/27-android-improvements/) across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)\\n9. **Lack of Fuzzing** \u2013 while [Fuzzbot](https://openprivacy.ca/discreet-log/07-fuzzbot/) sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)\\n10. **Lack of Formal Release Acceptance Process** \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)\\n11. **Inconsistent Cwtch Information Discovery** \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)\\n12. **Incomplete Documentation** \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)\\n\\n### Plan of Action\\n\\nOutside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:\\n\\n1. **Define, Publish, and Implement a Cwtch Interface Specification Documentation** \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)\\n2. **Define, Publish, and Implement a Cwtch Release Process** \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)\\n3. **Define, Publish, and Implement a Cwtch Support Document** - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)\\n4. **Define, Publish, and Implement a Cwtch Packaging Document** - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)\\n5. **Define, Publish, and Implement a Reproducible Builds Document** \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)\\n6. **Expand the Cwtch Documentation Site** \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)\\n7. **Expand our Automated Testing to include UI and Fuzzing** - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)\\n8. **Re-evaluate all Issues across all Cwtch related repositories** \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.\\n9. **Define a Stable Feature Set** \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)\\n\\n### Goals and Timelines\\n\\nWith all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:\\n\\n1. By **1st February 2023**, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).\\n2. By **1st February 2023**, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.\\n3. By **1st February 2023**, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.\\n4. By **31st March 2023**, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).\\n5. By **31st March 2023** the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.\\n6. By **31st March 2023** the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.\\n7. By **31st March 2023** the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.\\n8. By **31st March 2023** the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.\\n\\nAs these documents are written, and these goals met we will be posting them here! Subscribe to our [RSS feed](/blog/rss.xml), [Atom feed](/blog/atom.xml), or [JSON feed](/blog/feed.json) to stay up to date, and get the latest on, Cwtch development.\\n\\n### Help us get there!\\n\\nWe couldn\'t do what we do without all the wonderful community support we get, from [one-off donations](https://openprivacy.ca/donate) to [recurring support via Patreon](https://www.patreon.com/openprivacy).\\n\\nIf you want to see us move faster on some of these goals and are in a position, please [donate](https://openprivacy.ca/donate). If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.\\n\\nDonations of **$5 or more** can opt to receive stickers as a thank-you gift!\\n\\nFor more information about donating to Open Privacy and claiming a thank you gift [please visit the Open Privacy Donate page](https://openprivacy.ca/donate/).\\n\\n![A Photo of Cwtch Stickers](/img/stickers-new.jpg)"}]}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0b5b83c5.62502289.js b/build-staging/it/assets/js/0b5b83c5.62502289.js new file mode 100644 index 00000000..bce17032 --- /dev/null +++ b/build-staging/it/assets/js/0b5b83c5.62502289.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9207],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>b});var r=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;e=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var l=r.createContext({}),c=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},p=function(t){var e=c(t.components);return r.createElement(l.Provider,{value:e},t.children)},f="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var n=t.components,i=t.mdxType,o=t.originalType,l=t.parentName,p=s(t,["components","mdxType","originalType","parentName"]),f=c(n),d=i,b=f["".concat(l,".").concat(d)]||f[d]||u[d]||o;return n?r.createElement(b,a(a({ref:e},p),{},{components:n})):r.createElement(b,a({ref:e},p))}));function b(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var o=n.length,a=new Array(o);a[0]=d;var s={};for(var l in e)hasOwnProperty.call(e,l)&&(s[l]=e[l]);s.originalType=t,s[f]="string"==typeof t?t:i,a[1]=s;for(var c=2;c{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:15},a="Setting Profile Attributes",s={unversionedId:"profiles/profile-info",id:"profiles/profile-info",title:"Setting Profile Attributes",description:"This functionality is currently only available in the Nightly Release builds of Cwtch.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/profile-info.md",sourceDirName:"profiles",slug:"/profiles/profile-info",permalink:"/it/docs/profiles/profile-info",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/profile-info.md",tags:[],version:"current",sidebarPosition:15,frontMatter:{sidebar_position:15},sidebar:"tutorialSidebar",previous:{title:"Setting Availability Status",permalink:"/it/docs/profiles/availability-status"},next:{title:"Conversations",permalink:"/it/docs/category/conversations"}},l={},c=[],p={toc:c},f="wrapper";function u(t){let{components:e,...o}=t;return(0,i.kt)(f,(0,r.Z)({},p,o,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-profile-attributes"},"Setting Profile Attributes"),(0,i.kt)("admonition",{title:"Nightly Feature",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This functionality is currently ",(0,i.kt)("strong",{parentName:"p"},"only")," available in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly Release")," builds of Cwtch."),(0,i.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,i.kt)("p",null,"On the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/introduction#manage-profiles"},"profile management pane")," there are three free-form text fields below your profile picture."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(92).Z},(0,i.kt)("img",{src:n(6852).Z,width:"783",height:"354"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"You can fill these fields with any information your would like potential contacts to know. ",(0,i.kt)("strong",{parentName:"p"},"This information is public")," - do not put any information in here that you do not want to share with everyone."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(2243).Z},(0,i.kt)("img",{src:n(3506).Z,width:"730",height:"342"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Contacts will be able to see this information in ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/conversation-settings"},"conversation settings")),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(5637).Z},(0,i.kt)("img",{src:n(136).Z,width:"294",height:"195"}))),(0,i.kt)("figcaption",null)))}u.isMDXComponent=!0},5637:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/files/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},92:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/files/attributes-empty-3df496b84657bd88e590c245671de191.png"},2243:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},136:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/images/attributes-contact-4ba7fccff01d2995a47b45098a47ef93.png"},6852:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/images/attributes-empty-3df496b84657bd88e590c245671de191.png"},3506:(t,e,n)=>{n.d(e,{Z:()=>r});const r=n.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0bb12077.7852f71b.js b/build-staging/it/assets/js/0bb12077.7852f71b.js new file mode 100644 index 00000000..bb5037d2 --- /dev/null +++ b/build-staging/it/assets/js/0bb12077.7852f71b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8697],{6735:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/cwtch-stable","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/it/blog/tags/cwtch-stable/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0d59ece6.08931564.js b/build-staging/it/assets/js/0d59ece6.08931564.js new file mode 100644 index 00000000..65cbbc12 --- /dev/null +++ b/build-staging/it/assets/js/0d59ece6.08931564.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5490],{8731:e=>{e.exports=JSON.parse('{"title":"Connectivity & Tor","slug":"/category/connectivity--tor","permalink":"/it/security/category/connectivity--tor","navigation":{"previous":{"title":"Component Ecosystem Overview","permalink":"/it/security/components/ecosystem-overview"},"next":{"title":"Connectivity","permalink":"/it/security/components/connectivity/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0d64c1d9.640c15f3.js b/build-staging/it/assets/js/0d64c1d9.640c15f3.js new file mode 100644 index 00000000..bc48a486 --- /dev/null +++ b/build-staging/it/assets/js/0d64c1d9.640c15f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8710],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>b});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function r(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):r(r({},t),e)),i},d=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(i),h=a,b=p["".concat(s,".").concat(h)]||p[h]||u[h]||o;return i?n.createElement(b,r(r({ref:t},d),{},{components:i})):n.createElement(b,r({ref:t},d))}));function b(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=i.length,r=new Array(o);r[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=i(7462),a=(i(7294),i(3905));const o={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/it/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"20 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/it/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"repliqate",permalink:"/it/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/it/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/it/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"How Cwtch Bindings are Built",id:"how-cwtch-bindings-are-built",level:2},{value:"Making libCwtch Reproducible",id:"making-libcwtch-reproducible",level:2},{value:"Linux Specific Considerations",id:"linux-specific-considerations",level:3},{value:"Windows Specific Considerations",id:"windows-specific-considerations",level:3},{value:"Android Specific Considerations",id:"android-specific-considerations",level:3},{value:"OSX Specific Considerations",id:"osx-specific-considerations",level:3},{value:"Introducing Repliqate!",id:"introducing-repliqate",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...o}=e;return(0,a.kt)(p,(0,n.Z)({},d,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,a.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,a.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,a.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,a.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."),(0,a.kt)("h2",{id:"how-cwtch-bindings-are-built"},"How Cwtch Bindings are Built"),(0,a.kt)("p",null,"Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process."),(0,a.kt)("p",null,"When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms."),(0,a.kt)("p",null,"The Cwtch Bindings build pipeline results in four compiled libraries:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.so")," \u2013 For Linux Platforms, built using the ",(0,a.kt)("a",{parentName:"li",href:"https://hub.docker.com/_/golang"},"official golang:1.19.X Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.dll")," \u2013 For Windows Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/mingw-go"},"mingw-go Docker Image")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"libcwtch.ld")," \u2013 For OSX Platforms, built using our dedicated OSX build server (Big Sur 11.6.1)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"cwtch.aar")," \u2013 For Android Platforms, built using our own ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/android-go-mobile"},"Android/GoMobile Docker Image"))),(0,a.kt)("p",null,"These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI."),(0,a.kt)("h2",{id:"making-libcwtch-reproducible"},"Making libCwtch Reproducible"),(0,a.kt)("p",null,"Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Go Build ID"),": By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Build Paths and Go Environment Variables"),": By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary \u2013 ostensibly to aid with debugging. These can be removed using the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimPath")," option, which we now specify for all bindings builds.")),(0,a.kt)("h3",{id:"linux-specific-considerations"},"Linux Specific Considerations"),(0,a.kt)("p",null,"After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against."),(0,a.kt)("p",null,"Our Drone/Docker build environments are based on ",(0,a.kt)("a",{parentName:"p",href:"https://www.debian.org/releases/bullseye/"},"Debian Bullseye")," which provides ",(0,a.kt)("a",{parentName:"p",href:"https://packages.debian.org/bullseye/i386/libc6-dev"},"libc6-dev version 2.31"),". Other development setups will likely link libc-dev 2.34+."),(0,a.kt)("p",null,"libc6-dev 2.34 is notable ",(0,a.kt)("a",{parentName:"p",href:"https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread"},"because it removed dependencies on libpthread and libdl")," \u2013 neither are used in libCwtch, but they are currently referenced \u2013 which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file."),(0,a.kt)("p",null,"This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on ",(0,a.kt)("a",{parentName:"p",href:"#next-steps"},"Next Steps")," for more information)."),(0,a.kt)("h3",{id:"windows-specific-considerations"},"Windows Specific Considerations"),(0,a.kt)("p",null,"The headers of PE files technically contain a timestamp field. In recent years an ",(0,a.kt)("a",{parentName:"p",href:"https://devblogs.microsoft.com/oldnewthing/20180103-00/?p=97705"},"effort has been made to use this field for other purposes"),", but by default ",(0,a.kt)("inlineCode",{parentName:"p"},"go build")," will still include the timestamp of the file when producing a DLL file (at least when using CGO)."),(0,a.kt)("p",null,"Fortunately this field can be zeroed out through passing ",(0,a.kt)("inlineCode",{parentName:"p"},"-Xlinker \u2013no-insert-timestamp")," into the ",(0,a.kt)("inlineCode",{parentName:"p"},"mingw32-gcc")," process."),(0,a.kt)("p",null,"With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment."),(0,a.kt)("h3",{id:"android-specific-considerations"},"Android Specific Considerations"),(0,a.kt)("p",null,"With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Cwtch makes use of ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/golang/mobile"},"GoMobile")," for compiling Android libraries. We pin to a specific version ",(0,a.kt)("inlineCode",{parentName:"li"},"43a0384520996c8376bfb8637390f12b44773e65")," in our Docker containers. Unlike ",(0,a.kt)("inlineCode",{parentName:"li"},"go build"),", the ",(0,a.kt)("inlineCode",{parentName:"li"},"trimpPath")," parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized ",(0,a.kt)("inlineCode",{parentName:"li"},"/tmp/go-build*")," references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced."),(0,a.kt)("li",{parentName:"ul"},"We still use ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/releases/sdk-tools"},"sdk-tools")," instead of the new ",(0,a.kt)("a",{parentName:"li",href:"https://developer.android.com/studio/command-line"},"commandline-tools"),". The latest version of sdk-tools is ",(0,a.kt)("inlineCode",{parentName:"li"},"4333796")," and available from: ",(0,a.kt)("a",{parentName:"li",href:"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"},"https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip"),". As part of our plans for Cwtch Stable we will be updating this dependency."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated ",(0,a.kt)("inlineCode",{parentName:"li"},"openjdk:8")," image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency. ")),(0,a.kt)("p",null,"All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles."),(0,a.kt)("h3",{id:"osx-specific-considerations"},"OSX Specific Considerations"),(0,a.kt)("p",null,"Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds."),(0,a.kt)("p",null,"As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine."),(0,a.kt)("p",null,"In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1."),(0,a.kt)("p",null,"In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a ",(0,a.kt)("a",{parentName:"p",href:"https://www.apple.com/legal/sla/docs/xcode.pdf"},"proprietary SDK"),". There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware."),(0,a.kt)("p",null,"Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions."),(0,a.kt)("h2",{id:"introducing-repliqate"},"Introducing Repliqate!"),(0,a.kt)("p",null,"With all the above changes, ",(0,a.kt)("strong",{parentName:"p"},"Cwtch Bindings for Linux and Windows are fully reproducible!")),(0,a.kt)("p",null,"That alone is great, but we also want to make it easier for ",(0,a.kt)("strong",{parentName:"p"},"you")," to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team."),(0,a.kt)("p",null,"To make this process accessible we are releasing a new tool called ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate"),"."),(0,a.kt)("p",null,"Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution."),(0,a.kt)("p",null,"Repliqate runs ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate#writing-a-build-script"},"build-scripts")," to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"builds.openprivacy.ca"),"."),(0,a.kt)("p",null,"We now provide ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"Repliqate build-scripts")," for reproducible both ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-linux.script"},"Linux libCwtch.so builds"),", ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-windows.script"},"Windows libCwtch.dll builds"),"!"),(0,a.kt)("p",null,"We also have a partially repeatable ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/libcwtch.v1.10.2-android.script"},"Android cwtch.aar build")," script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section."),(0,a.kt)("p",null,"You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings."),(0,a.kt)("p",null,"As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!"),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4515:(e,t,i)=>{i.d(t,{Z:()=>n});const n=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/0fb199c9.6c1937b9.js b/build-staging/it/assets/js/0fb199c9.6c1937b9.js new file mode 100644 index 00000000..66a72c35 --- /dev/null +++ b/build-staging/it/assets/js/0fb199c9.6c1937b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5221],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,o(o({ref:t},p),{},{components:n})):r.createElement(m,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,o[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={sidebar_position:1},o="Running Cwtch on Tails",s={unversionedId:"platforms/tails",id:"platforms/tails",title:"Running Cwtch on Tails",description:"This functionality is currently only available in the Nightly Release builds of Cwtch.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/platforms/tails.md",sourceDirName:"platforms",slug:"/platforms/tails",permalink:"/it/docs/platforms/tails",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/platforms/tails.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Platforms",permalink:"/it/docs/category/platforms"}},c={},l=[{value:"Onion Grater Configuration",id:"onion-grater-configuration",level:2},{value:"Persistence",id:"persistence",level:2}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"running-cwtch-on-tails"},"Running Cwtch on Tails"),(0,a.kt)("admonition",{title:"Nightly Feature",type:"warning"},(0,a.kt)("p",{parentName:"admonition"},"This functionality is currently ",(0,a.kt)("strong",{parentName:"p"},"only")," available in the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly Release")," builds of Cwtch."),(0,a.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,a.kt)("p",null,"The following steps require that Tails has been launched with an ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/first_steps/welcome_screen/administration_password/"},"Administration Password"),"."),(0,a.kt)("p",null,"Tails uses ",(0,a.kt)("a",{parentName:"p",href:"https://gitlab.tails.boum.org/tails/tails/-/blob/master/config/chroot_local-includes/usr/local/lib/onion-grater#L3"},"Onion Grater")," to guard access to the control port. We have packaged an oniongrater configuration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," and setup script (",(0,a.kt)("inlineCode",{parentName:"p"},"install-tails.sh"),") with Cwtch on Linux."),(0,a.kt)("p",null,"The tails-specific part of the script is reproduced below:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," # Tails needs to be have been setup up with an Administration account\n # \n # Make Auth Cookie Readable\n sudo chmod o+r /var/run/tor/control.authcookie\n # Copy Onion Grater Config\n sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml\n # Restart Onion Grater so the Config Takes effect\n sudo systemctl restart onion-grater.service\n")),(0,a.kt)("p",null,"When launching, Cwtch on Tails should be passed the ",(0,a.kt)("inlineCode",{parentName:"p"},"CWTCH_TAILS=true")," environment variable to automatically configure Cwtch for running in a Tails-like environment:"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch")),(0,a.kt)("admonition",{title:"Install Location",type:"info"},(0,a.kt)("p",{parentName:"admonition"},"The above command, and the below onion grater configuration assume that Cwtch was installed in ",(0,a.kt)("inlineCode",{parentName:"p"},"~/.local/lib/cwtch/cwtch")," - if Cwtch was installed somewhere else (or if you are running directly from the download folder) then you will need to adjust the commands.")),(0,a.kt)("h2",{id:"onion-grater-configuration"},"Onion Grater Configuration"),(0,a.kt)("p",null,"The oniongrater configuration ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/linux/cwtch-tails.yml"},(0,a.kt)("inlineCode",{parentName:"a"},"cwtch-tails.yml")," ")," is reproduced below. As noted this configuration is can likely be restricted much further. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," ---\n # TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern\n\n - apparmor-profiles:\n - '/home/amnesia/.local/lib/cwtch/cwtch'\n users:\n\n - 'amnesia'\n commands:\n AUTHCHALLENGE:\n\n - 'SAFECOOKIE .*'\n SETEVENTS:\n\n - 'CIRC WARN ERR'\n - 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'\n GETINFO:\n\n - '.*'\n GETCONF:\n\n - 'DisableNetwork'\n SETCONF:\n\n - 'DisableNetwork.*'\n ADD_ONION:\n\n - '.*'\n DEL_ONION:\n\n - '.+'\n HSFETCH:\n\n - '.+'\n events:\n CIRC:\n suppress: true\n ORCONN:\n suppress: true\n INFO:\n suppress: true\n NOTICE:\n suppress: true\n WARN:\n suppress: true\n ERR:\n suppress: true\n HS_DESC:\n response:\n\n - pattern: '650 HS_DESC CREATED (\\S+) (\\S+) (\\S+) \\S+ (.+)'\n replacement: '650 HS_DESC CREATED {} {} {} redacted {}'\n\n - pattern: '650 HS_DESC UPLOAD (\\S+) (\\S+) .*'\n replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'\n\n - pattern: '650 HS_DESC UPLOADED (\\S+) (\\S+) .+'\n replacement: '650 HS_DESC UPLOADED {} {} redacted'\n\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH'\n\n - pattern: '650 HS_DESC REQUESTED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'\n\n - pattern: '650 HS_DESC RECEIVED (\\S+) NO_AUTH \\S+ \\S+'\n replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'\n\n - pattern: '.*'\n replacement: ''\n HS_DESC_CONTENT:\n suppress: true\n")),(0,a.kt)("h2",{id:"persistence"},"Persistence"),(0,a.kt)("p",null,"By default, Cwtch creates ",(0,a.kt)("inlineCode",{parentName:"p"},"$HOME/.cwtch")," and saves all encrypted profiles and settings files there. In order to save any profiles/conversations in Cwtch on Tails you will have to backup this folder to a non-volatile home."),(0,a.kt)("p",null,"See the Tails documentation for setting up ",(0,a.kt)("a",{parentName:"p",href:"https://tails.boum.org/doc/persistent_storage/"},"persistent storage")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/115541e2.64566ecd.js b/build-staging/it/assets/js/115541e2.64566ecd.js new file mode 100644 index 00000000..48f3018b --- /dev/null +++ b/build-staging/it/assets/js/115541e2.64566ecd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2450],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=i,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:3},a="Come modificare un server",s={unversionedId:"servers/edit-server",id:"servers/edit-server",title:"Come modificare un server",description:"Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/edit-server.md",sourceDirName:"servers",slug:"/servers/edit-server",permalink:"/it/docs/servers/edit-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/edit-server.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Come creare un server",permalink:"/it/docs/servers/create-server"},next:{title:"Come eliminare un server",permalink:"/it/docs/servers/delete-server"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"come-modificare-un-server"},"Come modificare un server"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l' ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Esperimento di server hosting")," attivato."),(0,i.kt)("p",null,":::"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Vai all'icona del server"),(0,i.kt)("li",{parentName:"ol"},"Seleziona il server che vuoi modificare"),(0,i.kt)("li",{parentName:"ol"},"Clicca sull'icona della matita"),(0,i.kt)("li",{parentName:"ol"},"Cambia la descrizione / abilita o disabilita il server"),(0,i.kt)("li",{parentName:"ol"},'Clicca su "Salva server"')),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/server_edit.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/11796dfe.c8f1e93b.js b/build-staging/it/assets/js/11796dfe.c8f1e93b.js new file mode 100644 index 00000000..bdc7a514 --- /dev/null +++ b/build-staging/it/assets/js/11796dfe.c8f1e93b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2033],{5761:e=>{e.exports=JSON.parse('{"label":"release","permalink":"/it/blog/tags/release","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/13965eb4.7c9d96d5.js b/build-staging/it/assets/js/13965eb4.7c9d96d5.js new file mode 100644 index 00000000..b0905709 --- /dev/null +++ b/build-staging/it/assets/js/13965eb4.7c9d96d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[80],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),s=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=s(e.components);return i.createElement(l.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(n),d=r,m=u["".concat(l,".").concat(d)]||u[d]||f[d]||o;return n?i.createElement(m,a(a({ref:t},p),{},{components:n})):i.createElement(m,a({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,a=new Array(o);a[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:r,a[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var i=n(7462),r=(n(7294),n(3905));const o={sidebar_position:2},a="Policy di notifica",c={unversionedId:"settings/behaviour/notification-policy",id:"settings/behaviour/notification-policy",title:"Policy di notifica",description:"1. Vai alle impostazioni",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/behaviour/notification-policy.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-policy",permalink:"/it/docs/settings/behaviour/notification-policy",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-policy.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Blocca connessioni sconosciute",permalink:"/it/docs/settings/behaviour/block-unknown-connections"},next:{title:"Contenuto notifica",permalink:"/it/docs/settings/behaviour/notification-content"}},l={},s=[],p={toc:s},u="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"policy-di-notifica"},"Policy di notifica"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Vai alle impostazioni"),(0,r.kt)("li",{parentName:"ol"},'Scorri fino a "comportamento"'),(0,r.kt)("li",{parentName:"ol"},"La policy di notifica controlla il comportamento delle notifiche"),(0,r.kt)("li",{parentName:"ol"},'Clicca su "Predefinita" per modificare il comportamento per attivare o per disabilitare tutte le notifiche'),(0,r.kt)("li",{parentName:"ol"},"Scegli la tua policy di notifica preferita")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/141cdfa9.d8dc748d.js b/build-staging/it/assets/js/141cdfa9.d8dc748d.js new file mode 100644 index 00000000..2a7f0765 --- /dev/null +++ b/build-staging/it/assets/js/141cdfa9.d8dc748d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7293],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>h});var r=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,i=e.mdxType,n=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(a),m=i,h=u["".concat(c,".").concat(m)]||u[m]||f[m]||n;return a?r.createElement(h,o(o({ref:t},p),{},{components:a})):r.createElement(h,o({ref:t},p))}));function h(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var n=a.length,o=new Array(n);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:i,o[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>n,metadata:()=>l,toc:()=>s});var r=a(7462),i=(a(7294),a(3905));const n={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"6 aprile 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/it/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/it/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/it/blog/cwtch-stable-roadmap-update"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},u="wrapper";function f(e){let{components:t,...a}=e;return(0,i.kt)(u,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,i.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,i.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,i.kt)("p",null,"The Open Privacy Research Society have ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/14eb3368.5ac78d9e.js b/build-staging/it/assets/js/14eb3368.5ac78d9e.js new file mode 100644 index 00000000..b466bfa7 --- /dev/null +++ b/build-staging/it/assets/js/14eb3368.5ac78d9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9817],{1310:(e,t,a)=>{a.d(t,{Z:()=>E});var n=a(7462),r=a(7294),i=a(6010),l=a(5281),s=a(2802),c=a(8596),o=a(9960),m=a(5999),d=a(4996);function u(e){return r.createElement("svg",(0,n.Z)({viewBox:"0 0 24 24"},e),r.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const h={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,d.Z)("/");return r.createElement("li",{className:"breadcrumbs__item"},r.createElement(o.Z,{"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},r.createElement(u,{className:h.breadcrumbHomeIcon})))}const v={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g(e){let{children:t,href:a,isLast:n}=e;const i="breadcrumbs__link";return n?r.createElement("span",{className:i,itemProp:"name"},t):a?r.createElement(o.Z,{className:i,href:a,itemProp:"item"},r.createElement("span",{itemProp:"name"},t)):r.createElement("span",{className:i},t)}function p(e){let{children:t,active:a,index:l,addMicrodata:s}=e;return r.createElement("li",(0,n.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,i.Z)("breadcrumbs__item",{"breadcrumbs__item--active":a})}),t,r.createElement("meta",{itemProp:"position",content:String(l+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?r.createElement("nav",{className:(0,i.Z)(l.k.docs.docBreadcrumbs,v.breadcrumbsContainer),"aria-label":(0,m.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},r.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&r.createElement(b,null),e.map(((t,a)=>{const n=a===e.length-1;return r.createElement(p,{key:a,active:n,index:a,addMicrodata:!!t.href},r.createElement(g,{href:t.href,isLast:n},t.label))})))):null}},4228:(e,t,a)=>{a.r(t),a.d(t,{default:()=>y});var n=a(7294),r=a(1944),i=a(2802),l=a(4996),s=a(6010),c=a(9960),o=a(3919),m=a(5999);const d={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};function u(e){let{href:t,children:a}=e;return n.createElement(c.Z,{href:t,className:(0,s.Z)("card padding--lg",d.cardContainer)},a)}function h(e){let{href:t,icon:a,title:r,description:i}=e;return n.createElement(u,{href:t},n.createElement("h2",{className:(0,s.Z)("text--truncate",d.cardTitle),title:r},a," ",r),i&&n.createElement("p",{className:(0,s.Z)("text--truncate",d.cardDescription),title:i},i))}function b(e){let{item:t}=e;const a=(0,i.Wl)(t);return a?n.createElement(h,{href:a,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,m.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const a=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,i.xz)(t.docId??void 0);return n.createElement(h,{href:t.href,icon:a,title:t.label,description:t.description??r?.description})}function g(e){let{item:t}=e;switch(t.type){case"link":return n.createElement(v,{item:t});case"category":return n.createElement(b,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function p(e){let{className:t}=e;const a=(0,i.jA)();return n.createElement(E,{items:a.items,className:t})}function E(e){const{items:t,className:a}=e;if(!t)return n.createElement(p,e);const r=(0,i.MN)(t);return n.createElement("section",{className:(0,s.Z)("row",a)},r.map(((e,t)=>n.createElement("article",{key:t,className:"col col--6 margin-bottom--lg"},n.createElement(g,{item:e})))))}var f=a(49),N=a(3120),Z=a(4364),k=a(1310),_=a(2503);const L={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function T(e){let{categoryGeneratedIndex:t}=e;return n.createElement(r.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,l.Z)(t.image)})}function x(e){let{categoryGeneratedIndex:t}=e;const a=(0,i.jA)();return n.createElement("div",{className:L.generatedIndexPage},n.createElement(N.Z,null),n.createElement(k.Z,null),n.createElement(Z.Z,null),n.createElement("header",null,n.createElement(_.Z,{as:"h1",className:L.title},t.title),t.description&&n.createElement("p",null,t.description)),n.createElement("article",{className:"margin-top--lg"},n.createElement(E,{items:a.items,className:L.list})),n.createElement("footer",{className:"margin-top--lg"},n.createElement(f.Z,{previous:t.navigation.previous,next:t.navigation.next})))}function y(e){return n.createElement(n.Fragment,null,n.createElement(T,e),n.createElement(x,e))}},49:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7462),r=a(7294),i=a(5999),l=a(2244);function s(e){const{previous:t,next:a}=e;return r.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,i.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&r.createElement(l.Z,(0,n.Z)({},t,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),a&&r.createElement(l.Z,(0,n.Z)({},a,{subLabel:r.createElement(i.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,a)=>{a.d(t,{Z:()=>c});var n=a(7294),r=a(6010),i=a(5999),l=a(5281),s=a(4477);function c(e){let{className:t}=e;const a=(0,s.E)();return a.badge?n.createElement("span",{className:(0,r.Z)(t,l.k.docs.docVersionBadge,"badge badge--secondary")},n.createElement(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:a.label}},"Version: {versionLabel}")):null}},3120:(e,t,a)=>{a.d(t,{Z:()=>g});var n=a(7294),r=a(6010),i=a(2263),l=a(9960),s=a(5999),c=a(143),o=a(5281),m=a(373),d=a(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:a}=e;return n.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:n.createElement("b",null,a.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function h(e){const t=u[e.versionMetadata.banner];return n.createElement(t,e)}function b(e){let{versionLabel:t,to:a,onClick:r}=e;return n.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:n.createElement("b",null,n.createElement(l.Z,{to:a,onClick:r},n.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function v(e){let{className:t,versionMetadata:a}=e;const{siteConfig:{title:l}}=(0,i.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,m.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:v}=(0,c.Jo)(s),g=u??(p=v).docs.find((e=>e.id===p.mainDocId));var p;return n.createElement("div",{className:(0,r.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},n.createElement("div",null,n.createElement(h,{siteTitle:l,versionMetadata:a})),n.createElement("div",{className:"margin-top--md"},n.createElement(b,{versionLabel:v.label,to:g.path,onClick:()=>d(v.name)})))}function g(e){let{className:t}=e;const a=(0,d.E)();return a.banner?n.createElement(v,{className:t,versionMetadata:a}):null}},2503:(e,t,a)=>{a.d(t,{Z:()=>m});var n=a(7462),r=a(7294),i=a(6010),l=a(5999),s=a(6668),c=a(9960);const o={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function m(e){let{as:t,id:a,...m}=e;const{navbar:{hideOnScroll:d}}=(0,s.L)();if("h1"===t||!a)return r.createElement(t,(0,n.Z)({},m,{id:void 0}));const u=(0,l.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof m.children?m.children:a});return r.createElement(t,(0,n.Z)({},m,{className:(0,i.Z)("anchor",d?o.anchorWithHideOnScrollNavbar:o.anchorWithStickyNavbar,m.className),id:a}),m.children,r.createElement(c.Z,{className:"hash-link",to:`#${a}`,"aria-label":u,title:u},"\u200b"))}},2244:(e,t,a)=>{a.d(t,{Z:()=>l});var n=a(7294),r=a(6010),i=a(9960);function l(e){const{permalink:t,title:a,subLabel:l,isNext:s}=e;return n.createElement(i.Z,{className:(0,r.Z)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},l&&n.createElement("div",{className:"pagination-nav__sublabel"},l),n.createElement("div",{className:"pagination-nav__label"},a))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/1578504c.2df26b14.js b/build-staging/it/assets/js/1578504c.2df26b14.js new file mode 100644 index 00000000..26d7b0e6 --- /dev/null +++ b/build-staging/it/assets/js/1578504c.2df26b14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3693],{7542:e=>{e.exports=JSON.parse('{"title":"Cwtch UI","slug":"/category/cwtch-ui","permalink":"/it/security/category/cwtch-ui","navigation":{"previous":{"title":"Cwtch Server","permalink":"/it/security/components/cwtch/server"},"next":{"title":"Android Service","permalink":"/it/security/components/ui/android"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/17896441.27340309.js b/build-staging/it/assets/js/17896441.27340309.js new file mode 100644 index 00000000..d1e2980a --- /dev/null +++ b/build-staging/it/assets/js/17896441.27340309.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7918],{1310:(e,t,n)=>{n.d(t,{Z:()=>E});var a=n(7462),l=n(7294),o=n(6010),r=n(5281),s=n(2802),c=n(8596),i=n(9960),d=n(5999),m=n(4996);function u(e){return l.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},e),l.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const v={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function b(){const e=(0,m.Z)("/");return l.createElement("li",{className:"breadcrumbs__item"},l.createElement(i.Z,{"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},l.createElement(u,{className:v.breadcrumbHomeIcon})))}const p={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function h(e){let{children:t,href:n,isLast:a}=e;const o="breadcrumbs__link";return a?l.createElement("span",{className:o,itemProp:"name"},t):n?l.createElement(i.Z,{className:o,href:n,itemProp:"item"},l.createElement("span",{itemProp:"name"},t)):l.createElement("span",{className:o},t)}function f(e){let{children:t,active:n,index:r,addMicrodata:s}=e;return l.createElement("li",(0,a.Z)({},s&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,o.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n})}),t,l.createElement("meta",{itemProp:"position",content:String(r+1)}))}function E(){const e=(0,s.s1)(),t=(0,c.Ns)();return e?l.createElement("nav",{className:(0,o.Z)(r.k.docs.docBreadcrumbs,p.breadcrumbsContainer),"aria-label":(0,d.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},l.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&l.createElement(b,null),e.map(((t,n)=>{const a=n===e.length-1;return l.createElement(f,{key:n,active:a,index:n,addMicrodata:!!t.href},l.createElement(h,{href:t.href,isLast:a},t.label))})))):null}},5154:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});var a=n(7294),l=n(1944),o=n(902);const r=a.createContext(null);function s(e){let{children:t,content:n}=e;const l=function(e){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return a.createElement(r.Provider,{value:l},t)}function c(){const e=(0,a.useContext)(r);if(null===e)throw new o.i6("DocProvider");return e}function i(){const{metadata:e,frontMatter:t,assets:n}=c();return a.createElement(l.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var d=n(6010),m=n(7524),u=n(49);function v(){const{metadata:e}=c();return a.createElement(u.Z,{previous:e.previous,next:e.next})}var b=n(3120),p=n(4364),h=n(5281),f=n(5999);function E(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:a.createElement("b",null,a.createElement("time",{dateTime:new Date(1e3*t).toISOString()},n))}}," on {date}")}function g(e){let{lastUpdatedBy:t}=e;return a.createElement(f.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:a.createElement("b",null,t)}}," by {user}")}function L(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:l}=e;return a.createElement("span",{className:h.k.common.lastUpdated},a.createElement(f.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?a.createElement(E,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:l?a.createElement(g,{lastUpdatedBy:l}):""}},"Last updated{atDate}{byUser}"),!1)}var C=n(4881),N=n(1526);const Z={lastUpdated:"lastUpdated_vwxv"};function k(e){return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterTagsRow,"row margin-bottom--sm")},a.createElement("div",{className:"col"},a.createElement(N.Z,e)))}function _(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:l,formattedLastUpdatedAt:o}=e;return a.createElement("div",{className:(0,d.Z)(h.k.docs.docFooterEditMetaRow,"row")},a.createElement("div",{className:"col"},t&&a.createElement(C.Z,{editUrl:t})),a.createElement("div",{className:(0,d.Z)("col",Z.lastUpdated)},(n||l)&&a.createElement(L,{lastUpdatedAt:n,formattedLastUpdatedAt:o,lastUpdatedBy:l})))}function x(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:l,lastUpdatedBy:o,tags:r}=e,s=r.length>0,i=!!(t||n||o);return s||i?a.createElement("footer",{className:(0,d.Z)(h.k.docs.docFooter,"docusaurus-mt-lg")},s&&a.createElement(k,{tags:r}),i&&a.createElement(_,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:o,formattedLastUpdatedAt:l})):null}var T=n(6043),H=n(3743),U=n(7462);const y={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function A(e){let{collapsed:t,...n}=e;return a.createElement("button",(0,U.Z)({type:"button"},n,{className:(0,d.Z)("clean-btn",y.tocCollapsibleButton,!t&&y.tocCollapsibleButtonExpanded,n.className)}),a.createElement(f.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component"},"On this page"))}const w={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function M(e){let{toc:t,className:n,minHeadingLevel:l,maxHeadingLevel:o}=e;const{collapsed:r,toggleCollapsed:s}=(0,T.u)({initialState:!0});return a.createElement("div",{className:(0,d.Z)(w.tocCollapsible,!r&&w.tocCollapsibleExpanded,n)},a.createElement(A,{collapsed:r,onClick:s}),a.createElement(T.z,{lazy:!0,className:w.tocCollapsibleContent,collapsed:r},a.createElement(H.Z,{toc:t,minHeadingLevel:l,maxHeadingLevel:o})))}const I={tocMobile:"tocMobile_ITEo"};function B(){const{toc:e,frontMatter:t}=c();return a.createElement(M,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,d.Z)(h.k.docs.docTocMobile,I.tocMobile)})}var O=n(9407);function S(){const{toc:e,frontMatter:t}=c();return a.createElement(O.Z,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:h.k.docs.docTocDesktop})}var V=n(2503),P=n(1506);function D(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return a.createElement("div",{className:(0,d.Z)(h.k.docs.docMarkdown,"markdown")},n&&a.createElement("header",null,a.createElement(V.Z,{as:"h1"},n)),a.createElement(P.Z,null,t))}var R=n(1310);const F={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function z(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),l=e.hide_table_of_contents,o=!l&&t.length>0;return{hidden:l,mobile:o?a.createElement(B,null):void 0,desktop:!o||"desktop"!==n&&"ssr"!==n?void 0:a.createElement(S,null)}}();return a.createElement("div",{className:"row"},a.createElement("div",{className:(0,d.Z)("col",!n.hidden&&F.docItemCol)},a.createElement(b.Z,null),a.createElement("div",{className:F.docItemContainer},a.createElement("article",null,a.createElement(R.Z,null),a.createElement(p.Z,null),n.mobile,a.createElement(D,null,t),a.createElement(x,null)),a.createElement(v,null))),n.desktop&&a.createElement("div",{className:"col col--3"},n.desktop))}function j(e){const t=`docs-doc-id-${e.content.metadata.unversionedId}`,n=e.content;return a.createElement(s,{content:e.content},a.createElement(l.FG,{className:t},a.createElement(i,null),a.createElement(z,null,a.createElement(n,null))))}},49:(e,t,n)=>{n.d(t,{Z:()=>s});var a=n(7462),l=n(7294),o=n(5999),r=n(2244);function s(e){const{previous:t,next:n}=e;return l.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,o.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&l.createElement(r.Z,(0,a.Z)({},t,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),n&&l.createElement(r.Z,(0,a.Z)({},n,{subLabel:l.createElement(o.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}},4364:(e,t,n)=>{n.d(t,{Z:()=>c});var a=n(7294),l=n(6010),o=n(5999),r=n(5281),s=n(4477);function c(e){let{className:t}=e;const n=(0,s.E)();return n.badge?a.createElement("span",{className:(0,l.Z)(t,r.k.docs.docVersionBadge,"badge badge--secondary")},a.createElement(o.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label}},"Version: {versionLabel}")):null}},3120:(e,t,n)=>{n.d(t,{Z:()=>h});var a=n(7294),l=n(6010),o=n(2263),r=n(9960),s=n(5999),c=n(143),i=n(5281),d=n(373),m=n(4477);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(s.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function v(e){const t=u[e.versionMetadata.banner];return a.createElement(t,e)}function b(e){let{versionLabel:t,to:n,onClick:l}=e;return a.createElement(s.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:a.createElement("b",null,a.createElement(r.Z,{to:n,onClick:l},a.createElement(s.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function p(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:r}}=(0,o.Z)(),{pluginId:s}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:m}=(0,d.J)(s),{latestDocSuggestion:u,latestVersionSuggestion:p}=(0,c.Jo)(s),h=u??(f=p).docs.find((e=>e.id===f.mainDocId));var f;return a.createElement("div",{className:(0,l.Z)(t,i.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},a.createElement("div",null,a.createElement(v,{siteTitle:r,versionMetadata:n})),a.createElement("div",{className:"margin-top--md"},a.createElement(b,{versionLabel:p.label,to:h.path,onClick:()=>m(p.name)})))}function h(e){let{className:t}=e;const n=(0,m.E)();return n.banner?a.createElement(p,{className:t,versionMetadata:n}):null}},9407:(e,t,n)=>{n.d(t,{Z:()=>d});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",i="table-of-contents__link--active";function d(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(s.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:i})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>b});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function s(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=s({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function m(e){const t=(0,l.useRef)(void 0),n=d();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function s(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),s=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=i(s,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===d)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const v=l.memo(u);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:d,maxHeadingLevel:u,...b}=e;const p=(0,o.L)(),h=d??p.tableOfContents.minHeadingLevel,f=u??p.tableOfContents.maxHeadingLevel,E=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>s({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:h,maxHeadingLevel:f});return m((0,l.useMemo)((()=>{if(c&&i)return{linkClassName:c,linkActiveClassName:i,minHeadingLevel:h,maxHeadingLevel:f}}),[c,i,h,f])),l.createElement(v,(0,a.Z)({toc:E,className:n,linkClassName:c},b))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/18b4904d.fd5db813.js b/build-staging/it/assets/js/18b4904d.fd5db813.js new file mode 100644 index 00000000..29b2ab2b --- /dev/null +++ b/build-staging/it/assets/js/18b4904d.fd5db813.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1322],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>m});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function i(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var l=r.createContext({}),p=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},u="mdxType",d={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},f=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,o=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),u=p(n),f=a,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||o;return n?r.createElement(m,i(i({ref:e},s),{},{components:n})):r.createElement(m,i({ref:e},s))}));function m(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var o=n.length,i=new Array(o);i[0]=f;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[u]="string"==typeof t?t:a,i[1]=c;for(var p=2;p{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:1.5},i="Starting a New Conversation",c={unversionedId:"chat/add-contact",id:"chat/add-contact",title:"Starting a New Conversation",description:"1. Seleziona un profilo",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/add-contact.md",sourceDirName:"chat",slug:"/chat/add-contact",permalink:"/it/docs/chat/add-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/add-contact.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Un'introduzione alla chat p2p di Cwtch",permalink:"/it/docs/chat/introduction"},next:{title:"Accettare/Declinare nuove conversazioni",permalink:"/it/docs/chat/accept-deny-new-conversation"}},l={},p=[],s={toc:p},u="wrapper";function d(t){let{components:e,...n}=t;return(0,a.kt)(u,(0,r.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"starting-a-new-conversation"},"Starting a New Conversation"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Seleziona un profilo"),(0,a.kt)("li",{parentName:"ol"},'Clicca sul pulsante "Aggiungi"'),(0,a.kt)("li",{parentName:"ol"},'Scegli "Aggiungi contatto"'),(0,a.kt)("li",{parentName:"ol"},"Incolla un indirizzo Cwtch"),(0,a.kt)("li",{parentName:"ol"},"Il contatto verr\xe0 aggiunto alla tua lista contatti")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/19563afa.3086b02e.js b/build-staging/it/assets/js/19563afa.3086b02e.js new file mode 100644 index 00000000..fa8d43d2 --- /dev/null +++ b/build-staging/it/assets/js/19563afa.3086b02e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3185],{3905:(e,n,r)=>{r.d(n,{Zo:()=>l,kt:()=>f});var t=r(7294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=t.createContext({}),s=function(e){var n=t.useContext(p),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},l=function(e){var n=s(e.components);return t.createElement(p.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=s(r),d=a,f=u["".concat(p,".").concat(d)]||u[d]||m[d]||i;return r?t.createElement(f,o(o({ref:n},l),{},{components:r})):t.createElement(f,o({ref:n},l))}));function f(e,n){var r=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var c={};for(var p in n)hasOwnProperty.call(n,p)&&(c[p]=n[p]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var s=2;s{r.r(n),r.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var t=r(7462),a=(r(7294),r(3905));const i={},o="References",c={unversionedId:"references",id:"references",title:"References",description:'* Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."',source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/references.md",sourceDirName:".",slug:"/references",permalink:"/it/security/references",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Development",permalink:"/it/security/development"}},p={},s=[],l={toc:s},u="wrapper";function m(e){let{components:n,...r}=e;return(0,a.kt)(u,(0,t.Z)({},l,r,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"references"},"References"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Brooks, John. Ricochet: Anonymous instant messaging for real privacy. ",(0,a.kt)("a",{parentName:"p",href:"https://ricochet.im."},"https://ricochet.im.")," Accessed: 2018-03-10")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata\u2014New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Langley, Adam. Pond. ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/agl/pond"},"https://github.com/agl/pond"),". Accessed: 2018-05-21.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},'Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).')),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Kalysch, A., Bove, D. and M\xfcller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn\u2019t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},"Unger, Nik et al. \u201cSoK: secure messaging\u201d. In: Security and Privacy (SP ), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232\u2013249 ",(0,a.kt)("a",{parentName:"p",href:"http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf"},"link")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/19cde8ec.3738013a.js b/build-staging/it/assets/js/19cde8ec.3738013a.js new file mode 100644 index 00000000..33fad73e --- /dev/null +++ b/build-staging/it/assets/js/19cde8ec.3738013a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5552],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),s=c(r),d=o,f=s["".concat(l,".").concat(d)]||s[d]||m[d]||i;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p[s]="string"==typeof e?e:o,a[1]=p;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:6},a="Come lasciare un gruppo",p={unversionedId:"groups/leave-group",id:"groups/leave-group",title:"Come lasciare un gruppo",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/leave-group.md",sourceDirName:"groups",slug:"/groups/leave-group",permalink:"/it/docs/groups/leave-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/leave-group.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Accettare un Invito a un gruppo",permalink:"/it/docs/groups/accept-group-invite"},next:{title:"Modificare il nome di un gruppo",permalink:"/it/docs/groups/edit-group-name"}},l={},c=[],u={toc:c},s="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"come-lasciare-un-gruppo"},"Come lasciare un gruppo"),(0,o.kt)("p",null,":::attenzione Esperimenti necessari"),(0,o.kt)("p",null,"Questa funzione richiede ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,o.kt)("p",null,":::"),(0,o.kt)("p",null,":::avviso"),(0,o.kt)("p",null,"Questa funzione comporter\xe0 ",(0,o.kt)("strong",{parentName:"p"},"la cancellazione irreversibile")," di materiale chiave. ",(0,o.kt)("strong",{parentName:"p"},"Non pu\xf2 essere annullata"),"."),(0,o.kt)("p",null,":::"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Nel pannello della chat vai alle impostazioni"),(0,o.kt)("li",{parentName:"ol"},"Scorri verso il basso fino alla fine del pannello"),(0,o.kt)("li",{parentName:"ol"},'Clicca su "lascia la conversazione"'),(0,o.kt)("li",{parentName:"ol"},"Conferma che vuoi lasciare")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Leave.mp4"}))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/1a25c548.9e772eca.js b/build-staging/it/assets/js/1a25c548.9e772eca.js new file mode 100644 index 00000000..07c7f298 --- /dev/null +++ b/build-staging/it/assets/js/1a25c548.9e772eca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5732],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=r,u=h["".concat(c,".").concat(m)]||h[m]||g[m]||o;return a?n.createElement(u,i(i({ref:t},p),{},{components:a})):n.createElement(u,i({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const o={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/it/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"6 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/it/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,n.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,r.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,r.kt)("strong",{parentName:"p"},"Beta")," to ",(0,r.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,r.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}g.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/1be78505.c2da882e.js b/build-staging/it/assets/js/1be78505.c2da882e.js new file mode 100644 index 00000000..fb0a6ec0 --- /dev/null +++ b/build-staging/it/assets/js/1be78505.c2da882e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9514,4972],{9963:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ge});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),c=n(3320),i=n(2802),s=n(4477),d=n(1116),m=n(7961),u=n(5999),b=n(2466),p=n(5936);const h={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};function E(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,l]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:r,cancelScroll:c}=(0,b.Ct)();return(0,b.RF)(((e,n)=>{let{scrollY:a}=e;const r=n?.scrollY;r&&(o.current?o.current=!1:a>=r?(c(),l(!1)):a{e.location.hash&&(o.current=!0,l(!1))})),{shown:n,scrollToTop:()=>r(0)}}({threshold:300});return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,l.Z)("clean-btn",r.k.common.backToTopButton,h.backToTopButton,e&&h.backToTopButtonShow),type:"button",onClick:t})}var f=n(1442),g=n(6550),k=n(7524),_=n(6668),v=n(1327),C=n(7462);function S(e){return a.createElement("svg",(0,C.Z)({width:"20",height:"20","aria-hidden":"true"},e),a.createElement("g",{fill:"#7a7a7a"},a.createElement("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),a.createElement("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})))}const I={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function N(e){let{onClick:t}=e;return a.createElement("button",{type:"button",title:(0,u.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,l.Z)("button button--secondary button--outline",I.collapseSidebarButton),onClick:t},a.createElement(S,{className:I.collapseSidebarButtonIcon}))}var T=n(9689),Z=n(902);const x=Symbol("EmptyContext"),B=a.createContext(x);function y(e){let{children:t}=e;const[n,l]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:l})),[n]);return a.createElement(B.Provider,{value:o},t)}var w=n(6043),L=n(8596),A=n(9960),M=n(2389);function F(e){let{categoryLabel:t,onClick:n}=e;return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel",message:"Toggle the collapsible sidebar category '{label}'",description:"The ARIA label to toggle the collapsible sidebar category"},{label:t}),type:"button",className:"clean-btn menu__caret",onClick:n})}function H(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{items:m,label:u,collapsible:b,className:p,href:h}=t,{docs:{sidebar:{autoCollapseCategories:E}}}=(0,_.L)(),f=function(e){const t=(0,M.Z)();return(0,a.useMemo)((()=>e.href?e.href:!t&&e.collapsible?(0,i.Wl)(e):void 0),[e,t])}(t),g=(0,i._F)(t,o),k=(0,L.Mg)(h,o),{collapsed:v,setCollapsed:S}=(0,w.u)({initialState:()=>!!b&&(!g&&t.collapsed)}),{expandedItem:I,setExpandedItem:N}=function(){const e=(0,a.useContext)(B);if(e===x)throw new Z.i6("DocSidebarItemsExpandedStateProvider");return e}(),T=function(e){void 0===e&&(e=!v),N(e?null:s),S(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:l}=e;const o=(0,Z.D9)(t);(0,a.useEffect)((()=>{t&&!o&&n&&l(!1)}),[t,o,n,l])}({isActive:g,collapsed:v,updateCollapsed:T}),(0,a.useEffect)((()=>{b&&null!=I&&I!==s&&E&&S(!0)}),[b,I,s,S,E]),a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemCategory,r.k.docs.docSidebarItemCategoryLevel(c),"menu__list-item",{"menu__list-item--collapsed":v},p)},a.createElement("div",{className:(0,l.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":k})},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!h&&b,"menu__link--active":g}),onClick:b?e=>{n?.(t),h?T(!1):(e.preventDefault(),T())}:()=>{n?.(t)},"aria-current":k?"page":void 0,"aria-expanded":b?!v:void 0,href:b?f??"#":f},d),u),h&&b&&a.createElement(F,{categoryLabel:u,onClick:e=>{e.preventDefault(),T()}})),a.createElement(w.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:v},a.createElement(j,{items:m,tabIndex:v?-1:0,onItemClick:n,activePath:o,level:c+1})))}var P=n(3919),W=n(9471);const D={menuExternalLink:"menuExternalLink_NmtK"};function R(e){let{item:t,onItemClick:n,activePath:o,level:c,index:s,...d}=e;const{href:m,label:u,className:b,autoAddBaseUrl:p}=t,h=(0,i._F)(t,o),E=(0,P.Z)(m);return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(c),"menu__list-item",b),key:u},a.createElement(A.Z,(0,C.Z)({className:(0,l.Z)("menu__link",!E&&D.menuExternalLink,{"menu__link--active":h}),autoAddBaseUrl:p,"aria-current":h?"page":void 0,to:m},E&&{onClick:n?()=>n(t):void 0},d),u,!E&&a.createElement(W.Z,null)))}const V={menuHtmlItem:"menuHtmlItem_M9Kj"};function z(e){let{item:t,level:n,index:o}=e;const{value:c,defaultStyle:i,className:s}=t;return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(n),i&&[V.menuHtmlItem,"menu__list-item"],s),key:o,dangerouslySetInnerHTML:{__html:c}})}function U(e){let{item:t,...n}=e;switch(t.type){case"category":return a.createElement(H,(0,C.Z)({item:t},n));case"html":return a.createElement(z,(0,C.Z)({item:t},n));default:return a.createElement(R,(0,C.Z)({item:t},n))}}function K(e){let{items:t,...n}=e;return a.createElement(y,null,t.map(((e,t)=>a.createElement(U,(0,C.Z)({key:t,item:e,index:t},n)))))}const j=(0,a.memo)(K),G={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:o}=e;const c=function(){const{isActive:e}=(0,T.nT)(),[t,n]=(0,a.useState)(e);return(0,b.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return a.createElement("nav",{"aria-label":(0,u.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,l.Z)("menu thin-scrollbar",G.menu,c&&G.menuWithAnnouncementBar,o)},a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:n,activePath:t,level:1})))}const q="sidebar_njMd",O="sidebarWithHideableNavbar_wUlq",X="sidebarHidden_VK0M",J="sidebarLogo_isFc";function Q(e){let{path:t,sidebar:n,onCollapse:o,isHidden:r}=e;const{navbar:{hideOnScroll:c},docs:{sidebar:{hideable:i}}}=(0,_.L)();return a.createElement("div",{className:(0,l.Z)(q,c&&O,r&&X)},c&&a.createElement(v.Z,{tabIndex:-1,className:J}),a.createElement(Y,{path:t,sidebar:n}),i&&a.createElement(N,{onClick:o}))}const $=a.memo(Q);var ee=n(3102),te=n(2961);const ne=e=>{let{sidebar:t,path:n}=e;const o=(0,te.e)();return a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(j,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&o.toggle(),"link"===e.type&&o.toggle()},level:1}))};function ae(e){return a.createElement(ee.Zo,{component:ne,props:e})}const le=a.memo(ae);function oe(e){const t=(0,k.i)(),n="desktop"===t||"ssr"===t,l="mobile"===t;return a.createElement(a.Fragment,null,n&&a.createElement($,e),l&&a.createElement(le,e))}const re={expandButton:"expandButton_m80_",expandButtonIcon:"expandButtonIcon_BlDH"};function ce(e){let{toggleSidebar:t}=e;return a.createElement("div",{className:re.expandButton,title:(0,u.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t},a.createElement(S,{className:re.expandButtonIcon}))}const ie={docSidebarContainer:"docSidebarContainer_b6E3",docSidebarContainerHidden:"docSidebarContainerHidden_b3ry",sidebarViewport:"sidebarViewport_Xe31"};function se(e){let{children:t}=e;const n=(0,d.V)();return a.createElement(a.Fragment,{key:n?.name??"noSidebar"},t)}function de(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}=e;const{pathname:c}=(0,g.TH)(),[i,s]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{i&&s(!1),!i&&(0,f.n)()&&s(!0),o((e=>!e))}),[o,i]);return a.createElement("aside",{className:(0,l.Z)(r.k.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&s(!0)}},a.createElement(se,null,a.createElement("div",{className:(0,l.Z)(ie.sidebarViewport,i&&ie.sidebarViewportHidden)},a.createElement(oe,{sidebar:t,path:c,onCollapse:d,isHidden:i}),i&&a.createElement(ce,{toggleSidebar:d}))))}const me={docMainContainer:"docMainContainer_gTbr",docMainContainerEnhanced:"docMainContainerEnhanced_Uz_u",docItemWrapperEnhanced:"docItemWrapperEnhanced_czyv"};function ue(e){let{hiddenSidebarContainer:t,children:n}=e;const o=(0,d.V)();return a.createElement("main",{className:(0,l.Z)(me.docMainContainer,(t||!o)&&me.docMainContainerEnhanced)},a.createElement("div",{className:(0,l.Z)("container padding-top--md padding-bottom--lg",me.docItemWrapper,t&&me.docItemWrapperEnhanced)},n))}const be={docPage:"docPage__5DB",docsWrapper:"docsWrapper_BCFX"};function pe(e){let{children:t}=e;const n=(0,d.V)(),[l,o]=(0,a.useState)(!1);return a.createElement(m.Z,{wrapperClassName:be.docsWrapper},a.createElement(E,null),a.createElement("div",{className:be.docPage},n&&a.createElement(de,{sidebar:n.items,hiddenSidebarContainer:l,setHiddenSidebarContainer:o}),a.createElement(ue,{hiddenSidebarContainer:l},t)))}var he=n(4972),Ee=n(197);function fe(e){const{versionMetadata:t}=e;return a.createElement(a.Fragment,null,a.createElement(Ee.Z,{version:t.version,tag:(0,c.os)(t.pluginId,t.version)}),a.createElement(o.d,null,t.noIndex&&a.createElement("meta",{name:"robots",content:"noindex, nofollow"})))}function ge(e){const{versionMetadata:t}=e,n=(0,i.hI)(e);if(!n)return a.createElement(he.default,null);const{docElement:c,sidebarName:m,sidebarItems:u}=n;return a.createElement(a.Fragment,null,a.createElement(fe,e),a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.docsPages,r.k.page.docsDocPage,e.versionMetadata.className)},a.createElement(s.q,{version:t},a.createElement(d.b,{name:m,items:u},a.createElement(pe,null,c)))))}},4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});var a=n(7294),l=n(5999),o=n(1944),r=n(7961);function c(){return a.createElement(a.Fragment,null,a.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/1cbfc7c5.b1788676.js b/build-staging/it/assets/js/1cbfc7c5.b1788676.js new file mode 100644 index 00000000..8dbf8fce --- /dev/null +++ b/build-staging/it/assets/js/1cbfc7c5.b1788676.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3712],{1879:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/release","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/1d0a8d89.a73fb03b.js b/build-staging/it/assets/js/1d0a8d89.a73fb03b.js new file mode 100644 index 00000000..73650b43 --- /dev/null +++ b/build-staging/it/assets/js/1d0a8d89.a73fb03b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6711],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),f=o,d=u["".concat(s,".").concat(f)]||u[f]||g[f]||i;return n?r.createElement(d,a(a({ref:t},p),{},{components:n})):r.createElement(d,a({ref:t},p))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>g,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:5},a="Accessing Conversation Settings",c={unversionedId:"chat/conversation-settings",id:"chat/conversation-settings",title:"Accessing Conversation Settings",description:"In a conversation window, click on the Settings icon in the top bar.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/conversation-settings.md",sourceDirName:"chat",slug:"/chat/conversation-settings",permalink:"/it/docs/chat/conversation-settings",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/conversation-settings.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Formattazione messaggio",permalink:"/it/docs/chat/message-formatting"},next:{title:"Rispondere a un messaggio",permalink:"/it/docs/chat/reply-to-message"}},s={},l=[],p={toc:l},u="wrapper";function g(e){let{components:t,...i}=e;return(0,o.kt)(u,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accessing-conversation-settings"},"Accessing Conversation Settings"),(0,o.kt)("p",null,"In a conversation window, click on the Settings icon in the top bar."),(0,o.kt)("figure",null,(0,o.kt)("p",null,(0,o.kt)("a",{target:"_blank",href:n(671).Z},(0,o.kt)("img",{src:n(6305).Z,width:"624",height:"257"}))),(0,o.kt)("figcaption",null)),(0,o.kt)("p",null,"This action will open up a new screen where you can view and manage the contact."),(0,o.kt)("figure",null,(0,o.kt)("p",null,(0,o.kt)("a",{target:"_blank",href:n(4306).Z},(0,o.kt)("img",{src:n(2289).Z,width:"937",height:"689"}))),(0,o.kt)("figcaption",null)))}g.isMDXComponent=!0},4306:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-full-a068891bad494392f02a68cff0c943cd.png"},671:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/files/settings-138ef72c7beda06bcdba55491d3f7c26.png"},2289:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-full-a068891bad494392f02a68cff0c943cd.png"},6305:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/settings-138ef72c7beda06bcdba55491d3f7c26.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/1ebd8798.efaa5cf8.js b/build-staging/it/assets/js/1ebd8798.efaa5cf8.js new file mode 100644 index 00000000..e31acfe9 --- /dev/null +++ b/build-staging/it/assets/js/1ebd8798.efaa5cf8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4788],{3905:(e,t,n)=>{n.d(t,{Zo:()=>g,kt:()=>u});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=i.createContext({}),s=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},g=function(e){var t=s(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,g=c(e,["components","mdxType","originalType","parentName"]),p=s(n),d=a,u=p["".concat(l,".").concat(d)]||p[d]||h[d]||r;return n?i.createElement(u,o(o({ref:t},g),{},{components:n})):i.createElement(u,o({ref:t},g))}));function u(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:a,o[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const r={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/it/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"24 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"autobindings",permalink:"/it/blog/tags/autobindings"},{label:"libcwtch",permalink:"/it/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/it/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/it/blog/cwtch-testing-ii"}},l={authorsImageUrls:[void 0]},s=[],g={toc:s},p="wrapper";function h(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,i.Z)({},g,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,a.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,a.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/209bdfc3.e88f9793.js b/build-staging/it/assets/js/209bdfc3.e88f9793.js new file mode 100644 index 00000000..8add5e83 --- /dev/null +++ b/build-staging/it/assets/js/209bdfc3.e88f9793.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2537],{4520:a=>{a.exports=JSON.parse('{"label":"documentation","permalink":"/it/blog/tags/documentation","allTagsPath":"/it/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/21d06810.9f9af253.js b/build-staging/it/assets/js/21d06810.9f9af253.js new file mode 100644 index 00000000..cde818b8 --- /dev/null +++ b/build-staging/it/assets/js/21d06810.9f9af253.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7621],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=c(r),d=o,m=p["".concat(l,".").concat(d)]||p[d]||h[d]||i;return r?n.createElement(m,s(s({ref:t},u),{},{components:r})):n.createElement(m,s({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:o,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Developing Cwtch",a={unversionedId:"contribute/developing",id:"contribute/developing",title:"Developing Cwtch",description:"This section documents some ways to get started with Cwtch Development.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/developing.md",sourceDirName:"contribute",slug:"/contribute/developing",permalink:"/it/docs/contribute/developing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/developing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Contribute",permalink:"/it/docs/category/contribute"},next:{title:"Testare Cwtch",permalink:"/it/docs/contribute/testing"}},l={},c=[{value:"Cwtch Issues Tracking Process",id:"cwtch-issues-tracking-process",level:2},{value:"Cwtch Pull-Request Process",id:"cwtch-pull-request-process",level:2},{value:"Build Bot",id:"build-bot",level:3},{value:"Useful Resources",id:"useful-resources",level:2}],u={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"developing-cwtch"},"Developing Cwtch"),(0,o.kt)("p",null,"This section documents some ways to get started with Cwtch Development."),(0,o.kt)("h2",{id:"cwtch-issues-tracking-process"},"Cwtch Issues Tracking Process"),(0,o.kt)("p",null,"All Cwtch issues are tracked from the ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"cwtch-ui git repository"),", even if the bug/feature originates in an upstream library. This allows us to keep everything in one place."),(0,o.kt)("p",null,"Issues are generally divided into 4 distinct categories:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Unprocessed")," - These are new issues that have not been discussed by the Cwtch team."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=195&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Scheduled"))," - These issues have been planned for an upcoming release. They are usually tagged with the release they are expected to be fixed in e.g. ",(0,o.kt)("inlineCode",{parentName:"li"},"cwtch-1.11"),". A core Cwtch team member is likely working on the issue, or is expecting to work on the issue in the coming weeks."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=153&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Desired"))," - These are issues that we would like to fix but for some reason we are unable to schedule. This might be because the feature is large and requires a lot of effort, or because there is some blocker (e.g. a missing feature in Flutter or some other library) that prevents work on the feature."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues?q=&type=all&state=open&labels=136&milestone=0&assignee=0&poster=0"},(0,o.kt)("strong",{parentName:"a"},"Help Wanted"))," - These are generally small issues that we would like to fix but that have been designated low priority. These are ideal first issues for volunteers.")),(0,o.kt)("p",null,'If you would like to work on an open bug/feature, please comment on the issue and a member of the Cwtch team will follow up with advice on where to go from there. This helps us keep track of who is working on what problems, and reduces the amount of duplicate work. We aim to answer most queries within 24 hours, feel free to "bump" an issue if it takes longer than that.'),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)")),(0,o.kt)("h2",{id:"cwtch-pull-request-process"},"Cwtch Pull-Request Process"),(0,o.kt)("p",null,"All pull-requests must be reviewed and approved by a core Cwtch team member prior to merging. Sarah reviews all new and active pull requests multiple times a week."),(0,o.kt)("h3",{id:"build-bot"},"Build Bot"),(0,o.kt)("p",null,"All Cwtch projects are set up with automated builds and testing. Every pull request is expected to be able to pass through these pipelines prior to being merged. If buildbot reports a failure then Sarah will work with you to determine the issue, and any necessary fixes."),(0,o.kt)("p",null,"Buildbot can fail for reasons beyond your control e.g. many of our integration tests rely setting up Tor connections, these can be brittle on occasion and result in timeouts and failures. Always confirm the root cause of a test failure before deciding what to do next."),(0,o.kt)("h2",{id:"useful-resources"},"Useful Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/components/ecosystem-overview"},"Cwtch Ecosystem Overview")," - a summary of active Cwtch repositories from the Cwtch Secure Development Handbook."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"Contributing Documentation")," - advice on contributing Cwtch documentation."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/testing"},"Contributing Testing")," - advice on contributing by testing Cwtch."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/translate"},"Contributing Translations")," - advice on contributing translations to Cwtch.")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"All contributions are ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/231a229c.9ecf60b7.js b/build-staging/it/assets/js/231a229c.9ecf60b7.js new file mode 100644 index 00000000..471e0de5 --- /dev/null +++ b/build-staging/it/assets/js/231a229c.9ecf60b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2348],{3905:(e,i,t)=>{t.d(i,{Zo:()=>p,kt:()=>m});var n=t(7294);function a(e,i,t){return i in e?Object.defineProperty(e,i,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[i]=t,e}function o(e,i){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);i&&(n=n.filter((function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable}))),t.push.apply(t,n)}return t}function r(e){for(var i=1;i=0||(a[t]=e[t]);return a}(e,i);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var s=n.createContext({}),c=function(e){var i=n.useContext(s),t=i;return e&&(t="function"==typeof e?e(i):r(r({},i),e)),t},p=function(e){var i=c(e.components);return n.createElement(s.Provider,{value:i},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var i=e.children;return n.createElement(n.Fragment,{},i)}},f=n.forwardRef((function(e,i){var t=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=c(t),f=a,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||o;return t?n.createElement(m,r(r({ref:i},p),{},{components:t})):n.createElement(m,r({ref:i},p))}));function m(e,i){var t=arguments,a=i&&i.mdxType;if("string"==typeof e||a){var o=t.length,r=new Array(o);r[0]=f;var l={};for(var s in i)hasOwnProperty.call(i,s)&&(l[s]=i[s]);l.originalType=e,l[u]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{t.r(i),t.d(i,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=t(7462),a=(t(7294),t(3905));const o={sidebar_position:6},r="Condividere un file",l={unversionedId:"chat/share-file",id:"chat/share-file",title:"Condividere un file",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento di condivisione file attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/share-file.md",sourceDirName:"chat",slug:"/chat/share-file",permalink:"/it/docs/chat/share-file",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-file.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Rispondere a un messaggio",permalink:"/it/docs/chat/reply-to-message"},next:{title:"Bloccare un contatto",permalink:"/it/docs/chat/block-contact"}},s={},c=[{value:"Come funziona la condivisione file con i gruppi? I miei file sono salvati su un server da qualche parte?",id:"come-funziona-la-condivisione-file-con-i-gruppi-i-miei-file-sono-salvati-su-un-server-da-qualche-parte",level:2},{value:"Questo significa che devo essere online per inviare un file?",id:"questo-significa-che-devo-essere-online-per-inviare-un-file",level:2},{value:"Perch\xe9 ci sono dei nuovi contatti che appaiono nella mia lista?",id:"perch\xe9-ci-sono-dei-nuovi-contatti-che-appaiono-nella-mia-lista",level:2},{value:"Che cosa \xe8 "SHA512"?",id:"che-cosa-\xe8-sha512",level:2},{value:"C'\xe8 un limite alla dimensione dei file?",id:"c\xe8-un-limite-alla-dimensione-dei-file",level:2},{value:"Che cosa sono questi file .manifest?",id:"che-cosa-sono-questi-file-manifest",level:2},{value:"E i metadati dei file?",id:"e-i-metadati-dei-file",level:2},{value:"Posso scaricare file automaticamente?",id:"posso-scaricare-file-automaticamente",level:2}],p={toc:c},u="wrapper";function d(e){let{components:i,...t}=e;return(0,a.kt)(u,(0,n.Z)({},p,t,{components:i,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"condividere-un-file"},"Condividere un file"),(0,a.kt)("p",null,":::attenzione Esperimenti necessari"),(0,a.kt)("p",null,"Questa funzione richiede ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"Esperimento di condivisione file")," attivato."),(0,a.kt)("p",null,"Optionally, you can enable ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," to see display shared image previews in the conversation window."),(0,a.kt)("p",null,":::"),(0,a.kt)("p",null,"In una conversazione,"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Clicca sull'icona dell'allegato"),(0,a.kt)("li",{parentName:"ol"},"Trova il file che vuoi inviare"),(0,a.kt)("li",{parentName:"ol"},"Conferma che vuoi inviarlo")),(0,a.kt)("h2",{id:"come-funziona-la-condivisione-file-con-i-gruppi-i-miei-file-sono-salvati-su-un-server-da-qualche-parte"},"Come funziona la condivisione file con i gruppi? I miei file sono salvati su un server da qualche parte?"),(0,a.kt)("p",null,"I file vengono inviati tramite le connessioni Cwtch onion-to-onion direttamente dalla persona che offre il file alla persona che lo riceve. L'offerta iniziale per inviare un file \xe8 pubblicata come una conversazione standard in Cwtch / un normale messaggio in sovraimpressione. Per i gruppi, ci\xf2 significa che l'offerta iniziale (contenente il nome del file, la dimensione, l'hash e un nonce) \xe8 pubblicata sul server del gruppo, ma poi ogni destinatario si connette al mittente individualmente per ricevere effettivamente il contenuto del file."),(0,a.kt)("h2",{id:"questo-significa-che-devo-essere-online-per-inviare-un-file"},"Questo significa che devo essere online per inviare un file?"),(0,a.kt)("p",null,'Si. Se la persona che offre il file va offline, dovrai aspettare che sia di nuovo online per riprendere il trasferimento del file. Il protocollo sottostante divide i file in pezzi verificabili e che possono essere richiesti individualmente, in modo tale che in un futura versione sar\xe0 possibile "riospitare" un file pubblicato in un gruppo, e anche scaricare da pi\xf9 host contemporaneamente (come una sorta di bittorrent).'),(0,a.kt)("h2",{id:"perch\xe9-ci-sono-dei-nuovi-contatti-che-appaiono-nella-mia-lista"},"Perch\xe9 ci sono dei nuovi contatti che appaiono nella mia lista?"),(0,a.kt)("p",null,"Ci\xf2 \xe8 dovuto al modo in cui Cwtch gestisce attualmente le connessioni da indirizzi sconosciuti. Dato che pubblicare un file in un gruppo implica che i membri del gruppo si connettono a te direttamente, alcuni di questi membri potrebbero non essere gi\xe0 nella tua lista contatti, e quindi la loro connessione a te per il download apparir\xe0 nella tua lista come una richiesta di contatto."),(0,a.kt)("h2",{id:"che-cosa-\xe8-sha512"},'Che cosa \xe8 "SHA512"?'),(0,a.kt)("p",null,"SHA512 \xe8 un ",(0,a.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Cryptographic_hash_function"},"hash crittografico")," che pu\xf2 essere utilizzato per verificare che il file scaricato sia una copia corretta del file offerto. Cwtch fa questa verifica per te automaticamente, ma puoi anche provare a fare la tua propria verifica indipendentemente! Nota che includiamo anche un nonce casuale con le offerte di file, cosicch\xe9 le persone non possano semplicemente richiederti qualsiasi hash casuale che potresti avere, o file di conversazioni di cui non fanno parte."),(0,a.kt)("h2",{id:"c\xe8-un-limite-alla-dimensione-dei-file"},"C'\xe8 un limite alla dimensione dei file?"),(0,a.kt)("p",null,"Il limite attuale \xe8 di 10 gigabyte per file."),(0,a.kt)("h2",{id:"che-cosa-sono-questi-file-manifest"},"Che cosa sono questi file .manifest?"),(0,a.kt)("p",null,"I file .manifest vengono utilizzati durante il download di un file per verificare che i singoli pezzi siano ricevuti correttamente, e supportare il ripristino di trasferimenti interrotti. Essi contengono anche le informazioni provenienti dall'offerta del file originale. Puoi eliminarli senza problemi una volta completato il download. Su Android, i manifesti vengono memorizzati nella cache dell'app e possono essere cancellati attraverso le impostazioni di sistema."),(0,a.kt)("h2",{id:"e-i-metadati-dei-file"},"E i metadati dei file?"),(0,a.kt)("p",null,"Inviamo il nome del file come suggerimento e per aiutare a distinguerlo dalle offerte di altri file. Il percorso completo viene rimosso prima di inviare l'offerta. Bisogna fare attenzione ai metadati nascosti che potrebbero essere memorizzati nel file stesso, cosa che varia a seconda del formato del file. Ad esempio, le immagini potrebbero contenere informazioni sulla geo-localizzazione e informazioni sulla fotocamera che le ha catturate, e i file PDF sono noti per contenere informazioni nascoste come il nome dell'autore o il dispositivo su cui sono stati creati. In generale, si dovrebbe inviare/ricevere file solo a/da persone di cui ci si fida."),(0,a.kt)("h2",{id:"posso-scaricare-file-automaticamente"},"Posso scaricare file automaticamente?"),(0,a.kt)("p",null,"If the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures experiment")," is enabled then Cwtch will automatically download images from accepted conversations"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/247a7af4.e3a62790.js b/build-staging/it/assets/js/247a7af4.e3a62790.js new file mode 100644 index 00000000..5d4c89ff --- /dev/null +++ b/build-staging/it/assets/js/247a7af4.e3a62790.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8070],{4196:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/reproducible-builds","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/2887095c.3218a046.js b/build-staging/it/assets/js/2887095c.3218a046.js new file mode 100644 index 00000000..9758127c --- /dev/null +++ b/build-staging/it/assets/js/2887095c.3218a046.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[621],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>v});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),l=u(n),m=i,v=l["".concat(c,".").concat(m)]||l[m]||d[m]||o;return n?r.createElement(v,a(a({ref:t},s),{},{components:n})):r.createElement(v,a({ref:t},s))}));function v(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:i,a[1]=p;for(var u=2;u{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:4},a="Inviare inviti a un gruppo",p={unversionedId:"groups/send-invite",id:"groups/send-invite",title:"Inviare inviti a un gruppo",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/send-invite.md",sourceDirName:"groups",slug:"/groups/send-invite",permalink:"/it/docs/groups/send-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/send-invite.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Creare un nuovo gruppo",permalink:"/it/docs/groups/create-group"},next:{title:"Accettare un Invito a un gruppo",permalink:"/it/docs/groups/accept-group-invite"}},c={},u=[],s={toc:u},l="wrapper";function d(e){let{components:t,...n}=e;return(0,i.kt)(l,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"inviare-inviti-a-un-gruppo"},"Inviare inviti a un gruppo"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,i.kt)("p",null,":::"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Vai a una conversazione con un contatto"),(0,i.kt)("li",{parentName:"ol"},"Clicca sull'icona dell'invito"),(0,i.kt)("li",{parentName:"ol"},"Seleziona il gruppo in cui vuoi invitare la persona"),(0,i.kt)("li",{parentName:"ol"},'Seleziona "Invita"'),(0,i.kt)("li",{parentName:"ol"},"Hai inviato un invito")),(0,i.kt)("div",null,(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Group_Invite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/29659bc8.6aaa4109.js b/build-staging/it/assets/js/29659bc8.6aaa4109.js new file mode 100644 index 00000000..ab9c45a8 --- /dev/null +++ b/build-staging/it/assets/js/29659bc8.6aaa4109.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6266],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>f});var o=n(7294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,o)}return n}function c(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var l=o.createContext({}),s=function(t){var e=o.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):c(c({},e),t)),n},p=function(t){var e=s(t.components);return o.createElement(l.Provider,{value:e},t.children)},u="mdxType",d={inlineCode:"code",wrapper:function(t){var e=t.children;return o.createElement(o.Fragment,{},e)}},b=o.forwardRef((function(t,e){var n=t.components,r=t.mdxType,a=t.originalType,l=t.parentName,p=i(t,["components","mdxType","originalType","parentName"]),u=s(n),b=r,f=u["".concat(l,".").concat(b)]||u[b]||d[b]||a;return n?o.createElement(f,c(c({ref:e},p),{},{components:n})):o.createElement(f,c({ref:e},p))}));function f(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var a=n.length,c=new Array(a);c[0]=b;var i={};for(var l in e)hasOwnProperty.call(e,l)&&(i[l]=e[l]);i.originalType=t,i[u]="string"==typeof t?t:r,c[1]=i;for(var s=2;s{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={sidebar_position:8},c="Sbloccare un contatto",i={unversionedId:"chat/unblock-contact",id:"chat/unblock-contact",title:"Sbloccare un contatto",description:"1. Seleziona il contatto nella tua lista conversazioni. I contatti bloccati vengono spostati in fondo alla lista.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/unblock-contact.md",sourceDirName:"chat",slug:"/chat/unblock-contact",permalink:"/it/docs/chat/unblock-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/unblock-contact.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8},sidebar:"tutorialSidebar",previous:{title:"Bloccare un contatto",permalink:"/it/docs/chat/block-contact"},next:{title:"Removing a Conversation",permalink:"/it/docs/chat/delete-contact"}},l={},s=[],p={toc:s},u="wrapper";function d(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"sbloccare-un-contatto"},"Sbloccare un contatto"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Seleziona il contatto nella tua lista conversazioni. I contatti bloccati vengono spostati in fondo alla lista."),(0,r.kt)("li",{parentName:"ol"},"Vai alle Impostazioni della conversazione"),(0,r.kt)("li",{parentName:"ol"},'Scorri verso il basso fino a "Blocca il contatto"'),(0,r.kt)("li",{parentName:"ol"},'Sposta l\'interruttore su "Sblocca il contatto"')),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/298daba3.cc57f664.js b/build-staging/it/assets/js/298daba3.cc57f664.js new file mode 100644 index 00000000..32dfea5a --- /dev/null +++ b/build-staging/it/assets/js/298daba3.cc57f664.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8573],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>d});var r=n(7294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function i(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function o(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var l=r.createContext({}),u=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):o(o({},e),t)),n},s=function(t){var e=u(t.components);return r.createElement(l.Provider,{value:e},t.children)},p="mdxType",h={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},m=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,i=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),p=u(n),m=a,d=p["".concat(l,".").concat(m)]||p[m]||h[m]||i;return n?r.createElement(d,o(o({ref:e},s),{},{components:n})):r.createElement(d,o({ref:e},s))}));function d(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var i=n.length,o=new Array(i);o[0]=m;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[p]="string"==typeof t?t:a,o[1]=c;for(var u=2;u{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(7462),a=(n(7294),n(3905));const i={sidebar_position:2},o="Translating Cwtch",c={unversionedId:"contribute/translate",id:"contribute/translate",title:"Translating Cwtch",description:"Se vuoi contribuire con delle traduzioni all'applicazione di Cwtch o a questo manuale, ecco come fare",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/translate.md",sourceDirName:"contribute",slug:"/contribute/translate",permalink:"/it/docs/contribute/translate",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/translate.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Testare Cwtch",permalink:"/it/docs/contribute/testing"},next:{title:"Documentation Style Guide",permalink:"/it/docs/contribute/documentation"}},l={},u=[{value:"Contributing Translations to the Cwtch Application",id:"contributing-translations-to-the-cwtch-application",level:2},{value:"Join our Lokalise Team",id:"join-our-lokalise-team",level:3},{value:"Directly via Git",id:"directly-via-git",level:3},{value:"Manuale utente di Cwtch",id:"manuale-utente-di-cwtch",level:2}],s={toc:u},p="wrapper";function h(t){let{components:e,...n}=t;return(0,a.kt)(p,(0,r.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"translating-cwtch"},"Translating Cwtch"),(0,a.kt)("p",null,"Se vuoi contribuire con delle traduzioni all'applicazione di Cwtch o a questo manuale, ecco come fare"),(0,a.kt)("h2",{id:"contributing-translations-to-the-cwtch-application"},"Contributing Translations to the Cwtch Application"),(0,a.kt)("p",null,"There are two ways to contribute to Cwtch applications."),(0,a.kt)("h3",{id:"join-our-lokalise-team"},"Join our Lokalise Team"),(0,a.kt)("p",null,"We use ",(0,a.kt)("a",{parentName:"p",href:"https://lokalise.com"},"Lokalise")," for managing translations for the Cwtch application."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Sign up for a Lokalise account"),(0,a.kt)("li",{parentName:"ol"},"Email ",(0,a.kt)("a",{parentName:"li",href:"mailto:team@cwtch.im"},"team@cwtch.im")," with the language you are interested in translating and an email we can use to invite you to our Lokalise team.")),(0,a.kt)("h3",{id:"directly-via-git"},"Directly via Git"),(0,a.kt)("p",null,"For new translations, you can make a copy of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb")," and begin translating - you can then either ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing#cwtch-pull-request-process"},"submit pull requests or directly")," send updates to us (",(0,a.kt)("a",{parentName:"p",href:"mailto:team@cwtch.im"},"team@cwtch.im"),") and we will merge them in."),(0,a.kt)("p",null,"For adding to existing translations you can make pull requests directly on any file in ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/")," and we will review and merge them in."),(0,a.kt)("h2",{id:"manuale-utente-di-cwtch"},"Manuale utente di Cwtch"),(0,a.kt)("p",null,"This handbook is translated through ",(0,a.kt)("a",{parentName:"p",href:"https://crowdin.com"},"Crowdin"),"."),(0,a.kt)("p",null,"To join our Crowdin project:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Sign up for an account on ",(0,a.kt)("a",{parentName:"li",href:"https://crowdin.com"},"Crowdin"),"."),(0,a.kt)("li",{parentName:"ol"},"Join the ",(0,a.kt)("a",{parentName:"li",href:"https://crowdin.com/project/cwtch-users-handbook"},"cwtch-users-handbook project"),".")),(0,a.kt)("p",null,"We bundle up changes to the documentation in batches and sync them with the Crowdin project on a regular basis."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"All contributions are ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/2c10bcf6.fe137241.js b/build-staging/it/assets/js/2c10bcf6.fe137241.js new file mode 100644 index 00000000..f43c0b0e --- /dev/null +++ b/build-staging/it/assets/js/2c10bcf6.fe137241.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2397],{9355:a=>{a.exports=JSON.parse('{"label":"security-handbook","permalink":"/it/blog/tags/security-handbook","allTagsPath":"/it/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/2c901dd2.29005498.js b/build-staging/it/assets/js/2c901dd2.29005498.js new file mode 100644 index 00000000..9c224690 --- /dev/null +++ b/build-staging/it/assets/js/2c901dd2.29005498.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5314],{2255:a=>{a.exports=JSON.parse('{"label":"api","permalink":"/it/blog/tags/api","allTagsPath":"/it/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/2ffad701.d61d2196.js b/build-staging/it/assets/js/2ffad701.d61d2196.js new file mode 100644 index 00000000..be97ed03 --- /dev/null +++ b/build-staging/it/assets/js/2ffad701.d61d2196.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[785],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var a=n.createContext({}),c=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(a.Provider,{value:t},e.children)},l="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=c(r),d=o,f=l["".concat(a,".").concat(d)]||l[d]||m[d]||i;return r?n.createElement(f,s(s({ref:t},u),{},{components:r})):n.createElement(f,s({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=d;var p={};for(var a in t)hasOwnProperty.call(t,a)&&(p[a]=t[a]);p.originalType=e,p[l]="string"==typeof e?e:o,s[1]=p;for(var c=2;c{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},s="Groups Experiment",p={unversionedId:"settings/experiments/group-experiment",id:"settings/experiments/group-experiment",title:"Groups Experiment",description:"Enables Cwtch to connect to untrusted servers and use them to host private, asynchronous, groups.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/group-experiment.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/group-experiment",permalink:"/it/docs/settings/experiments/group-experiment",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/group-experiment.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Experiments",permalink:"/it/docs/category/experiments"},next:{title:"Hosting di un server",permalink:"/it/docs/settings/experiments/server-hosting"}},a={},c=[{value:"To Turn On",id:"to-turn-on",level:2}],u={toc:c},l="wrapper";function m(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"groups-experiment"},"Groups Experiment"),(0,o.kt)("p",null,"Enables Cwtch to ",(0,o.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},"connect to untrusted servers")," and use them to ",(0,o.kt)("a",{parentName:"p",href:"/docs/groups/introduction"},"host private, asynchronous, groups"),"."),(0,o.kt)("h2",{id:"to-turn-on"},"To Turn On"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},'Vai su "Impostazioni"'),(0,o.kt)("li",{parentName:"ol"},'Abilita "Esperimenti"'),(0,o.kt)("li",{parentName:"ol"},"Abilita l'Esperimento Gruppi")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/34843fbe.da3b7d88.js b/build-staging/it/assets/js/34843fbe.da3b7d88.js new file mode 100644 index 00000000..e871a097 --- /dev/null +++ b/build-staging/it/assets/js/34843fbe.da3b7d88.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6940],{1403:e=>{e.exports=JSON.parse('{"title":"Cwtch Components","slug":"/category/cwtch-components","permalink":"/it/security/category/cwtch-components","navigation":{"previous":{"title":"Risk Model","permalink":"/it/security/risk"},"next":{"title":"Cwtch Technical Basics","permalink":"/it/security/components/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3a109bd3.e8f7d386.js b/build-staging/it/assets/js/3a109bd3.e8f7d386.js new file mode 100644 index 00000000..dd4385b5 --- /dev/null +++ b/build-staging/it/assets/js/3a109bd3.e8f7d386.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7782],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>g});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),s=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),p=s(n),h=r,g=p["".concat(l,".").concat(h)]||p[h]||u[h]||a;return n?o.createElement(g,i(i({ref:t},m),{},{components:n})):o.createElement(g,i({ref:t},m))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:r,i[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/it/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"10 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/it/blog/tags/documentation"},{label:"security-handbook",permalink:"/it/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/it/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/it/blog/autobindings-ii"}},l={authorsImageUrls:[void 0]},s=[],m={toc:s},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,o.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3b7b256a.61f28f34.js b/build-staging/it/assets/js/3b7b256a.61f28f34.js new file mode 100644 index 00000000..05a5109e --- /dev/null +++ b/build-staging/it/assets/js/3b7b256a.61f28f34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4867],{2504:a=>{a.exports=JSON.parse('{"label":"libcwtch","permalink":"/it/blog/tags/libcwtch","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3b87f7a6.e4176764.js b/build-staging/it/assets/js/3b87f7a6.e4176764.js new file mode 100644 index 00000000..43f96506 --- /dev/null +++ b/build-staging/it/assets/js/3b87f7a6.e4176764.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2135],{982:t=>{t.exports=JSON.parse('{"title":"Tapir","slug":"/category/tapir","permalink":"/it/security/category/tapir","navigation":{"previous":{"title":"Connectivity","permalink":"/it/security/components/connectivity/intro"},"next":{"title":"Packet Format","permalink":"/it/security/components/tapir/packet_format"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3bc00383.ea404c51.js b/build-staging/it/assets/js/3bc00383.ea404c51.js new file mode 100644 index 00000000..b7a164f9 --- /dev/null +++ b/build-staging/it/assets/js/3bc00383.ea404c51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9481],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>f});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=l(n),m=r,f=p["".concat(s,".").concat(m)]||p[m]||d[m]||i;return n?o.createElement(f,c(c({ref:t},u),{},{components:n})):o.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,c=new Array(i);c[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[p]="string"==typeof e?e:r,c[1]=a;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:1},c="Blocca connessioni sconosciute",a={unversionedId:"settings/behaviour/block-unknown-connections",id:"settings/behaviour/block-unknown-connections",title:"Blocca connessioni sconosciute",description:'By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. \xc8 possibile modificare questo comportamento tramite l\'impostazione "Blocco connessioni sconosciute".',source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/behaviour/block-unknown-connections.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/block-unknown-connections",permalink:"/it/docs/settings/behaviour/block-unknown-connections",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/block-unknown-connections.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Behaviour",permalink:"/it/docs/category/behaviour"},next:{title:"Policy di notifica",permalink:"/it/docs/settings/behaviour/notification-policy"}},s={},l=[],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"blocca-connessioni-sconosciute"},"Blocca connessioni sconosciute"),(0,r.kt)("p",null,"By default, Cwtch interprets connections from unknown Cwtch addresses as ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/chat/accept-deny-new-conversation"},"Contact Requests"),'. \xc8 possibile modificare questo comportamento tramite l\'impostazione "Blocco connessioni sconosciute".'),(0,r.kt)("p",null,"Se abilitata, Cwtch chiuder\xe0 automaticamente tutte le connessioni dagli indirizzi Cwtch che non hai aggiunto al tuo elenco delle conversazioni. This will prevent people who have your Cwtch address from contacting you unless you also add them."),(0,r.kt)("p",null,"Per abilitare:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},'Vai su "Impostazioni"'),(0,r.kt)("li",{parentName:"ol"},'Attiva/Disattiva "Blocco contatti sconosciuti"')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3bf835b2.df84e28a.js b/build-staging/it/assets/js/3bf835b2.df84e28a.js new file mode 100644 index 00000000..fafbff13 --- /dev/null +++ b/build-staging/it/assets/js/3bf835b2.df84e28a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4862],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>m});var o=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function n(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=o.createContext({}),c=function(e){var r=o.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},s=function(e){var r=c(e.components);return o.createElement(p.Provider,{value:r},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},d=o.forwardRef((function(e,r){var t=e.components,i=e.mdxType,n=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),f=c(t),d=i,m=f["".concat(p,".").concat(d)]||f[d]||u[d]||n;return t?o.createElement(m,a(a({ref:r},s),{},{components:t})):o.createElement(m,a({ref:r},s))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var n=t.length,a=new Array(n);a[0]=d;var l={};for(var p in r)hasOwnProperty.call(r,p)&&(l[p]=r[p]);l.originalType=e,l[f]="string"==typeof e?e:i,a[1]=l;for(var c=2;c{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>a,default:()=>u,frontMatter:()=>n,metadata:()=>l,toc:()=>c});var o=t(7462),i=(t(7294),t(3905));const n={sidebar_position:10},a="Backup o esportazione di un profilo",l={unversionedId:"profiles/exporting-profile",id:"profiles/exporting-profile",title:"Backup o esportazione di un profilo",description:"Nella schermata di Gestione del profilo:",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/exporting-profile.md",sourceDirName:"profiles",slug:"/profiles/exporting-profile",permalink:"/it/docs/profiles/exporting-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/exporting-profile.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Eliminare un profilo",permalink:"/it/docs/profiles/delete-profile"},next:{title:"Importare un profilo",permalink:"/it/docs/profiles/importing-a-profile"}},p={},c=[],s={toc:c},f="wrapper";function u(e){let{components:r,...t}=e;return(0,i.kt)(f,(0,o.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"backup-o-esportazione-di-un-profilo"},"Backup o esportazione di un profilo"),(0,i.kt)("p",null,"Nella schermata di Gestione del profilo:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Seleziona la matita accanto al profilo che vuoi modificare"),(0,i.kt)("li",{parentName:"ol"},"Scorri verso il basso fino alla fine del men\xfa"),(0,i.kt)("li",{parentName:"ol"},'Seleziona "Esporta profilo"'),(0,i.kt)("li",{parentName:"ol"},"Scegli una posizione e un nome per il file"),(0,i.kt)("li",{parentName:"ol"},"Conferma")),(0,i.kt)("p",null,"Una volta confermato, Cwtch inserir\xe0 una copia del profilo alla posizione indicata. Questo file viene crittografato allo stesso livello del profilo. Vedi ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"Una nota sui profili protetti da password (crittografati)")," per ulteriori informazioni sui profili crittografati."),(0,i.kt)("p",null,"Questo file pu\xf2 essere ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/importing-a-profile"},"importato")," in un'altra istanza di Cwtch su qualsiasi dispositivo."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3bf8c048.fc0d4ec1.js b/build-staging/it/assets/js/3bf8c048.fc0d4ec1.js new file mode 100644 index 00000000..9e7c78e2 --- /dev/null +++ b/build-staging/it/assets/js/3bf8c048.fc0d4ec1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8371],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>d});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),p=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},s=function(e){var r=p(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),u=p(t),m=o,d=u["".concat(c,".").concat(m)]||u[m]||f[m]||i;return t?n.createElement(d,a(a({ref:r},s),{},{components:t})):n.createElement(d,a({ref:r},s))}));function d(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,a=new Array(i);a[0]=m;var l={};for(var c in r)hasOwnProperty.call(r,c)&&(l[c]=r[c]);l.originalType=e,l[u]="string"==typeof e?e:o,a[1]=l;for(var p=2;p{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:6},a="Eliminare un profilo",l={unversionedId:"profiles/delete-profile",id:"profiles/delete-profile",title:"Eliminare un profilo",description:"Questa funzione comporter\xe0 la cancellazione irreversibile di materiale chiave. Non pu\xf2 essere annullata.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/delete-profile.md",sourceDirName:"profiles",slug:"/profiles/delete-profile",permalink:"/it/docs/profiles/delete-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/delete-profile.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Sbloccare profili crittografati",permalink:"/it/docs/profiles/unlock-profile"},next:{title:"Backup o esportazione di un profilo",permalink:"/it/docs/profiles/exporting-profile"}},c={},p=[],s={toc:p},u="wrapper";function f(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"eliminare-un-profilo"},"Eliminare un profilo"),(0,o.kt)("p",null,":::avviso"),(0,o.kt)("p",null,"Questa funzione comporter\xe0 ",(0,o.kt)("strong",{parentName:"p"},"la cancellazione irreversibile")," di materiale chiave. ",(0,o.kt)("strong",{parentName:"p"},"Non pu\xf2 essere annullata"),"."),(0,o.kt)("p",null,":::"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Clicca sulla matita accanto al profilo che vuoi modificare"),(0,o.kt)("li",{parentName:"ol"},"Scorri verso il basso fino alla fine del men\xfa"),(0,o.kt)("li",{parentName:"ol"},"Clicca su elimina"),(0,o.kt)("li",{parentName:"ol"},"Clicca su elimina definitivamente il profilo")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3d43f565.27cb38fe.js b/build-staging/it/assets/js/3d43f565.27cb38fe.js new file mode 100644 index 00000000..5ad84962 --- /dev/null +++ b/build-staging/it/assets/js/3d43f565.27cb38fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4239],{9470:e=>{e.exports=JSON.parse('{"title":"Contribuisci","slug":"/category/contribute","permalink":"/it/docs/category/contribute","navigation":{"previous":{"title":"Tor","permalink":"/it/docs/tor"},"next":{"title":"Developing Cwtch","permalink":"/it/docs/contribute/developing"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3db42865.27ab3fca.js b/build-staging/it/assets/js/3db42865.27ab3fca.js new file mode 100644 index 00000000..c1f2d599 --- /dev/null +++ b/build-staging/it/assets/js/3db42865.27ab3fca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7139],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/3e80d710.98dc1d51.js b/build-staging/it/assets/js/3e80d710.98dc1d51.js new file mode 100644 index 00000000..eab1897b --- /dev/null +++ b/build-staging/it/assets/js/3e80d710.98dc1d51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2723],{7760:a=>{a.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable","allTagsPath":"/it/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/43b107c1.87b92c1b.js b/build-staging/it/assets/js/43b107c1.87b92c1b.js new file mode 100644 index 00000000..fdc78c7b --- /dev/null +++ b/build-staging/it/assets/js/43b107c1.87b92c1b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9200],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>g});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),d=i,g=c["".concat(l,".").concat(d)]||c[d]||h[d]||r;return n?a.createElement(g,o(o({ref:t},u),{},{components:n})):a.createElement(g,o({ref:t},u))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=d;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/it/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"3 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"support",permalink:"/it/blog/tags/support"},{label:"testing",permalink:"/it/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/it/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/it/blog/cwtch-platform-support"}},l={authorsImageUrls:[void 0]},p=[{value:"Current Limitations of Flutter Gherkin",id:"current-limitations-of-flutter-gherkin",level:2},{value:"Integrating Tests into the Pipeline",id:"integrating-tests-into-the-pipeline",level:2},{value:"Catching Bugs!",id:"catching-bugs",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},c="wrapper";function h(e){let{components:t,...r}=e;return(0,i.kt)(c,(0,a.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"We first ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,i.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})),(0,i.kt)("h2",{id:"current-limitations-of-flutter-gherkin"},"Current Limitations of Flutter Gherkin"),(0,i.kt)("p",null,"The original ",(0,i.kt)("a",{parentName:"p",href:"https://pub.dev/packages/flutter_gherkin"},"flutter_gherkin")," is under semi-active development; however, the latest published versions don't support using it with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),"."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Test")," was originally intended to run single widget/unit tests for a Flutter project."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"Flutter Drive")," was originally intended to run integration tests ",(0,i.kt)("em",{parentName:"li"},"on a device or an emulator"),".")),(0,i.kt)("p",null,"However, in recent releases these lines have become blurred. The new ",(0,i.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/testing/integration-tests"},"integration_test")," package that comes built into newer Flutter releases has support for both ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),". This was a great change because it decreases the required overhead to run larger integration tests (",(0,i.kt)("inlineCode",{parentName:"p"},"flutter drive")," sets up a host-controller model that requires a dedicated control channel to be setup, whereas ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible)."),(0,i.kt)("p",null,"There is thankfully code in the ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter_gherkin")," repository that supports running tests with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", however this code currently has a few issues:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The test code generation produces code that doesn't compile without minor changes."),(0,i.kt)("li",{parentName:"ul"},'Certain functionality like "take a screenshot" does not work on desktop.')),(0,i.kt)("p",null,"Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test."),(0,i.kt)("li",{parentName:"ul"},"Certain Flutter widgets like ",(0,i.kt)("inlineCode",{parentName:"li"},"DropdownButton")," are not compatible with built-in steps like ",(0,i.kt)("inlineCode",{parentName:"li"},"tap")," because they internally contain multiple copies of the same widget.")),(0,i.kt)("p",null,"Because of the above issues we have chosen to ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/flutter_gherkin"},"fork flutter_gherkin")," to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing."),(0,i.kt)("h2",{id:"integrating-tests-into-the-pipeline"},"Integrating Tests into the Pipeline"),(0,i.kt)("p",null,"One of the major limitations of ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test")," is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display."),(0,i.kt)("p",null,"Thankfully it is possible to use ",(0,i.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Xvfb"},"Xfvb")," to create a virtual framebuffer, and set ",(0,i.kt)("inlineCode",{parentName:"p"},"DISPLAY")," to render to that buffer:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"export DISPLAY=:99\nXvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &\n")),(0,i.kt)("p",null,"This allows us to neutralize our main issue with ",(0,i.kt)("inlineCode",{parentName:"p"},"flutter test"),", and efficiently run tests in our pipeline."),(0,i.kt)("h2",{id:"catching-bugs"},"Catching Bugs!"),(0,i.kt)("p",null,"This small amount of integration work has already caught its first bug."),(0,i.kt)("p",null,"Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/integration_test/features/01_general/02_save_load.feature"},"02_save_load.feature")," simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment."),(0,i.kt)("p",null,"The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory ",(0,i.kt)("inlineCode",{parentName:"p"},"$USER_HOME/Downloads")," didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available."),(0,i.kt)("p",null,"As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!"),(0,i.kt)("h2",{id:"next-steps"},"Next Steps"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More automated tests:")," We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More platforms:")," Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/getting-started/supported_platforms"},"our target platforms"),". We expect to start this work soon; expect more news in a future Cwtch Testing update!")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("strong",{parentName:"p"},"More steps:")," One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the ",(0,i.kt)("inlineCode",{parentName:"p"},"expect to see the message")," step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. ",(0,i.kt)("inlineCode",{parentName:"p"},"send a file")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"set profile picture"),"."))),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/45a7c7c6.49c7af0e.js b/build-staging/it/assets/js/45a7c7c6.49c7af0e.js new file mode 100644 index 00000000..0890447e --- /dev/null +++ b/build-staging/it/assets/js/45a7c7c6.49c7af0e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9251],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,p=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),u=c(r),d=i,f=u["".concat(p,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,s(s({ref:t},l),{},{components:r})):n.createElement(f,s({ref:t},l))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,s=new Array(o);s[0]=d;var a={};for(var p in t)hasOwnProperty.call(t,p)&&(a[p]=t[p]);a.originalType=e,a[u]="string"==typeof e?e:i,s[1]=a;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:2},s="Hosting di un server",a={unversionedId:"settings/experiments/server-hosting",id:"settings/experiments/server-hosting",title:"Hosting di un server",description:"L'hosting di un server \xe8 attualmente una funzione sperimentale in Cwtch, non \xe8 tra le impostazioni predefinite.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/server-hosting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/server-hosting",permalink:"/it/docs/settings/experiments/server-hosting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/server-hosting.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Groups Experiment",permalink:"/it/docs/settings/experiments/group-experiment"},next:{title:"Condivisione file",permalink:"/it/docs/settings/experiments/file-sharing"}},p={},c=[],l={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,i.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"hosting-di-un-server"},"Hosting di un server"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"L'hosting di un server \xe8 attualmente una funzione sperimentale in Cwtch, non \xe8 tra le impostazioni predefinite.")),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},'Vai su "Impostazioni"'),(0,i.kt)("li",{parentName:"ol"},'Abilita "Esperimenti"'),(0,i.kt)("li",{parentName:"ol"},"Abilita l'Esperimento di server hosting"),(0,i.kt)("li",{parentName:"ol"},"Probabilmente vorrai anche abilitare l'Esperimento Gruppi se vuoi partecipare a un gruppo ospitato sul tuo server")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/46b0c109.e289bdf1.js b/build-staging/it/assets/js/46b0c109.e289bdf1.js new file mode 100644 index 00000000..f884b047 --- /dev/null +++ b/build-staging/it/assets/js/46b0c109.e289bdf1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5583],{3905:(t,e,n)=>{n.d(e,{Zo:()=>p,kt:()=>d});var a=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function r(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,a)}return n}function s(t){for(var e=1;e=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var l=a.createContext({}),c=function(t){var e=a.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):s(s({},e),t)),n},p=function(t){var e=c(t.components);return a.createElement(l.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},b=a.forwardRef((function(t,e){var n=t.components,i=t.mdxType,r=t.originalType,l=t.parentName,p=o(t,["components","mdxType","originalType","parentName"]),u=c(n),b=i,d=u["".concat(l,".").concat(b)]||u[b]||f[b]||r;return n?a.createElement(d,s(s({ref:e},p),{},{components:n})):a.createElement(d,s({ref:e},p))}));function d(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var r=n.length,s=new Array(r);s[0]=b;var o={};for(var l in e)hasOwnProperty.call(e,l)&&(o[l]=e[l]);o.originalType=t,o[u]="string"==typeof t?t:i,s[1]=o;for(var c=2;c{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>s,default:()=>f,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var a=n(7462),i=(n(7294),n(3905));const r={sidebar_position:14},s="Setting Availability Status",o={unversionedId:"profiles/availability-status",id:"profiles/availability-status",title:"Setting Availability Status",description:"This functionality is currently only available in the Nightly Release builds of Cwtch.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/availability-status.md",sourceDirName:"profiles",slug:"/profiles/availability-status",permalink:"/it/docs/profiles/availability-status",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/availability-status.md",tags:[],version:"current",sidebarPosition:14,frontMatter:{sidebar_position:14},sidebar:"tutorialSidebar",previous:{title:"Importare un profilo",permalink:"/it/docs/profiles/importing-a-profile"},next:{title:"Setting Profile Attributes",permalink:"/it/docs/profiles/profile-info"}},l={},c=[],p={toc:c},u="wrapper";function f(t){let{components:e,...r}=t;return(0,i.kt)(u,(0,a.Z)({},p,r,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"setting-availability-status"},"Setting Availability Status"),(0,i.kt)("admonition",{title:"Nightly Feature",type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This functionality is currently ",(0,i.kt)("strong",{parentName:"p"},"only")," available in the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly Release")," builds of Cwtch."),(0,i.kt)("p",{parentName:"admonition"},"This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.")),(0,i.kt)("p",null,"On the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/category/conversations"},"conversations pane")," click the Status icon next to your profile picture."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(1476).Z},(0,i.kt)("img",{src:n(3163).Z,width:"444",height:"252"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"A drop-down menu will appear with various options e.g. Available, Away, and Busy"),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(8791).Z},(0,i.kt)("img",{src:n(3891).Z,width:"443",height:"242"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"When you select Away or Busy as a status the border of your profile picture will change to reflect the status"),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(4940).Z},(0,i.kt)("img",{src:n(1859).Z,width:"442",height:"233"}))),(0,i.kt)("figcaption",null)),(0,i.kt)("p",null,"Contacts will see this change reflected in their conversations pane."),(0,i.kt)("figure",null,(0,i.kt)("p",null,(0,i.kt)("a",{target:"_blank",href:n(8868).Z},(0,i.kt)("img",{src:n(6792).Z,width:"443",height:"223"}))),(0,i.kt)("figcaption",null)))}f.isMDXComponent=!0},8868:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},4940:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},8791:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},1476:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/files/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"},6792:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-busy-3fb73cba568a8a79114c63df9f09c01b.png"},1859:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3891:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-tooltip-busy-e3d123418d62abccb5ab50796aa86747.png"},3163:(t,e,n)=>{n.d(e,{Z:()=>a});const a=n.p+"assets/images/status-tooltip-e1b9f7ca4de7c1fb3b3ae39b2e10f578.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/47db09cd.872c613a.js b/build-staging/it/assets/js/47db09cd.872c613a.js new file mode 100644 index 00000000..3ed242f5 --- /dev/null +++ b/build-staging/it/assets/js/47db09cd.872c613a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6891],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),d=a,f=u["".concat(c,".").concat(d)]||u[d]||m[d]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var l=2;l{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:4},i="Modalit\xe0 Streamer/Presentazione",s={unversionedId:"settings/appearance/streamer-mode",id:"settings/appearance/streamer-mode",title:"Modalit\xe0 Streamer/Presentazione",description:"La modalit\xe0 Streamer/Presentazione rende l'applicazione visivamente pi\xf9 privata. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/streamer-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/streamer-mode",permalink:"/it/docs/settings/appearance/streamer-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/streamer-mode.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Colonne dell' IU (Interfaccia Utente)",permalink:"/it/docs/settings/appearance/ui-columns"},next:{title:"Behaviour",permalink:"/it/docs/category/behaviour"}},c={},l=[],p={toc:l},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"modalit\xe0-streamerpresentazione"},"Modalit\xe0 Streamer/Presentazione"),(0,a.kt)("p",null,"La modalit\xe0 Streamer/Presentazione rende l'applicazione visivamente pi\xf9 privata. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens."),(0,a.kt)("p",null,'Questo \xe8 utile quando si catturano screenshot o in altro modo si mostra Cwtch pi\xf9 "pubblicamente".'),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Clicca sull'icona impostazione"),(0,a.kt)("li",{parentName:"ol"},'Imposta la "Modalit\xe0 Streamer" su On'),(0,a.kt)("li",{parentName:"ol"},"Controlla che funzioni guardando il tuo profilo la tua lista di contatti")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/4972.486cf118.js b/build-staging/it/assets/js/4972.486cf118.js new file mode 100644 index 00000000..4e318acc --- /dev/null +++ b/build-staging/it/assets/js/4972.486cf118.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4972],{4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});var a=n(7294),o=n(5999),l=n(1944),r=n(7961);function i(){return a.createElement(a.Fragment,null,a.createElement(l.d,{title:(0,o.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/49b07f50.aea03bee.js b/build-staging/it/assets/js/49b07f50.aea03bee.js new file mode 100644 index 00000000..6e3c6852 --- /dev/null +++ b/build-staging/it/assets/js/49b07f50.aea03bee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6318],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var s=a.createContext({}),l=function(e){var t=a.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(r),m=n,h=u["".concat(s,".").concat(m)]||u[m]||d[m]||i;return r?a.createElement(h,o(o({ref:t},p),{},{components:r})):a.createElement(h,o({ref:t},p))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:n,o[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var a=r(7462),n=(r(7294),r(3905));const i={sidebar_position:1},o="Che cos\u2019\xe8 Cwtch?",c={unversionedId:"intro",id:"intro",title:"Che cos\u2019\xe8 Cwtch?",description:"Cwtch (/k\u028at\u0283/ - una parola gallese che si traduce approssimativamente in \u201cun abbraccio che crea un luogo sicuro\u201d) \xe8 un'applicazione di messaggistica decentralizzata, rispettosa della privacy e resistente ai metadati.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/intro.md",sourceDirName:".",slug:"/intro",permalink:"/it/docs/intro",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Getting started",permalink:"/it/docs/category/getting-started"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(u,(0,a.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"che-cos\xe8-cwtch"},"Che cos\u2019\xe8 Cwtch?"),(0,n.kt)("p",null,"Cwtch (/k\u028at\u0283/ - una parola gallese che si traduce approssimativamente in \u201cun abbraccio che crea un luogo sicuro\u201d) \xe8 un'applicazione di messaggistica decentralizzata, rispettosa della privacy e resistente ai metadati."),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Decentralizzata e aperta"),": non c'\xe8 alcun \u201cservizio Cwtch\u201d o \u201crete Cwtch\u201d. I partecipanti a Cwtch possono ospitare i propri spazi sicuri, o prestare la loro infrastruttura ad altri che cercano uno spazio sicuro. Il protocollo Cwtch \xe8 aperto, e chiunque \xe8 libero di creare bot, servizi e interfacce utente, e di integrare e interagire con Cwtch."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Rispettosa della privacy"),": Tutta la comunicazione in Cwtch \xe8 crittografata end-to-end e si svolge attraverso i servizi onion di Tor v3."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Resistente ai metadati"),": Cwtch \xe8 stata progettata in modo tale che nessuna informazione venga scambiata o resa disponibile a qualcuno senza il suo esplicito consenso, inclusi i messaggi on-the-wire e i metadati del protocollo.")),(0,n.kt)("h1",{id:"sicurezza-e-crittografia"},"Sicurezza e Crittografia"),(0,n.kt)("p",null,"Per uno sguardo pi\xf9 approfondito alla sicurezza, alla privacy e alla sottostante tecnologia di crittografia utilizzata in Cwtch, consulta il nostro ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Manuale sulla sicurezza")),(0,n.kt)("h1",{id:"come-iniziare"},"Come iniziare"),(0,n.kt)("p",null,"Puoi scaricare l'ultima versione di Cwtch da ",(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download/"},"https://cwtch.im/download/")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/4aa555c3.65cc139a.js b/build-staging/it/assets/js/4aa555c3.65cc139a.js new file mode 100644 index 00000000..e2ce950f --- /dev/null +++ b/build-staging/it/assets/js/4aa555c3.65cc139a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7797],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),u=n,f=h["".concat(c,".").concat(u)]||h[u]||m[u]||o;return a?r.createElement(f,i(i({ref:t},p),{},{components:a})):r.createElement(f,i({ref:t},p))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/it/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"16 giugno 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"release",permalink:"/it/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/it/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/it/blog/cwtch-nightly-v.11-74"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function m(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(159).Z,width:"1004",height:"480"})))}m.isMDXComponent=!0},159:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/4d27f429.e6e4fc99.js b/build-staging/it/assets/js/4d27f429.e6e4fc99.js new file mode 100644 index 00000000..774da933 --- /dev/null +++ b/build-staging/it/assets/js/4d27f429.e6e4fc99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[788],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=i.createContext({}),s=function(e){var t=i.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},p="mdxType",b={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(r),d=n,h=p["".concat(c,".").concat(d)]||p[d]||b[d]||a;return r?i.createElement(h,o(o({ref:t},u),{},{components:r})):i.createElement(h,o({ref:t},u))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=d;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:n,o[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>b,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/cwtch-bindings-reproducible",source:"@site/blog/2023-01-20-reproducible-builds-bindings.md",title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",date:"2023-01-20T00:00:00.000Z",formattedDate:"20 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/it/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"repliqate",permalink:"/it/blog/tags/repliqate"}],readingTime:7.915,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Bindings Reproducible",description:"How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.",slug:"cwtch-bindings-reproducible",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog3_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch UI Platform Support",permalink:"/it/blog/cwtch-platform-support"},nextItem:{title:"Cwtch Stable API Design",permalink:"/it/blog/cwtch-stable-api-design"}},c={authorsImageUrls:[void 0]},s=[],u={toc:s},p="wrapper";function b(e){let{components:t,...r}=e;return(0,n.kt)(p,(0,i.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify."),(0,n.kt)("p",null,"But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable."),(0,n.kt)("p",null,"The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can ",(0,n.kt)("strong",{parentName:"p"},"independently verify")," that the binaries we release are built from the Cwtch source code."),(0,n.kt)("p",null,"In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project."))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/4f68bcc6.d9b156bf.js b/build-staging/it/assets/js/4f68bcc6.d9b156bf.js new file mode 100644 index 00000000..e5eed984 --- /dev/null +++ b/build-staging/it/assets/js/4f68bcc6.d9b156bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3516],{4289:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-security"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/508409b4.0048c1c5.js b/build-staging/it/assets/js/508409b4.0048c1c5.js new file mode 100644 index 00000000..62a4e392 --- /dev/null +++ b/build-staging/it/assets/js/508409b4.0048c1c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3171],{3905:(e,r,t)=>{t.d(r,{Zo:()=>c,kt:()=>m});var o=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function n(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=o.createContext({}),s=function(e){var r=o.useContext(p),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},c=function(e){var r=s(e.components);return o.createElement(p.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},d=o.forwardRef((function(e,r){var t=e.components,i=e.mdxType,n=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=s(t),d=i,m=u["".concat(p,".").concat(d)]||u[d]||f[d]||n;return t?o.createElement(m,a(a({ref:r},c),{},{components:t})):o.createElement(m,a({ref:r},c))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var n=t.length,a=new Array(n);a[0]=d;var l={};for(var p in r)hasOwnProperty.call(r,p)&&(l[p]=r[p]);l.originalType=e,l[u]="string"==typeof e?e:i,a[1]=l;for(var s=2;s{t.r(r),t.d(r,{assets:()=>p,contentTitle:()=>a,default:()=>f,frontMatter:()=>n,metadata:()=>l,toc:()=>s});var o=t(7462),i=(t(7294),t(3905));const n={sidebar_position:11},a="Importare un profilo",l={unversionedId:"profiles/importing-a-profile",id:"profiles/importing-a-profile",title:"Importare un profilo",description:'1. Clicca sul pulsante di azione "+" nell\'angolo in basso a destra e seleziona "Importa profilo"',source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/importing-a-profile.md",sourceDirName:"profiles",slug:"/profiles/importing-a-profile",permalink:"/it/docs/profiles/importing-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/importing-a-profile.md",tags:[],version:"current",sidebarPosition:11,frontMatter:{sidebar_position:11},sidebar:"tutorialSidebar",previous:{title:"Backup o esportazione di un profilo",permalink:"/it/docs/profiles/exporting-profile"},next:{title:"Setting Availability Status",permalink:"/it/docs/profiles/availability-status"}},p={},s=[],c={toc:s},u="wrapper";function f(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,o.Z)({},c,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"importare-un-profilo"},"Importare un profilo"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},'Clicca sul pulsante di azione "',(0,i.kt)("inlineCode",{parentName:"li"},"+"),'" nell\'angolo in basso a destra e seleziona "Importa profilo"'),(0,i.kt)("li",{parentName:"ol"},"Seleziona il ",(0,i.kt)("a",{parentName:"li",href:"/docs/profiles/exporting-profile"},"file di un profilo Cwtch esportato")," da importare"),(0,i.kt)("li",{parentName:"ol"},"Inserisci la ",(0,i.kt)("a",{parentName:"li",href:"/docs/profiles/create-a-profile#a-note-on-password-protected-encrypted-profiles"},"password")," associata al profilo e conferma.")),(0,i.kt)("p",null,"Una volta confermato, Cwtch tenter\xe0 di decifrare il file fornito utilizzando una chiave derivata dalla password fornita. Se l'operazione ha successo il profilo verr\xe0 visualizzato nella schermata Gestione profilo e sar\xe0 pronto per l'uso."),(0,i.kt)("p",null,":::nota"),(0,i.kt)("p",null,"Mentre un profilo pu\xf2 essere importato su pi\xf9 dispositivi, attualmente si pu\xf3 avere una sola versione di un profilo in uso su tutti i dispositivi ad un dato momento."),(0,i.kt)("p",null,"Tentativi di utilizzare lo stesso profilo su pi\xf9 dispositivi possono causare problemi di disponibilit\xe0 e errori di messaggistica."),(0,i.kt)("p",null,":::"))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/53cc4802.a67d245e.js b/build-staging/it/assets/js/53cc4802.a67d245e.js new file mode 100644 index 00000000..7deebd7f --- /dev/null +++ b/build-staging/it/assets/js/53cc4802.a67d245e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7594],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),m=a,d=u["".concat(s,".").concat(m)]||u[m]||g[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const i={title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/it/blog/cwtch-testing-i",source:"@site/blog/2023-02-03-cwtch-testing-i.md",title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",date:"2023-02-03T00:00:00.000Z",formattedDate:"3 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"support",permalink:"/it/blog/tags/support"},{label:"testing",permalink:"/it/blog/tags/testing"}],readingTime:4.74,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing",description:"In this development log we provide an update on automated UI integration testing!",slug:"cwtch-testing-i",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog5_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/it/blog/cwtch-android-reproducibility"},nextItem:{title:"Cwtch UI Platform Support",permalink:"/it/blog/cwtch-platform-support"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},u="wrapper";function g(e){let{components:t,...i}=e;return(0,a.kt)(u,(0,r.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"We first ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"introduced UI tests last January"),". At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines."),(0,a.kt)("p",null,"One of the main threads of work that needs to be complete early in the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"Cwtch Stable roadmap")," is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3976).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},3976:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog5-3d09f11235d2bc53dd5e6f68d231cd53.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/553c6794.bb21a347.js b/build-staging/it/assets/js/553c6794.bb21a347.js new file mode 100644 index 00000000..945be1cb --- /dev/null +++ b/build-staging/it/assets/js/553c6794.bb21a347.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8185],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,s=e.originalType,p=e.parentName,l=i(e,["components","mdxType","originalType","parentName"]),u=c(n),g=a,m=u["".concat(p,".").concat(g)]||u[g]||d[g]||s;return n?r.createElement(m,o(o({ref:t},l),{},{components:n})):r.createElement(m,o({ref:t},l))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=n.length,o=new Array(s);o[0]=g;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[u]="string"==typeof e?e:a,o[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const s={sidebar_position:2},o="Message Formats",i={unversionedId:"components/cwtch/message_formats",id:"components/cwtch/message_formats",title:"Message Formats",description:"Peer to Peer Messages",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/message_formats.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/message_formats",permalink:"/it/security/components/cwtch/message_formats",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch",permalink:"/it/security/category/cwtch"},next:{title:"Key Bundles",permalink:"/it/security/components/cwtch/key_bundles"}},p={},c=[{value:"Peer to Peer Messages",id:"peer-to-peer-messages",level:2},{value:"Context Identifiers",id:"context-identifiers",level:3},{value:"Plaintext / Decrypted Group Messages",id:"plaintext--decrypted-group-messages",level:2},{value:"Encrypted Group Messages",id:"encrypted-group-messages",level:2}],l={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"message-formats"},"Message Formats"),(0,a.kt)("h2",{id:"peer-to-peer-messages"},"Peer to Peer Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"PeerMessage {\n ID string // A unique Message ID (primarily used for acknowledgments)\n Context string // A unique context identifier i.e. im.cwtch.chat\n Data []byte // The context-dependent serialized data packet.\n}\n")),(0,a.kt)("h3",{id:"context-identifiers"},"Context Identifiers"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.raw")," - Data contains a plain text chat message (see: ",(0,a.kt)("a",{parentName:"p",href:"/it/security/components/ui/overlays"},"overlays")," for more information)")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.acknowledgement")," - Data is empty and ID references a previously sent message")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("p",{parentName:"li"},(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.getVal")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"im.cwtch.retVal")," - Used for requesting / returning specific information about a peer. Data contains a serialized ",(0,a.kt)("inlineCode",{parentName:"p"},"peerGetVal")," structure and ",(0,a.kt)("inlineCode",{parentName:"p"},"peerRetVal")," respectively."),(0,a.kt)("pre",{parentName:"li"},(0,a.kt)("code",{parentName:"pre"}," peerGetVal struct {\n Scope string\n Path string\n }\n\n type peerRetVal struct {\n Val string // Serialized path-dependent value\n Exists bool\n }\n")))),(0,a.kt)("h2",{id:"plaintext--decrypted-group-messages"},"Plaintext / Decrypted Group Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},'type DecryptedGroupMessage struct {\n Text string // plaintext of the message\n Onion string // The Cwtch address of the sender\n Timestamp uint64 // A user specified timestamp\n // NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages\n // We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.\n // respect particular group constitutions) can be built on top of group messages, but the underlying groups are\n // now agnostic to those models.\n SignedGroupID []byte \n PreviousMessageSig []byte // A reference to a previous message\n Padding []byte // random bytes of length = 1800 - len(Text)\n}\n')),(0,a.kt)("p",null,"DecryptedGroupMessage contains random padding to a fixed size that is equal to the length of all fixed length fields + 1800. This ensures that all encrypted group messages are equal length."),(0,a.kt)("h2",{id:"encrypted-group-messages"},"Encrypted Group Messages"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server\ntype EncryptedGroupMessage struct {\n Ciphertext []byte\n Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key\n}\n")),(0,a.kt)("p",null,"Calculating the signature requires knowing the groupID of the message, the server the group is associated with and the decrypted group message (and thus, the Group Key). It is (ed25519) signed by the sender of the message, and can be verified using their public Cwtch address key."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/56ee2ea4.e554caa6.js b/build-staging/it/assets/js/56ee2ea4.e554caa6.js new file mode 100644 index 00000000..7b4b2886 --- /dev/null +++ b/build-staging/it/assets/js/56ee2ea4.e554caa6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9195],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>m});var r=n(7294);function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function c(t){for(var e=1;e=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}var l=r.createContext({}),p=function(t){var e=r.useContext(l),n=e;return t&&(n="function"==typeof t?t(e):c(c({},e),t)),n},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var n=t.components,o=t.mdxType,a=t.originalType,l=t.parentName,s=i(t,["components","mdxType","originalType","parentName"]),u=p(n),d=o,m=u["".concat(l,".").concat(d)]||u[d]||f[d]||a;return n?r.createElement(m,c(c({ref:e},s),{},{components:n})):r.createElement(m,c({ref:e},s))}));function m(t,e){var n=arguments,o=e&&e.mdxType;if("string"==typeof t||o){var a=n.length,c=new Array(a);c[0]=d;var i={};for(var l in e)hasOwnProperty.call(e,l)&&(i[l]=e[l]);i.originalType=t,i[u]="string"==typeof t?t:o,c[1]=i;for(var p=2;p{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>c,default:()=>f,frontMatter:()=>a,metadata:()=>i,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:7},c="Bloccare un contatto",i={unversionedId:"chat/block-contact",id:"chat/block-contact",title:"Bloccare un contatto",description:"1. Dalla finestra di una conversazione",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/block-contact.md",sourceDirName:"chat",slug:"/chat/block-contact",permalink:"/it/docs/chat/block-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/block-contact.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Condividere un file",permalink:"/it/docs/chat/share-file"},next:{title:"Sbloccare un contatto",permalink:"/it/docs/chat/unblock-contact"}},l={},p=[],s={toc:p},u="wrapper";function f(t){let{components:e,...n}=t;return(0,o.kt)(u,(0,r.Z)({},s,n,{components:e,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"bloccare-un-contatto"},"Bloccare un contatto"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Dalla finestra di una conversazione"),(0,o.kt)("li",{parentName:"ol"},'Vai su "Impostazioni"'),(0,o.kt)("li",{parentName:"ol"},'Scorri verso il basso fino a "Blocca il contatto"'),(0,o.kt)("li",{parentName:"ol"},'Sposta l\'interruttore su "Blocca contatto"')),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/57d795a6.5de42757.js b/build-staging/it/assets/js/57d795a6.5de42757.js new file mode 100644 index 00000000..c994a1d8 --- /dev/null +++ b/build-staging/it/assets/js/57d795a6.5de42757.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6735],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>y});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=c(r),m=i,y=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return r?n.createElement(y,a(a({ref:t},u),{},{components:r})):n.createElement(y,a({ref:t},u))}));function y(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:i,a[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(7462),i=(r(7294),r(3905));const o={},a="Deployment",l={unversionedId:"deployment",id:"deployment",title:"Deployment",description:"Risk: Binaries are replaced on the website with malicious ones",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/deployment.md",sourceDirName:".",slug:"/deployment",permalink:"/it/security/deployment",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Message Overlays",permalink:"/it/security/components/ui/overlays"},next:{title:"Development",permalink:"/it/security/development"}},s={},c=[{value:"Risk: Binaries are replaced on the website with malicious ones",id:"risk-binaries-are-replaced-on-the-website-with-malicious-ones",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"deployment"},"Deployment"),(0,i.kt)("h2",{id:"risk-binaries-are-replaced-on-the-website-with-malicious-ones"},"Risk: Binaries are replaced on the website with malicious ones"),(0,i.kt)("p",null,(0,i.kt)("strong",{parentName:"p"},"Status: Partially-mitigated")),(0,i.kt)("p",null,"While this process is now mostly automated, should this automation ever be compromised then there is nothing in our current process that would detect this."),(0,i.kt)("p",null,"We need:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Reproducible Builds - we currently use public docker containers for all builds which should allow anyone to compare distributed builds with ones built from source."),(0,i.kt)("li",{parentName:"ul"},"Signed Releases - Open Privacy does not yet maintain a public record of staff public keys. This is likely a necessity for signing released builds and creating an audit chain backed by the organization. This process must be manual by definition.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/59e122e4.b1557b13.js b/build-staging/it/assets/js/59e122e4.b1557b13.js new file mode 100644 index 00000000..93cde310 --- /dev/null +++ b/build-staging/it/assets/js/59e122e4.b1557b13.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6299],{86:s=>{s.exports=JSON.parse('{"label":"testing","permalink":"/it/blog/tags/testing","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/5ae3487b.c6fc1894.js b/build-staging/it/assets/js/5ae3487b.c6fc1894.js new file mode 100644 index 00000000..95418be6 --- /dev/null +++ b/build-staging/it/assets/js/5ae3487b.c6fc1894.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9507],{6271:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/it/blog","blogDescription":"The latest updated on Cwtch development.","blogTitle":"Development Log"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/5beee875.1a7eefd7.js b/build-staging/it/assets/js/5beee875.1a7eefd7.js new file mode 100644 index 00000000..b2e4ec2c --- /dev/null +++ b/build-staging/it/assets/js/5beee875.1a7eefd7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9444],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>g});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var c=a.createContext({}),p=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=p(e.components);return a.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(n),m=r,g=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return n?a.createElement(g,i(i({ref:t},s),{},{components:n})):a.createElement(g,i({ref:t},s))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,i[1]=l;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/it/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"7 giugno 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/it/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/it/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/it/blog/cwtch-developer-documentation"}},c={authorsImageUrls:[void 0]},p=[{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,r.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,r.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{src:n(9964).Z,width:"1005",height:"481"})),(0,r.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,r.kt)("p",null,"There is a ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,r.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-06-05-17-36-v1.11.0-74-g0406/"},"2023-06-05-17-36-v1.11.0-74-g0406"),"."),(0,r.kt)("p",null,"This version has a large number of improvements and bug fixes including:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A new Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor."),(0,r.kt)("li",{parentName:"ul"},"Updated UI font styles"),(0,r.kt)("li",{parentName:"ul"},"Dependency updates, including a new base of Flutter 3.10."),(0,r.kt)("li",{parentName:"ul"},"A fix for stuck file downloading notifications on Android"),(0,r.kt)("li",{parentName:"ul"},"A fix for missing profile images in certain edge cases on Android"),(0,r.kt)("li",{parentName:"ul"},"Japanese, Swedish, and Swahili translation options"),(0,r.kt)("li",{parentName:"ul"},"A new retry peer connection button for prompting Cwtch to prioritize specific connections"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails support"))),(0,r.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9964:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/5cb298ca.f94bfc38.js b/build-staging/it/assets/js/5cb298ca.f94bfc38.js new file mode 100644 index 00000000..121ef895 --- /dev/null +++ b/build-staging/it/assets/js/5cb298ca.f94bfc38.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2909],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(r),m=n,d=h["".concat(l,".").concat(m)]||h[m]||u[m]||o;return r?a.createElement(d,i(i({ref:t},s),{},{components:r})):a.createElement(d,i({ref:t},s))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/it/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"28 aprile 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/it/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/it/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/it/blog/availability-status-profile-attributes"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(3466).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},3466:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/5dc151e9.1beabf93.js b/build-staging/it/assets/js/5dc151e9.1beabf93.js new file mode 100644 index 00000000..0656c6a1 --- /dev/null +++ b/build-staging/it/assets/js/5dc151e9.1beabf93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[923],{3905:(t,e,a)=>{a.d(e,{Zo:()=>s,kt:()=>g});var r=a(7294);function n(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,r)}return a}function i(t){for(var e=1;e=0||(n[a]=t[a]);return n}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(n[a]=t[a])}return n}var d=r.createContext({}),p=function(t){var e=r.useContext(d),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},s=function(t){var e=p(t.components);return r.createElement(d.Provider,{value:e},t.children)},u="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},m=r.forwardRef((function(t,e){var a=t.components,n=t.mdxType,l=t.originalType,d=t.parentName,s=o(t,["components","mdxType","originalType","parentName"]),u=p(a),m=n,g=u["".concat(d,".").concat(m)]||u[m]||c[m]||l;return a?r.createElement(g,i(i({ref:e},s),{},{components:a})):r.createElement(g,i({ref:e},s))}));function g(t,e){var a=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var d in e)hasOwnProperty.call(e,d)&&(o[d]=e[d]);o.originalType=t,o[u]="string"==typeof t?t:n,i[1]=o;for(var p=2;p{a.r(e),a.d(e,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const l={sidebar_position:1},i="Release and Packaging Process",o={unversionedId:"release",id:"release",title:"Release and Packaging Process",description:"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.",source:"@site/developing/release.md",sourceDirName:".",slug:"/release",permalink:"/it/developing/release",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Introduction to Cwtch Development",permalink:"/it/developing/intro"},next:{title:"Building a Cwtch App",permalink:"/it/developing/category/building-a-cwtch-app"}},d={},p=[{value:"Automated Testing",id:"automated-testing",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"UI Nightly Builds",id:"ui-nightly-builds",level:2},{value:"Official Releases",id:"official-releases",level:2},{value:"Reproducible Builds",id:"reproducible-builds",level:3}],s={toc:p},u="wrapper";function c(t){let{components:e,...a}=t;return(0,n.kt)(u,(0,r.Z)({},s,a,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member."),(0,n.kt)("h2",{id:"automated-testing"},"Automated Testing"),(0,n.kt)("p",null,"Drone carries out a suite of automated tests at various stages of the release pipeline."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Test Suite"),(0,n.kt)("th",{parentName:"tr",align:null},"Repository"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"A full exercise of peer-to-peer and group messaging")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"File Sharing Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that file sharing and image downloading work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Automated Download Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch"),(0,n.kt)("td",{parentName:"tr",align:null},"Tests that automated image downloading (e.g. profile pictures) work as expected")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"UI Integration Test"),(0,n.kt)("td",{parentName:"tr",align:null},"cwtch.im/cwtch-ui"),(0,n.kt)("td",{parentName:"tr",align:null},"A suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings")))),(0,n.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,n.kt)("p",null,"Drone produces the following build artifacts for all Cwtch autobindings builds."),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch-sources.jar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"gomobile derived source code for the Android Cwtch library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"android/cwtch.aar"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android Cwtch library. Supports arm, arm64, and amd64.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"linux/libCwtch.so"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.h"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"C header file")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"windows/libCwtch.dll"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 bit shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.arm64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"Arm64 shared library")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"macos/libCwtch.x64.dylib"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null},"x64 shared library")))),(0,n.kt)("h2",{id:"ui-nightly-builds"},"UI Nightly Builds"),(0,n.kt)("p",null,"We make unreleased versions of Cwtch available for testing as ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"Cwtch Nightlies"),"."),(0,n.kt)("p",null,"Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:"),(0,n.kt)("table",null,(0,n.kt)("thead",{parentName:"table"},(0,n.kt)("tr",{parentName:"thead"},(0,n.kt)("th",{parentName:"tr",align:null},"Build Artifact"),(0,n.kt)("th",{parentName:"tr",align:null},"Platform"),(0,n.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,n.kt)("tbody",{parentName:"table"},(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.apk"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Supports arm, arm64, and amd64. Can be sideloaded.")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.aab"),(0,n.kt)("td",{parentName:"tr",align:null},"Android"),(0,n.kt)("td",{parentName:"tr",align:null},"Android App Bundle for publishing to appstores")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"Cwtch-VERSION.dmg"),(0,n.kt)("td",{parentName:"tr",align:null},"MacOS"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.tar.gz"),(0,n.kt)("td",{parentName:"tr",align:null},"Linux"),(0,n.kt)("td",{parentName:"tr",align:null},"Contains the code, libs, and assets in addition to install scripts for various devices")),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-VERSION.zip"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null})),(0,n.kt)("tr",{parentName:"tbody"},(0,n.kt)("td",{parentName:"tr",align:null},"cwtch-installer-VERSION.exe"),(0,n.kt)("td",{parentName:"tr",align:null},"Windows"),(0,n.kt)("td",{parentName:"tr",align:null},"NSIS powered installation wizard")))),(0,n.kt)("p",null,"Nightly builds are regularly purged from the system"),(0,n.kt)("h2",{id:"official-releases"},"Official Releases"),(0,n.kt)("p",null,"The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps."),(0,n.kt)("p",null,"When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. ",(0,n.kt)("inlineCode",{parentName:"p"},"v.1.12.0"),". The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder."),(0,n.kt)("h3",{id:"reproducible-builds"},"Reproducible Builds"),(0,n.kt)("p",null,"We use ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"repliqate")," to provide ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts"},"reproducible build scripts for Cwtch"),"."),(0,n.kt)("p",null,"We update the ",(0,n.kt)("inlineCode",{parentName:"p"},"repliqate-scripts")," repository with scripts for all official releases. Currently only Cwtch bindings are reproducible"))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/5e5faacc.07853952.js b/build-staging/it/assets/js/5e5faacc.07853952.js new file mode 100644 index 00000000..7d281d17 --- /dev/null +++ b/build-staging/it/assets/js/5e5faacc.07853952.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8192],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>h});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function o(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function l(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=n.createContext({}),p=function(t){var e=n.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},u=function(t){var e=p(t.components);return n.createElement(s.Provider,{value:e},t.children)},d="mdxType",c={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,o=t.originalType,s=t.parentName,u=i(t,["components","mdxType","originalType","parentName"]),d=p(a),m=r,h=d["".concat(s,".").concat(m)]||d[m]||c[m]||o;return a?n.createElement(h,l(l({ref:e},u),{},{components:a})):n.createElement(h,l({ref:e},u))}));function h(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var o=a.length,l=new Array(o);l[0]=m;var i={};for(var s in e)hasOwnProperty.call(e,s)&&(i[s]=e[s]);i.originalType=t,i[d]="string"==typeof t?t:r,l[1]=i;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>l,default:()=>c,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const o={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/it/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"27 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"support",permalink:"/it/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/it/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/it/blog/cwtch-bindings-reproducible"}},s={authorsImageUrls:[void 0]},p=[{value:"Constraints on support",id:"constraints-on-support",level:2},{value:"Limitations on general-purpose computing",id:"limitations-on-general-purpose-computing",level:3},{value:"Constraints introduced by the Flutter SDK",id:"constraints-introduced-by-the-flutter-sdk",level:3},{value:"Constraints introduced by Appstore Policy",id:"constraints-introduced-by-appstore-policy",level:3},{value:"CPU Architecture and Cwtch Bindings",id:"cpu-architecture-and-cwtch-bindings",level:3},{value:"Testing and official support",id:"testing-and-official-support",level:3},{value:"End-of-life platforms",id:"end-of-life-platforms",level:3},{value:"How we decide to officially support a platform",id:"how-we-decide-to-officially-support-a-platform",level:2},{value:"Summary of official support",id:"summary-of-official-support",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],u={toc:p},d="wrapper";function c(t){let{components:e,...o}=t;return(0,r.kt)(d,(0,n.Z)({},u,o,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"One of the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,r.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,r.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,r.kt)("p",null,"The questions we aim to answer in this post are: "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,r.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,r.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,r.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,r.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6149).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraints-on-support"},"Constraints on support"),(0,r.kt)("p",null,"From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems. "),(0,r.kt)("p",null,"In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms."),(0,r.kt)("h3",{id:"limitations-on-general-purpose-computing"},"Limitations on general-purpose computing"),(0,r.kt)("p",null,"In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to ",(0,r.kt)("em",{parentName:"p"},"other")," onion services). "),(0,r.kt)("p",null,"On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, ",(0,r.kt)("strong",{parentName:"p"},"blocked entirely"),". "),(0,r.kt)("p",null,"This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind."),(0,r.kt)("p",null,"While we expect that ",(0,r.kt)("a",{parentName:"p",href:"https://gitlab.torproject.org/tpo/core/arti"},"Arti")," will improve the management of onion services and connections, there is no way around the need to have an active process managing such services. "),(0,r.kt)("p",null,"As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable."),(0,r.kt)("p",null,"We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device."),(0,r.kt)("h3",{id:"constraints-introduced-by-the-flutter-sdk"},"Constraints introduced by the Flutter SDK"),(0,r.kt)("p",null,"The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.flutter.dev/development/tools/sdk/release-notes/supported-platforms"},"platforms that are supported by the Flutter SDK"),"."),(0,r.kt)("p",null,"To summarize, as of writing this document those platforms are:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Android API 16 and above (arm, arm64, and amd64)"),(0,r.kt)("li",{parentName:"ul"},"Debian-based Linux Distributions (64-bit only)"),(0,r.kt)("li",{parentName:"ul"},"macOS El Capitan (10.11) and above"),(0,r.kt)("li",{parentName:"ul"},"Windows 7 & above (64-bit only)")),(0,r.kt)("p",null,"To put it plainly, without porting Cwtch UI to a different UI platform ",(0,r.kt)("strong",{parentName:"p"},"we cannot support a 32-bit desktop version"),"."),(0,r.kt)("h3",{id:"constraints-introduced-by-appstore-policy"},"Constraints introduced by Appstore Policy"),(0,r.kt)("p",null,"As of writing, ",(0,r.kt)("a",{parentName:"p",href:"https://developer.android.com/google/play/requirements/target-sdk"},"Google is pushing applications to target API 31 or above"),". This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality."),(0,r.kt)("h3",{id:"cpu-architecture-and-cwtch-bindings"},"CPU Architecture and Cwtch Bindings"),(0,r.kt)("p",null,"We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for."),(0,r.kt)("p",null,"It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Architecture / Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Windows"),(0,r.kt)("th",{parentName:"tr",align:null},"Linux"),(0,r.kt)("th",{parentName:"tr",align:null},"macOS"),(0,r.kt)("th",{parentName:"tr",align:null},"Android"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"arm64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"x86-64 / amd64"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705\ufe0f")))),(0,r.kt)("p",null,'"\ud83d\udfe1" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).'),(0,r.kt)("h3",{id:"testing-and-official-support"},"Testing and official support"),(0,r.kt)("p",null,"As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers")," to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues."),(0,r.kt)("p",null,"We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances."),(0,r.kt)("h3",{id:"end-of-life-platforms"},"End-of-life platforms"),(0,r.kt)("p",null,"Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. ",(0,r.kt)("a",{parentName:"p",href:"https://www.microsoft.com/en-us/windows/end-of-support"},"Windows 7 fell out of support on January 14, 2020"),", Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025."),(0,r.kt)("p",null,"Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also."),(0,r.kt)("p",null,"The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#linux-specific-considerations"},"Cwtch currently requires libc 2.31+"),"."),(0,r.kt)("p",null,"Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#join-the-cwtch-release-candidate-testers-group"},"Cwtch Release Candidate Testers groups")," to help us understand the limitations of Android support across different API versions."),(0,r.kt)("h2",{id:"how-we-decide-to-officially-support-a-platform"},"How we decide to officially support a platform"),(0,r.kt)("p",null,"To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform needs to be officially supported by our development tools")," - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target operating system needs to be supported by the Vendor")," - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"The target platform must be backwards compatible with the most recent version in general use")," - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch ",(0,r.kt)("em",{parentName:"li"},"may")," run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers)."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("strong",{parentName:"li"},"People want to use Cwtch on that platform")," - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!")),(0,r.kt)("h2",{id:"summary-of-official-support"},"Summary of official support"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023). "),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. A version of this table will be ",(0,r.kt)("a",{parentName:"p",href:"/docs/getting-started/supported_platforms"},"maintained as part of the Cwtch Handbook"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/607"},"Known Issues. Specific changes to Cwtch are required for support."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}c.isMDXComponent=!0},6149:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/5e9927d2.f2fc59f6.js b/build-staging/it/assets/js/5e9927d2.f2fc59f6.js new file mode 100644 index 00000000..6fabc71f --- /dev/null +++ b/build-staging/it/assets/js/5e9927d2.f2fc59f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5398],{3905:(e,r,t)=>{t.d(r,{Zo:()=>s,kt:()=>m});var o=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function n(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,o)}return t}function a(e){for(var r=1;r=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=o.createContext({}),p=function(e){var r=o.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},s=function(e){var r=p(e.components);return o.createElement(l.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return o.createElement(o.Fragment,{},r)}},d=o.forwardRef((function(e,r){var t=e.components,i=e.mdxType,n=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(t),d=i,m=u["".concat(l,".").concat(d)]||u[d]||f[d]||n;return t?o.createElement(m,a(a({ref:r},s),{},{components:t})):o.createElement(m,a({ref:r},s))}));function m(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var n=t.length,a=new Array(n);a[0]=d;var c={};for(var l in r)hasOwnProperty.call(r,l)&&(c[l]=r[l]);c.originalType=e,c[u]="string"==typeof e?e:i,a[1]=c;for(var p=2;p{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>n,metadata:()=>c,toc:()=>p});var o=t(7462),i=(t(7294),t(3905));const n={sidebar_position:5},a="Sbloccare profili crittografati",c={unversionedId:"profiles/unlock-profile",id:"profiles/unlock-profile",title:"Sbloccare profili crittografati",description:"Quando riavvii Cwtch, se hai usato una password per proteggere il tuo profilo, esso non verr\xe0 caricato per impostazione predefinita, e dovrai sbloccarlo.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/unlock-profile.md",sourceDirName:"profiles",slug:"/profiles/unlock-profile",permalink:"/it/docs/profiles/unlock-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/unlock-profile.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Modificare la tua immagine del profilo",permalink:"/it/docs/profiles/change-profile-image"},next:{title:"Eliminare un profilo",permalink:"/it/docs/profiles/delete-profile"}},l={},p=[],s={toc:p},u="wrapper";function f(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,o.Z)({},s,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"sbloccare-profili-crittografati"},"Sbloccare profili crittografati"),(0,i.kt)("p",null,"Quando riavvii Cwtch, se hai usato una ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-password/"},"password")," per proteggere il tuo profilo, esso non verr\xe0 caricato per impostazione predefinita, e dovrai sbloccarlo."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Clicca sull'icona di sblocco rosa ",(0,i.kt)("img",{src:"/img/lock_open-24px.webp",className:"ui-button",alt:"sblocca icona"})),(0,i.kt)("li",{parentName:"ol"},"Inserisci la tua password"),(0,i.kt)("li",{parentName:"ol"},"Clicca su \u201cSblocca il tuo profilo\u201d")),(0,i.kt)("p",null,"Vedi anche: ",(0,i.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Manuale sulla sicurezza di Cwtch: Crittografia del profilo & spazio di archiviazione")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6048.e7c7c18a.js b/build-staging/it/assets/js/6048.e7c7c18a.js new file mode 100644 index 00000000..bac03d84 --- /dev/null +++ b/build-staging/it/assets/js/6048.e7c7c18a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6048],{9058:(e,t,a)=>{a.d(t,{Z:()=>p});var l=a(7294),r=a(6010),n=a(7961),o=a(7524),s=a(9960),i=a(5999);const m={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};function c(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,r.Z)(m.sidebar,"thin-scrollbar"),"aria-label":(0,i.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,r.Z)(m.sidebarItemTitle,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,r.Z)(m.sidebarItemList,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:m.sidebarItem},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:m.sidebarItemLink,activeClassName:m.sidebarItemLinkActive},e.title)))))))}var u=a(3102);function d(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function g(e){return l.createElement(u.Zo,{component:d,props:e})}function h(e){let{sidebar:t}=e;const a=(0,o.i)();return t?.items.length?"mobile"===a?l.createElement(g,{sidebar:t}):l.createElement(c,{sidebar:t}):null}function p(e){const{sidebar:t,toc:a,children:o,...s}=e,i=t&&t.items.length>0;return l.createElement(n.Z,s,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(h,{sidebar:t}),l.createElement("main",{className:(0,r.Z)("col",{"col--7":i,"col--9 col--offset-1":!i}),itemScope:!0,itemType:"http://schema.org/Blog"},o),a&&l.createElement("div",{className:"col col--2"},a))))}},390:(e,t,a)=>{a.d(t,{Z:()=>A});var l=a(7294),r=a(6010),n=a(9460),o=a(4996);function s(e){let{children:t,className:a}=e;const{frontMatter:r,assets:s}=(0,n.C)(),{withBaseUrl:i}=(0,o.C)(),m=s.image??r.image;return l.createElement("article",{className:a,itemProp:"blogPost",itemScope:!0,itemType:"http://schema.org/BlogPosting"},m&&l.createElement("meta",{itemProp:"image",content:i(m,{absolute:!0})}),t)}var i=a(9960);const m={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,n.C)(),{permalink:s,title:c}=a,u=o?"h1":"h2";return l.createElement(u,{className:(0,r.Z)(m.title,t),itemProp:"headline"},o?c:l.createElement(i.Z,{itemProp:"url",to:s},c))}var u=a(5999),d=a(8824);const g={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,d.c)();return t=>{const a=Math.ceil(t);return e(a,(0,u.I)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return l.createElement(l.Fragment,null,a(t))}function p(e){let{date:t,formattedDate:a}=e;return l.createElement("time",{dateTime:t,itemProp:"datePublished"},a)}function b(){return l.createElement(l.Fragment,null," \xb7 ")}function E(e){let{className:t}=e;const{metadata:a}=(0,n.C)(),{date:o,formattedDate:s,readingTime:i}=a;return l.createElement("div",{className:(0,r.Z)(g.container,"margin-vert--md",t)},l.createElement(p,{date:o,formattedDate:s}),void 0!==i&&l.createElement(l.Fragment,null,l.createElement(b,null),l.createElement(h,{readingTime:i})))}function f(e){return e.href?l.createElement(i.Z,e):l.createElement(l.Fragment,null,e.children)}function v(e){let{author:t,className:a}=e;const{name:n,title:o,url:s,imageURL:i,email:m}=t,c=s||m&&`mailto:${m}`||void 0;return l.createElement("div",{className:(0,r.Z)("avatar margin-bottom--sm",a)},i&&l.createElement(f,{href:c,className:"avatar__photo-link"},l.createElement("img",{className:"avatar__photo",src:i,alt:n})),n&&l.createElement("div",{className:"avatar__intro",itemProp:"author",itemScope:!0,itemType:"https://schema.org/Person"},l.createElement("div",{className:"avatar__name"},l.createElement(f,{href:c,itemProp:"url"},l.createElement("span",{itemProp:"name"},n))),o&&l.createElement("small",{className:"avatar__subtitle",itemProp:"description"},o)))}const P={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function N(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,n.C)();if(0===a.length)return null;const s=a.every((e=>{let{name:t}=e;return!t}));return l.createElement("div",{className:(0,r.Z)("margin-top--md margin-bottom--sm",s?P.imageOnlyAuthorRow:"row",t)},a.map(((e,t)=>l.createElement("div",{className:(0,r.Z)(!s&&"col col--6",s?P.imageOnlyAuthorCol:P.authorCol),key:t},l.createElement(v,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})))))}function _(){return l.createElement("header",null,l.createElement(c,null),l.createElement(E,null),l.createElement(N,null))}var k=a(8780),Z=a(1506);function I(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,n.C)();return l.createElement("div",{id:o?k.blogPostContainerID:void 0,className:(0,r.Z)("markdown",a),itemProp:"articleBody"},l.createElement(Z.Z,null,t))}var C=a(4881),w=a(1526),T=a(7462);function y(){return l.createElement("b",null,l.createElement(u.Z,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts"},"Read More"))}function F(e){const{blogPostTitle:t,...a}=e;return l.createElement(i.Z,(0,T.Z)({"aria-label":(0,u.I)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t})},a),l.createElement(y,null))}const L={blogPostFooterDetailsFull:"blogPostFooterDetailsFull_mRVl"};function B(){const{metadata:e,isBlogPostPage:t}=(0,n.C)(),{tags:a,title:o,editUrl:s,hasTruncateMarker:i}=e,m=!t&&i,c=a.length>0;return c||m||s?l.createElement("footer",{className:(0,r.Z)("row docusaurus-mt-lg",t&&L.blogPostFooterDetailsFull)},c&&l.createElement("div",{className:(0,r.Z)("col",{"col--9":m})},l.createElement(w.Z,{tags:a})),t&&s&&l.createElement("div",{className:"col margin-top--sm"},l.createElement(C.Z,{editUrl:s})),m&&l.createElement("div",{className:(0,r.Z)("col text--right",{"col--3":c})},l.createElement(F,{blogPostTitle:o,to:e.permalink}))):null}function A(e){let{children:t,className:a}=e;const o=function(){const{isBlogPostPage:e}=(0,n.C)();return e?void 0:"margin-bottom--xl"}();return l.createElement(s,{className:(0,r.Z)(o,a)},l.createElement(_,null),l.createElement(I,null,t),l.createElement(B,null))}},9460:(e,t,a)=>{a.d(t,{C:()=>s,n:()=>o});var l=a(7294),r=a(902);const n=l.createContext(null);function o(e){let{children:t,content:a,isBlogPostPage:r=!1}=e;const o=function(e){let{content:t,isBlogPostPage:a}=e;return(0,l.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:r});return l.createElement(n.Provider,{value:o},t)}function s(){const e=(0,l.useContext)(n);if(null===e)throw new r.i6("BlogPostProvider");return e}},8824:(e,t,a)=>{a.d(t,{c:()=>m});var l=a(7294),r=a(2263);const n=["zero","one","two","few","many","other"];function o(e){return n.filter((t=>e.includes(t)))}const s={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function i(){const{i18n:{currentLocale:e}}=(0,r.Z)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:o(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),s}}),[e])}function m(){const e=i();return{selectMessage:(t,a)=>function(e,t,a){const l=e.split("|");if(1===l.length)return l[0];l.length>a.pluralForms.length&&console.error(`For locale=${a.locale}, a maximum of ${a.pluralForms.length} plural forms are expected (${a.pluralForms.join(",")}), but the message contains ${l.length}: ${e}`);const r=a.select(t),n=a.pluralForms.indexOf(r);return l[Math.min(n,l.length-1)]}(a,t,e)}}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/61794344.d52d09f1.js b/build-staging/it/assets/js/61794344.d52d09f1.js new file mode 100644 index 00000000..04429c9c --- /dev/null +++ b/build-staging/it/assets/js/61794344.d52d09f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6232],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(a),u=o,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||r;return a?n.createElement(m,i(i({ref:t},p),{},{components:a})):n.createElement(m,i({ref:t},p))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/it/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"30 giugno 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/it/blog/cwtch-nightly-1-12"}},s={authorsImageUrls:[void 0]},c=[{value:"Update on the Cwtch Stable Roadmap",id:"update-on-the-cwtch-stable-roadmap",level:2},{value:"Next Steps, Refinements, Additional Work",id:"next-steps-refinements-additional-work",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(h,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,o.kt)("p",null,"This post ",(0,o.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h2",{id:"update-on-the-cwtch-stable-roadmap"},"Update on the Cwtch Stable Roadmap"),(0,o.kt)("p",null,"Back in March we extended and updated several goals from ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"our January roadmap")," that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing."),(0,o.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \ud83d\udd52 reprioritized)"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/#official-releases"},"Release Process")),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/release/"},"Packaging Documentation")),(0,o.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots. \ud83d\udfe1 - new features are documented to the standards outlined in new ",(0,o.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"documentation style guide"),", and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries \u2705 - ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/developing/category/building-a-cwtch-app"},"Building a Cwtch App")),(0,o.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch \ud83d\udd52 - this effort has been delayed pending other higher priority work. "))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"An implementation of ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")," \ud83d\udfe1 - currently in ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch/pulls/518"},"active development")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information \u2705 - released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")),(0,o.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")," \ud83d\udfe1\ud83d\udd52 - new Network Management code was released in ",(0,o.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12"),". We now believe these changes will be complete in Cwtch Beta 1.13."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. \ud83d\udfe1 - we have recently made a few updates to ",(0,o.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks."),(0,o.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \ud83d\udd52 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below)."),(0,o.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,o.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")," \ud83d\udfe1 - we have already launched an environment for testing ",(0,o.kt)("a",{parentName:"li",href:"/docs/platforms/tails"},"Tails"),". Other platforms are underway."))),(0,o.kt)("li",{parentName:"ul"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,o.kt)("ul",{parentName:"li"},(0,o.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable."),(0,o.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,o.kt)("h2",{id:"next-steps-refinements-additional-work"},"Next Steps, Refinements, Additional Work"),(0,o.kt)("p",null,"As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments. "),(0,o.kt)("p",null,"Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like."),(0,o.kt)("p",null,"However, ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-nightly-1-12"},"Cwtch Beta 1.12")," featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing."),(0,o.kt)("p",null,"The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup."),(0,o.kt)("p",null,"We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards."),(0,o.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,o.kt)("h2",{id:"get-involved"},"Get Involved"),(0,o.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,o.kt)("p",null,"We also also updated our guides on ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,o.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,o.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,o.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,o.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6275ceb4.3ba97e15.js b/build-staging/it/assets/js/6275ceb4.3ba97e15.js new file mode 100644 index 00000000..c9e43b82 --- /dev/null +++ b/build-staging/it/assets/js/6275ceb4.3ba97e15.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6555],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),c=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},d=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),d=a,m=h["".concat(s,".").concat(d)]||h[d]||u[d]||i;return n?o.createElement(m,r(r({ref:t},p),{},{components:n})):o.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,r=new Array(i);r[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const i={title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/it/blog/cwtch-documentation",source:"@site/blog/2023-03-10-cwtch-documentation.md",title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",date:"2023-03-10T00:00:00.000Z",formattedDate:"10 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"documentation",permalink:"/it/blog/tags/documentation"},{label:"security-handbook",permalink:"/it/blog/tags/security-handbook"}],readingTime:2.57,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Updates to Cwtch Documentation",description:" In this development log we will highlight some of the major documentation updates over the last few weeks.",slug:"cwtch-documentation",tags:["cwtch","cwtch-stable","documentation","security-handbook"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.11",permalink:"/it/blog/cwtch-nightly-1-11"},nextItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/it/blog/autobindings-ii"}},s={authorsImageUrls:[void 0]},c=[{value:"Cwtch Secure Development Handbook",id:"cwtch-secure-development-handbook",level:2},{value:"Volunteer Development",id:"volunteer-development",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},h="wrapper";function u(e){let{components:t,...i}=e;return(0,a.kt)(h,(0,o.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(3466).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"cwtch-secure-development-handbook"},"Cwtch Secure Development Handbook"),(0,a.kt)("p",null,"One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions."),(0,a.kt)("p",null,"We have ",(0,a.kt)("a",{parentName:"p",href:"/security/intro"},"now ported the the handbook to this documentation site"),", along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation. "),(0,a.kt)("h2",{id:"volunteer-development"},"Volunteer Development"),(0,a.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,a.kt)("p",null,"We also also updated our guides on ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,a.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,a.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,a.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"We still have more work to do on the documentation front:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Ensuring all pages ",(0,a.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"implement the new documentation style guide"),", and include appropriate screenshots and descriptions."),(0,a.kt)("li",{parentName:"ul"},"Expanding the security handbook to provide information on ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"reproducible builds"),", ",(0,a.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"the new Cwtch Stable API")," and upcoming improvements around fuzz testing."),(0,a.kt)("li",{parentName:"ul"},"Creating new documentation sections on the ",(0,a.kt)("a",{parentName:"li",href:"/blog/autobindings"},"libCwtch autobindings API")," and building applications on top of Cwtch.")),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},3466:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/644e0e81.b5ab2ba3.js b/build-staging/it/assets/js/644e0e81.b5ab2ba3.js new file mode 100644 index 00000000..cbd9d4ef --- /dev/null +++ b/build-staging/it/assets/js/644e0e81.b5ab2ba3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4561],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var i=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(n),m=r,h=p["".concat(l,".").concat(m)]||p[m]||d[m]||a;return n?i.createElement(h,o(o({ref:t},u),{},{components:n})):i.createElement(h,o({ref:t},u))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,o=new Array(a);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[p]="string"==typeof e?e:r,o[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var i=n(7462),r=(n(7294),n(3905));const a={},o="Image Previews",s={unversionedId:"components/ui/image_previews",id:"components/ui/image_previews",title:"Image Previews",description:"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/image_previews.md",sourceDirName:"components/ui",slug:"/components/ui/image_previews",permalink:"/it/security/components/ui/image_previews",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Android Service",permalink:"/it/security/components/ui/android"},next:{title:"Input",permalink:"/it/security/components/ui/input"}},l={},c=[{value:"KnownRisks",id:"knownrisks",level:2},{value:"Other Applications and/or the OS Inferring Information from Images",id:"other-applications-andor-the-os-inferring-information-from-images",level:2},{value:"Malicious Images Crashing or otherwise Compromising Cwtch",id:"malicious-images--crashing-or-otherwise-compromising-cwtch",level:2},{value:"Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata",id:"malicious-images-rendering-differently-on-different-platforms-potentially-exposing-metadata",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"image-previews"},"Image Previews"),(0,r.kt)("p",null,"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes."),(0,r.kt)("p",null,"For now, we only support single-image messages, and any image editing/cropping will have to be done in a separate application. As we mention in the filesharing FAQ, image files also frequently contain significant hidden metadata, and you should only share them with people you trust."),(0,r.kt)("h2",{id:"knownrisks"},"KnownRisks"),(0,r.kt)("h2",{id:"other-applications-andor-the-os-inferring-information-from-images"},"Other Applications and/or the OS Inferring Information from Images"),(0,r.kt)("p",null,"Images must be stored somewhere, and for now we have chosen to store them unencrypted on the file system. We have done this for 2 reasons:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"In order to support more powerful file sharing schemes like rehosting we require the ability to efficiently scan files and deliver chunks - doing this through an encrypted database layer would harm performance."),(0,r.kt)("li",{parentName:"ol"},"This information always has to transit the application boundary (either via display drivers, or storing and viewing the file in an external application) - there is nothing that Cwtch can do after that point in any case.")),(0,r.kt)("h2",{id:"malicious-images--crashing-or-otherwise-compromising-cwtch"},"Malicious Images Crashing or otherwise Compromising Cwtch"),(0,r.kt)("p",null,"Flutter uses Skia to render Images. While the underlying code is memory unsafe, it is ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/google/skia/tree/main/fuzz"},"extensively fuzzed")," as part of regular development."),(0,r.kt)("p",null,"We also conduct our own fuzz testing of Cwtch components. In that analysis we found a single crash bug related to a malformed GIF file that caused the renderer to allocate a ridiculous amount of memory (and eventually be refused by the kernel). To prevent this from impacting Cwtch we have adopted the policy of always enabling a maximum ",(0,r.kt)("inlineCode",{parentName:"p"},"cacheWidth")," and/or ",(0,r.kt)("inlineCode",{parentName:"p"},"cacheHeight")," for Image widgets."),(0,r.kt)("h2",{id:"malicious-images-rendering-differently-on-different-platforms-potentially-exposing-metadata"},"Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata"),(0,r.kt)("p",null,"Recently ",(0,r.kt)("a",{parentName:"p",href:"https://www.da.vidbuchanan.co.uk/widgets/pngdiff/"},"a bug was found in Apple's png parser")," which would cause an image to render differently on Apple devices as it would on non-Apple devices."),(0,r.kt)("p",null,"We conducted a few tests on our Mac builds and could not replicate this issue for Flutter (because all Flutter builds use Skia for rendering), however we will continue to include such cases in our testing corpus."),(0,r.kt)("p",null,"For now image previews will remain experimental and opt-in."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6648656d.67321fde.js b/build-staging/it/assets/js/6648656d.67321fde.js new file mode 100644 index 00000000..4006709a --- /dev/null +++ b/build-staging/it/assets/js/6648656d.67321fde.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3026],{2490:t=>{t.exports=JSON.parse('{"title":"Conversations","slug":"/category/conversations","permalink":"/it/docs/category/conversations","navigation":{"previous":{"title":"Setting Profile Attributes","permalink":"/it/docs/profiles/profile-info"},"next":{"title":"Un\'introduzione alla chat p2p di Cwtch","permalink":"/it/docs/chat/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/66f0cf59.0da7321c.js b/build-staging/it/assets/js/66f0cf59.0da7321c.js new file mode 100644 index 00000000..1771466f --- /dev/null +++ b/build-staging/it/assets/js/66f0cf59.0da7321c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3588],{6331:t=>{t.exports=JSON.parse('{"title":"Getting started","slug":"/category/getting-started","permalink":"/it/docs/category/getting-started","navigation":{"previous":{"title":"Che cos\u2019\xe8 Cwtch?","permalink":"/it/docs/intro"},"next":{"title":"Supported Platforms","permalink":"/it/docs/getting-started/supported_platforms"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6875c492.a3d95c11.js b/build-staging/it/assets/js/6875c492.a3d95c11.js new file mode 100644 index 00000000..3a83b038 --- /dev/null +++ b/build-staging/it/assets/js/6875c492.a3d95c11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8610],{9703:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(5999),r=a(2244);function s(e){const{metadata:t}=e,{previousPage:a,nextPage:s}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,l.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(r.Z,{permalink:a,title:n.createElement(l.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),s&&n.createElement(r.Z,{permalink:s,title:n.createElement(l.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>s});var n=a(7294),l=a(9460),r=a(390);function s(e){let{items:t,component:a=r.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(l.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}},1714:(e,t,a)=>{a.r(t),a.d(t,{default:()=>E});var n=a(7294),l=a(6010),r=a(5999),s=a(8824),o=a(1944),i=a(5281),g=a(9960),c=a(9058),m=a(9703),u=a(197),p=a(9985);function d(e){const t=function(){const{selectMessage:e}=(0,s.c)();return t=>e(t,(0,r.I)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,r.I)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function h(e){let{tag:t}=e;const a=d(t);return n.createElement(n.Fragment,null,n.createElement(o.d,{title:a}),n.createElement(u.Z,{tag:"blog_tags_posts"}))}function b(e){let{tag:t,items:a,sidebar:l,listMetadata:s}=e;const o=d(t);return n.createElement(c.Z,{sidebar:l},n.createElement("header",{className:"margin-bottom--xl"},n.createElement("h1",null,o),n.createElement(g.Z,{href:t.allTagsPath},n.createElement(r.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page"},"View All Tags"))),n.createElement(p.Z,{items:a}),n.createElement(m.Z,{metadata:s}))}function E(e){return n.createElement(o.FG,{className:(0,l.Z)(i.k.wrapper.blogPages,i.k.page.blogTagPostListPage)},n.createElement(h,e),n.createElement(b,e))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/68c206b4.e35aacf5.js b/build-staging/it/assets/js/68c206b4.e35aacf5.js new file mode 100644 index 00000000..c368bf85 --- /dev/null +++ b/build-staging/it/assets/js/68c206b4.e35aacf5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3936],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>g});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(r),d=a,g=u["".concat(l,".").concat(d)]||u[d]||m[d]||i;return r?n.createElement(g,o(o({ref:t},p),{},{components:r})):n.createElement(g,o({ref:t},p))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:a,o[1]=c;for(var s=2;s{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var n=r(7462),a=(r(7294),r(3905));const i={sidebar_position:2},o="Modalit\xe0 chiara/scura e scomposizione dei temi",c={unversionedId:"settings/appearance/light-dark-mode",id:"settings/appearance/light-dark-mode",title:"Modalit\xe0 chiara/scura e scomposizione dei temi",description:"1. Clicca sull'icona impostazione",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/light-dark-mode.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/light-dark-mode",permalink:"/it/docs/settings/appearance/light-dark-mode",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/light-dark-mode.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cambia lingua",permalink:"/it/docs/settings/appearance/change-language"},next:{title:"Colonne dell' IU (Interfaccia Utente)",permalink:"/it/docs/settings/appearance/ui-columns"}},l={},s=[],p={toc:s},u="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"modalit\xe0-chiarascura-e-scomposizione-dei-temi"},"Modalit\xe0 chiara/scura e scomposizione dei temi"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Clicca sull'icona impostazione"),(0,a.kt)("li",{parentName:"ol"},'Puoi scegliere un tema chiaro o scuro interagendo con l\'interruttore "usa temi chiari"'),(0,a.kt)("li",{parentName:"ol"},"Utilizzando il menu a tendina \u201ctema colori\u201d, scegli un tema che ti piace"),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("ol",{parentName:"li"},(0,a.kt)("li",{parentName:"ol"},"Cwtch: toni di viola"),(0,a.kt)("li",{parentName:"ol"},"Fantasma: toni di grigio"),(0,a.kt)("li",{parentName:"ol"},"Sirena: toni di turchese e viola"),(0,a.kt)("li",{parentName:"ol"},"Mezzanotte: toni neri e grigi"),(0,a.kt)("li",{parentName:"ol"},"Neon 1: toni viola e rosa"),(0,a.kt)("li",{parentName:"ol"},"Neon 2: toni viola e turchese"),(0,a.kt)("li",{parentName:"ol"},"Zucca: toni viola e arancione"),(0,a.kt)("li",{parentName:"ol"},"Strega: toni verdi e rosa"),(0,a.kt)("li",{parentName:"ol"},"Vampiro: toni viola e rossi")))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6a78f460.0e1fdfda.js b/build-staging/it/assets/js/6a78f460.0e1fdfda.js new file mode 100644 index 00000000..99184517 --- /dev/null +++ b/build-staging/it/assets/js/6a78f460.0e1fdfda.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[439],{3905:(t,e,a)=>{a.d(e,{Zo:()=>c,kt:()=>d});var i=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function o(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var s=i.createContext({}),p=function(t){var e=i.useContext(s),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},c=function(t){var e=p(t.components);return i.createElement(s.Provider,{value:e},t.children)},u="mdxType",f={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},h=i.forwardRef((function(t,e){var a=t.components,r=t.mdxType,n=t.originalType,s=t.parentName,c=l(t,["components","mdxType","originalType","parentName"]),u=p(a),h=r,d=u["".concat(s,".").concat(h)]||u[h]||f[h]||n;return a?i.createElement(d,o(o({ref:e},c),{},{components:a})):i.createElement(d,o({ref:e},c))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var n=a.length,o=new Array(n);o[0]=h;var l={};for(var s in e)hasOwnProperty.call(e,s)&&(l[s]=e[s]);l.originalType=t,l[u]="string"==typeof t?t:r,o[1]=l;for(var p=2;p{a.r(e),a.d(e,{assets:()=>s,contentTitle:()=>o,default:()=>f,frontMatter:()=>n,metadata:()=>l,toc:()=>p});var i=a(7462),r=(a(7294),a(3905));const n={title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/availability-status-profile-attributes",source:"@site/blog/2023-04-06-availability-and-profile-attributes.md",title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",date:"2023-04-06T00:00:00.000Z",formattedDate:"6 aprile 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"nightly",permalink:"/it/blog/tags/nightly"}],readingTime:1.445,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Availability Status and Profile Attributes",description:"Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.",slug:"availability-status-profile-attributes",tags:["cwtch","cwtch-stable","nightly"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/it/blog/cwtch-developer-documentation"},nextItem:{title:"Cwtch Stable Roadmap Update",permalink:"/it/blog/cwtch-stable-roadmap-update"}},s={authorsImageUrls:[void 0]},p=[{value:"Availability Status",id:"availability-status",level:2},{value:"Profile Attributes",id:"profile-attributes",level:2},{value:"Downloading the Nightly",id:"downloading-the-nightly",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},u="wrapper";function f(t){let{components:e,...n}=t;return(0,r.kt)(u,(0,i.Z)({},c,n,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Two new Cwtch features are now available to test in nightly: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")," and ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information"),"."),(0,r.kt)("p",null,"Additionally, we have also published draft guidance on ",(0,r.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"running Cwtch on Tails")," that we would like volunteers to test and report back on."),(0,r.kt)("p",null,"The Open Privacy Research Society have ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like\nours with a ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("h2",{id:"availability-status"},"Availability Status"),(0,r.kt)("p",null,'New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".'),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(4940).Z},(0,r.kt)("img",{src:a(1859).Z,width:"442",height:"233"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/availability-status"},"Availability Status")),(0,r.kt)("h2",{id:"profile-attributes"},"Profile Attributes"),(0,r.kt)("p",null,"Also new is the ability to augment your profile with a few small pieces of ",(0,r.kt)("strong",{parentName:"p"},"public")," information."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(2243).Z},(0,r.kt)("img",{src:a(3506).Z,width:"730",height:"342"}))),(0,r.kt)("figcaption",null)),(0,r.kt)("p",null,"Read more: ",(0,r.kt)("a",{parentName:"p",href:"/docs/profiles/profile-info"},"Profile Information")),(0,r.kt)("h2",{id:"downloading-the-nightly"},"Downloading the Nightly"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"Nightly builds")," are available from our build server. Download links for ",(0,r.kt)("strong",{parentName:"p"},"2023-04-05-18-28-v1.11.0-7-g0290")," are available below."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Windows: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-win-2023-04-05-18-28-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Linux: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Mac: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-macos-2023-04-05-14-27-v1.11.0-7-g0290/")),(0,r.kt)("li",{parentName:"ul"},"Android: ",(0,r.kt)("a",{parentName:"li",href:"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"},"https://build.openprivacy.ca/files/flwtch-2023-04-05-18-27-v1.11.0-7-g0290/"))),(0,r.kt)("p",null,"Please see the contribution documentation for advice on ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}f.isMDXComponent=!0},2243:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},4940:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/files/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},3506:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/attributes-set-c412ff3d1c5116b11f01cbc56fe1f972.png"},1859:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/status-tooltip-busy-set-5764389ebf8112a9a420c911c424abe5.png"},4515:(t,e,a)=>{a.d(e,{Z:()=>i});const i=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6b44a42a.1528fa0c.js b/build-staging/it/assets/js/6b44a42a.1528fa0c.js new file mode 100644 index 00000000..159a65fa --- /dev/null +++ b/build-staging/it/assets/js/6b44a42a.1528fa0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4071],{4642:a=>{a.exports=JSON.parse('{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable","allTagsPath":"/it/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6c4339db.4177106d.js b/build-staging/it/assets/js/6c4339db.4177106d.js new file mode 100644 index 00000000..6215a112 --- /dev/null +++ b/build-staging/it/assets/js/6c4339db.4177106d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8795],{6705:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/security-handbook","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/6e2435dc.3f74bf5b.js b/build-staging/it/assets/js/6e2435dc.3f74bf5b.js new file mode 100644 index 00000000..8020d328 --- /dev/null +++ b/build-staging/it/assets/js/6e2435dc.3f74bf5b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5861],{3905:(e,t,o)=>{o.d(t,{Zo:()=>p,kt:()=>m});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function i(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function a(e){for(var t=1;t=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),o=t;return e&&(o="function"==typeof e?e(t):a(a({},t),e)),o},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(o),f=r,m=u["".concat(c,".").concat(f)]||u[f]||d[f]||i;return o?n.createElement(m,a(a({ref:t},p),{},{components:o})):n.createElement(m,a({ref:t},p))}));function m(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=o.length,a=new Array(i);a[0]=f;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:r,a[1]=l;for(var s=2;s{o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=o(7462),r=(o(7294),o(3905));const i={sidebar_position:5},a="Tor",l={unversionedId:"tor",id:"tor",title:"Tor",description:'Cwtch utilizza Tor per routing e connessioni. L\'utilizzo dei servizi nascosti di Tor per ospitare profili e connessioni "effimere" generate al volo durante la creazione di una connessione fornisce forti garanzie di anonimato agli utenti di Cwtch.',source:"@site/i18n/it/docusaurus-plugin-content-docs/current/tor.md",sourceDirName:".",slug:"/tor",permalink:"/it/docs/tor",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/tor.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"QR Codes",permalink:"/it/docs/settings/experiments/qrcodes"},next:{title:"Contribute",permalink:"/it/docs/category/contribute"}},c={},s=[{value:"Pannello Tor",id:"pannello-tor",level:2},{value:"Resetta Tor",id:"resetta-tor",level:3},{value:"Abilita la cache del Consenso Tor",id:"abilita-la-cache-del-consenso-tor",level:3},{value:"Configurazione avanzata di Tor",id:"configurazione-avanzata-di-tor",level:3}],p={toc:s},u="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(u,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"tor"},"Tor"),(0,r.kt)("p",null,"Cwtch utilizza ",(0,r.kt)("a",{parentName:"p",href:"https://www.torproject.org/"},"Tor"),' per routing e connessioni. L\'utilizzo dei servizi nascosti di Tor per ospitare profili e connessioni "effimere" generate al volo durante la creazione di una connessione fornisce forti garanzie di anonimato agli utenti di Cwtch.'),(0,r.kt)("h2",{id:"pannello-tor"},"Pannello Tor"),(0,r.kt)("p",null,"Dato che stiamo aggiungendo un ulteriore livello di rete a Cwtch, forniamo un pannello per visualizzare lo stato della rete Tor e apportare modifiche. Per accedervi"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"dal pannello Elenco profili, fare clic sull'icona Tor ",(0,r.kt)("img",{alt:"icona di tor",src:o(4525).Z,width:"32",height:"32"})),(0,r.kt)("li",{parentName:"ol"},"Visualizza lo stato della rete tor")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"Stato Tor: Online\nVersione Tor: 0.4.6.9\n")),(0,r.kt)("h3",{id:"resetta-tor"},"Resetta Tor"),(0,r.kt)("p",null,"La rete Tor stessa pu\xf2 occasionalmente avere connessioni obsolete che non vengono rilevate immediatamente da essa o da Cwtch (cerchiamo continuamente di introdurre miglioramenti a riguardo). A volte un utente pu\xf2 trovare contatti o gruppi visualizzati offline che ritiene dovrebbero invece essere online. Se vuoi riavviare tutte le connessioni di rete in Cwtch, forniamo un meccanismo per riavviare tor dall'interno dell'app. Il pulsante ",(0,r.kt)("strong",{parentName:"p"},"reset")," riavvier\xe0 Tor dall'interno dell'applicazione Cwtch."),(0,r.kt)("h3",{id:"abilita-la-cache-del-consenso-tor"},"Abilita la cache del Consenso Tor"),(0,r.kt)("p",null,"Come impostazione predefinita, avviamo un nuovo processo Tor ogni volta che l'app si avvia, e ci\xf3 richiede il download di un qualche stato di rete Tor prima che possa iniziare. Questo processo non \xe8 istantaneo. Se vuoi velocizzare gli avvii futuri di Cwtch, puoi abilitare la memorizzazione nella cache del Consenso Tor. Se riscontri un problema di avvio in cui i dati sono obsoleti o danneggiati e Cwtch segnala che non \xe8 possibile avviare Tor, disabilita questa funzione e ",(0,r.kt)("strong",{parentName:"p"},"resetta")," tor nuovamente, e dovrebbe funzionare."),(0,r.kt)("h3",{id:"configurazione-avanzata-di-tor"},"Configurazione avanzata di Tor"),(0,r.kt)("p",null,"Offriamo anche la possibilit\xe0 di fornire opzioni di configurazione Tor avanzate in questa sezione consentendoti di"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"specificare una porta SOCKS personalizzata per connettersi a un processo Tor esistente"),(0,r.kt)("li",{parentName:"ul"},"specificare una porta Controllo personalizzata per connettersi a un processo Tor esistente"),(0,r.kt)("li",{parentName:"ul"},"specificare ulteriori opzioni inserendo ",(0,r.kt)("inlineCode",{parentName:"li"},"torrc")," opzioni personalizzate")))}d.isMDXComponent=!0},4525:(e,t,o)=>{o.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAATrwAAE68BY+aOwwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMUSURBVFiFvZZPiNVVFMc/Z546zkwzOikaxlSSFRklQVBQCEWmmRK1CYIWLabIReC6TdCiVtamlaUlQbhrkfTPiMxF0KoyhtISyjBpgkZszJnGT4vfefXT3u817zfvzYHHvffc8873+zv33HsO9EDUsfna9vUAfBcwlPMrFoWAukQN9WXgNNBQ9wPX/99/l3SDAHArsAMYBG4HXge2R8SXXfJfLeom9Xn1jHpY/UPd3HPgEoED6kn1N3VGfWAxwZeqU/4rzywaeBLYXALfV8dHrSRUHwRWAnek6gfg2Tq+6l7DCWAjcBz4DtgbEedq+qon6ls53p1HUCvzF/IQrcixcdm69wTU9aXlZI671UYr+66KujMfnKvUAXVY/SmP4aB6Za+AV6hvqq8l6Op8B1aqT5au46S6S41ugm9Uj6hbSroNOV6bhehzL5V3uxINdYv6abnGq2vV0Zzfk9Vwm/+Vr9SRhYDfpH7W/JL80lXq8lw3Mg+25t5UCxLvLITAh+rVOe9TB0t7oV6nrlMfyXw42oKA5aO7XCqvoboV+CIifs6EWhoR0yWTbRTNxwhwGHgIOFbhbnfHBICdQDN8/RFxIYkNqePAidQNAOeAMeD3Cl/3qcOdEtgETKj/2KjXAE8BByLieKq/pmi9+oDzFb76qWjP2hFoANNAIyL+zGN4HHilFI1RigjMAWeBdk3o2lbKduX4PEXJnQZmgXuBgxFhgq8GbgHOpJ854IY2/iZbKdtF4FvgLuBi3uWxiDhZ2n8UOAKsAn6haEarCtIscKJTAoeA8YiYocj0IXWotP9jRmMQWAasS7tW8lFETHVK4H3gRos6PwN8DzwGoC6jyHwSdD3wK3Bzha89VSCVBCJiDngaeBsYBk4BO9SRjMpoicAwRTIOtHD1RkR83DGBJHEUeA54jyLMe4E9FnV/TdMM2A7c2cLFofyIaox2m01R7wdeBT4AvgFuoziSCeAJ4GGKXGjKX8CLwAsRMTsfjPmQWK6Oq59k0bmgzuXPHI+pL3lpx9RWajUNaj9F1jfr/VngdJ3O+G/ZO0GaKrbieAAAAABJRU5ErkJggg=="}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/7246b934.ae40e115.js b/build-staging/it/assets/js/7246b934.ae40e115.js new file mode 100644 index 00000000..7be6ed10 --- /dev/null +++ b/build-staging/it/assets/js/7246b934.ae40e115.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6730],{3364:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/cwtch","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/it/blog/tags/cwtch/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/73c8cde5.b5747b40.js b/build-staging/it/assets/js/73c8cde5.b5747b40.js new file mode 100644 index 00000000..bff51757 --- /dev/null +++ b/build-staging/it/assets/js/73c8cde5.b5747b40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2605],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},l=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),m=c(n),d=i,f=m["".concat(p,".").concat(d)]||m[d]||u[d]||a;return n?r.createElement(f,o(o({ref:t},l),{},{components:n})):r.createElement(f,o({ref:t},l))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=d;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[m]="string"==typeof e?e:i,o[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>c});var r=n(7462),i=(n(7294),n(3905));const a={sidebar_position:4},o="Anteprime immagine e immagini del profilo",s={unversionedId:"settings/experiments/image-previews-and-profile-pictures",id:"settings/experiments/image-previews-and-profile-pictures",title:"Anteprime immagine e immagini del profilo",description:"This experiment requires the File Sharing experiment enabled.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/image-previews-and-profile-pictures.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/image-previews-and-profile-pictures",permalink:"/it/docs/settings/experiments/image-previews-and-profile-pictures",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/image-previews-and-profile-pictures.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Condivisione file",permalink:"/it/docs/settings/experiments/file-sharing"},next:{title:"Esperimento Link cliccabili",permalink:"/it/docs/settings/experiments/clickable-links"}},p={},c=[],l={toc:c},m="wrapper";function u(e){let{components:t,...n}=e;return(0,i.kt)(m,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"anteprime-immagine-e-immagini-del-profilo"},"Anteprime immagine e immagini del profilo"),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"This experiment requires the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"File Sharing")," experiment enabled.")),(0,i.kt)("p",null,"When enabled, Cwtch will download image files automatically, display image previews in the conversation window, and enable the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profile Pictures")," feature;"),(0,i.kt)("p",null,"On Desktop, enabling this experiment will allow access to an additional setting ",(0,i.kt)("inlineCode",{parentName:"p"},'"'),"Download Folder` which can be changed to tell Cwtch where to (automatically) download pictures."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/794fc1e8.a5dabfce.js b/build-staging/it/assets/js/794fc1e8.a5dabfce.js new file mode 100644 index 00000000..23759a38 --- /dev/null +++ b/build-staging/it/assets/js/794fc1e8.a5dabfce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2111],{4205:l=>{l.exports=JSON.parse('[{"label":"cwtch","permalink":"/it/blog/tags/cwtch","count":17},{"label":"cwtch-stable","permalink":"/it/blog/tags/cwtch-stable","count":17},{"label":"planning","permalink":"/it/blog/tags/planning","count":4},{"label":"release","permalink":"/it/blog/tags/release","count":2},{"label":"developer-documentation","permalink":"/it/blog/tags/developer-documentation","count":2},{"label":"nightly","permalink":"/it/blog/tags/nightly","count":1},{"label":"documentation","permalink":"/it/blog/tags/documentation","count":1},{"label":"security-handbook","permalink":"/it/blog/tags/security-handbook","count":1},{"label":"bindings","permalink":"/it/blog/tags/bindings","count":4},{"label":"autobindings","permalink":"/it/blog/tags/autobindings","count":2},{"label":"libcwtch","permalink":"/it/blog/tags/libcwtch","count":2},{"label":"support","permalink":"/it/blog/tags/support","count":3},{"label":"testing","permalink":"/it/blog/tags/testing","count":2},{"label":"reproducible-builds","permalink":"/it/blog/tags/reproducible-builds","count":2},{"label":"repliqate","permalink":"/it/blog/tags/repliqate","count":2},{"label":"api","permalink":"/it/blog/tags/api","count":1}]')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/7a06dbff.706e10d2.js b/build-staging/it/assets/js/7a06dbff.706e10d2.js new file mode 100644 index 00000000..74b9cdf3 --- /dev/null +++ b/build-staging/it/assets/js/7a06dbff.706e10d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3905],{4040:e=>{e.exports=JSON.parse('{"title":"Experiments","slug":"/category/experiments","permalink":"/it/docs/category/experiments","navigation":{"previous":{"title":"Contenuto notifica","permalink":"/it/docs/settings/behaviour/notification-content"},"next":{"title":"Groups Experiment","permalink":"/it/docs/settings/experiments/group-experiment"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/7c6e9bc2.e7ec1ee4.js b/build-staging/it/assets/js/7c6e9bc2.e7ec1ee4.js new file mode 100644 index 00000000..336e2527 --- /dev/null +++ b/build-staging/it/assets/js/7c6e9bc2.e7ec1ee4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8254],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,d=u["".concat(c,".").concat(m)]||u[m]||h[m]||a;return r?n.createElement(d,i(i({ref:t},l),{},{components:r})):n.createElement(d,i({ref:t},l))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Cwtch Technical Basics",s={unversionedId:"components/intro",id:"components/intro",title:"Cwtch Technical Basics",description:"This page presents a brief technical overview of the Cwtch protocol.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/intro.md",sourceDirName:"components",slug:"/components/intro",permalink:"/it/security/components/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Cwtch Components",permalink:"/it/security/category/cwtch-components"},next:{title:"Component Ecosystem Overview",permalink:"/it/security/components/ecosystem-overview"}},c={},p=[{value:"A Cwtch Profile",id:"a-cwtch-profile",level:2},{value:"2-party conversions: Peer to Peer",id:"2-party-conversions-peer-to-peer",level:2},{value:"Multi-party conversations: Groups and Peer to Server Communication",id:"multi-party-conversations-groups-and-peer-to-server-communication",level:2},{value:"Servers are Peers",id:"servers-are-peers",level:3}],l={toc:p},u="wrapper";function h(e){let{components:t,...a}=e;return(0,o.kt)(u,(0,n.Z)({},l,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cwtch-technical-basics"},"Cwtch Technical Basics"),(0,o.kt)("p",null,"This page presents a brief technical overview of the Cwtch protocol."),(0,o.kt)("h2",{id:"a-cwtch-profile"},"A Cwtch Profile"),(0,o.kt)("p",null,"Users can create one of more Cwtch Profiles. Each profile generates a random ed25519 keypair compatible with Tor."),(0,o.kt)("p",null,"In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys + associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages)."),(0,o.kt)("h2",{id:"2-party-conversions-peer-to-peer"},"2-party conversions: Peer to Peer"),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(7868).Z,width:"960",height:"540"})),(0,o.kt)("p",null,'For 2 parties to engage in a peer-to-peer conversation both must be online, but only one needs to be reachable via their onion service. For the sake of clarity we often label one party the "inbound peer" (the one who hosts the onion service) and the other party the "outbound peer" (the one that connects to the onion service).'),(0,o.kt)("p",null,"After connection both parties engage in an authentication protocol which:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Asserts that each party has access to the private key associated with their public identity."),(0,o.kt)("li",{parentName:"ul"},"Generates an ephemeral session key used to encrypt all further communication during the session.")),(0,o.kt)("p",null,"This exchange (documented in further detail in ",(0,o.kt)("a",{parentName:"p",href:"/it/security/components/tapir/authentication_protocol"},"authentication protocol"),") is ",(0,o.kt)("em",{parentName:"p"},"offline deniable")," i.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the fact - it is impossible to definitely prove that the exchange happened at all."),(0,o.kt)("p",null,"After, the authentication protocol the two parties may exchange messages with each other freely."),(0,o.kt)("h2",{id:"multi-party-conversations-groups-and-peer-to-server-communication"},"Multi-party conversations: Groups and Peer to Server Communication"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Note: Metadata Resistant Group Communication is still an active research area and what is documented here will likely change in the future.")),(0,o.kt)("p",null,"When a person wants to start a group conversation they first randomly generate a secret ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),". All group communication will be encrypted using this key."),(0,o.kt)("p",null,"Along with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key"),", the group creator also decides on a ",(0,o.kt)("strong",{parentName:"p"},"Cwtch Server")," to use as the host of the group. For more information on how Servers authenticate themselves see ",(0,o.kt)("a",{parentName:"p",href:"/it/security/components/cwtch/key_bundles"},"key bundles"),"."),(0,o.kt)("p",null,"A ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Identifier")," is generated using the group key and the group server and these three elements are packaged up into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections)."),(0,o.kt)("p",null,"To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts their message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and generates a cryptographic signature over the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Id"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Server")," and the decrypted message (see: ",(0,o.kt)("a",{parentName:"p",href:"/it/security/components/cwtch/message_formats"},"wire formats")," for more information)."),(0,o.kt)("p",null,"To receive message from the group, a profile connected to the server hosting the group and downloads ",(0,o.kt)("em",{parentName:"p"},"all")," messages (since their previous connection). Profiles then attempt to decrypt each message using the ",(0,o.kt)("inlineCode",{parentName:"p"},"Group Key")," and if successful attempt to verify the signature (see ",(0,o.kt)("a",{parentName:"p",href:"/it/security/components/cwtch/server"},"Cwtch Servers")," ",(0,o.kt)("a",{parentName:"p",href:"/it/security/components/cwtch/groups"},"Cwtch Groups")," for an overview of attacks and mitigations)."),(0,o.kt)("h3",{id:"servers-are-peers"},"Servers are Peers"),(0,o.kt)("p",null,"In many respects communication with a server is identical to communication with a regular Cwtch peer, all the same steps above are taken however the server always acts as the inbound peer, and the outbound peer always uses newly generated ",(0,o.kt)("strong",{parentName:"p"},"ephemeral keypair"),' as their "longterm identity".'),(0,o.kt)("p",null,"As such peer-server conversations only differ in the ",(0,o.kt)("em",{parentName:"p"},"kinds")," of messages that are sent between the two parties, with the server relaying all messages that it receives and also allowing any client to query for older messages."))}h.isMDXComponent=!0},7868:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/BASE_3-a31d3b4ac686c16d510e76ceed179a35.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/7f5e9c41.f850b1e9.js b/build-staging/it/assets/js/7f5e9c41.f850b1e9.js new file mode 100644 index 00000000..f640e426 --- /dev/null +++ b/build-staging/it/assets/js/7f5e9c41.f850b1e9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2234],{9369:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/api","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8051e978.10d89153.js b/build-staging/it/assets/js/8051e978.10d89153.js new file mode 100644 index 00000000..11fd4ab5 --- /dev/null +++ b/build-staging/it/assets/js/8051e978.10d89153.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6325],{846:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/cwtch/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/it/blog/tags/cwtch","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/814f3328.134511a1.js b/build-staging/it/assets/js/814f3328.134511a1.js new file mode 100644 index 00000000..551949c6 --- /dev/null +++ b/build-staging/it/assets/js/814f3328.134511a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2535],{5641:t=>{t.exports=JSON.parse('{"title":"Recent Logs","items":[{"title":"Cwtch Stable Roadmap Update","permalink":"/it/blog/cwtch-stable-roadmap-update-june"},{"title":"Cwtch Beta 1.12","permalink":"/it/blog/cwtch-nightly-1-12"},{"title":"New Cwtch Nightly (v1.11.0-74-g0406)","permalink":"/it/blog/cwtch-nightly-v.11-74"},{"title":"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.","permalink":"/it/blog/cwtch-developer-documentation"},{"title":"Availability Status and Profile Attributes","permalink":"/it/blog/availability-status-profile-attributes"},{"title":"Cwtch Stable Roadmap Update","permalink":"/it/blog/cwtch-stable-roadmap-update"},{"title":"Cwtch Beta 1.11","permalink":"/it/blog/cwtch-nightly-1-11"},{"title":"Updates to Cwtch Documentation","permalink":"/it/blog/cwtch-documentation"},{"title":"Compile-time Optional Application Experiments (Autobindings)","permalink":"/it/blog/autobindings-ii"},{"title":"Autogenerating Cwtch Bindings","permalink":"/it/blog/autobindings"},{"title":"Notes on Cwtch UI Testing (II)","permalink":"/it/blog/cwtch-testing-ii"},{"title":"Making Cwtch Android Bindings Reproducible","permalink":"/it/blog/cwtch-android-reproducibility"},{"title":"Notes on Cwtch UI Testing","permalink":"/it/blog/cwtch-testing-i"},{"title":"Cwtch UI Platform Support","permalink":"/it/blog/cwtch-platform-support"},{"title":"Making Cwtch Bindings Reproducible","permalink":"/it/blog/cwtch-bindings-reproducible"},{"title":"Cwtch Stable API Design","permalink":"/it/blog/cwtch-stable-api-design"},{"title":"Path to Cwtch Stable","permalink":"/it/blog/path-to-cwtch-stable"}]}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/824a28c6.c282e634.js b/build-staging/it/assets/js/824a28c6.c282e634.js new file mode 100644 index 00000000..0ec9dda6 --- /dev/null +++ b/build-staging/it/assets/js/824a28c6.c282e634.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5905],{3905:(t,e,i)=>{i.d(e,{Zo:()=>s,kt:()=>b});var r=i(7294);function n(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function o(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,r)}return i}function a(t){for(var e=1;e=0||(n[i]=t[i]);return n}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,i)&&(n[i]=t[i])}return n}var l=r.createContext({}),p=function(t){var e=r.useContext(l),i=e;return t&&(i="function"==typeof t?t(e):a(a({},e),t)),i},s=function(t){var e=p(t.components);return r.createElement(l.Provider,{value:e},t.children)},h="mdxType",u={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},d=r.forwardRef((function(t,e){var i=t.components,n=t.mdxType,o=t.originalType,l=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),h=p(i),d=n,b=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return i?r.createElement(b,a(a({ref:e},s),{},{components:i})):r.createElement(b,a({ref:e},s))}));function b(t,e){var i=arguments,n=e&&e.mdxType;if("string"==typeof t||n){var o=i.length,a=new Array(o);a[0]=d;var c={};for(var l in e)hasOwnProperty.call(e,l)&&(c[l]=e[l]);c.originalType=t,c[h]="string"==typeof t?t:n,a[1]=c;for(var p=2;p{i.r(e),i.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=i(7462),n=(i(7294),i(3905));const o={sidebar_position:1},a="Getting Started",c={unversionedId:"building-a-cwtch-app/intro",id:"building-a-cwtch-app/intro",title:"Getting Started",description:"Choosing A Cwtch Library",source:"@site/developing/building-a-cwtch-app/intro.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/intro",permalink:"/it/developing/building-a-cwtch-app/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Building a Cwtch App",permalink:"/it/developing/category/building-a-cwtch-app"},next:{title:"Core Concepts",permalink:"/it/developing/building-a-cwtch-app/core-concepts"}},l={},p=[{value:"Choosing A Cwtch Library",id:"choosing-a-cwtch-library",level:2},{value:"Cwtch Go Lib",id:"cwtch-go-lib",level:3},{value:"CwtchBot",id:"cwtchbot",level:3},{value:"Autobindings (C-bindings)",id:"autobindings-c-bindings",level:3},{value:"libCwtch-rs (Rust)",id:"libcwtch-rs-rust",level:3}],s={toc:p},h="wrapper";function u(t){let{components:e,...i}=t;return(0,n.kt)(h,(0,r.Z)({},s,i,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"getting-started"},"Getting Started"),(0,n.kt)("h2",{id:"choosing-a-cwtch-library"},"Choosing A Cwtch Library"),(0,n.kt)("h3",{id:"cwtch-go-lib"},"Cwtch Go Lib"),(0,n.kt)("p",null,"The official Cwtch library is written in Go and can be found at ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"https://git.openprivacy.ca/cwtch.im/cwtch"),". This library allows access to all Cwtch functionality."),(0,n.kt)("h3",{id:"cwtchbot"},"CwtchBot"),(0,n.kt)("p",null,"We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot#using-cwtchbot-go"},"building an echobot tutorial"),"."),(0,n.kt)("h3",{id:"autobindings-c-bindings"},"Autobindings (C-bindings)"),(0,n.kt)("p",null,"The ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"official c-bindings for Cwtch")," are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI."),(0,n.kt)("h3",{id:"libcwtch-rs-rust"},"libCwtch-rs (Rust)"),(0,n.kt)("p",null,"An experimental rust-fied version of Cwtch Autobindings is available in ",(0,n.kt)("a",{parentName:"p",href:"https://crates.io/crates/libcwtch"},"libCwtch-rs"),". While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8281c315.b32fff9f.js b/build-staging/it/assets/js/8281c315.b32fff9f.js new file mode 100644 index 00000000..d6b4decd --- /dev/null +++ b/build-staging/it/assets/js/8281c315.b32fff9f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2861],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(n),d=r,m=u["".concat(l,".").concat(d)]||u[d]||g[d]||i;return n?a.createElement(m,o(o({ref:t},s),{},{components:n})):a.createElement(m,o({ref:t},s))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:r,o[1]=c;for(var p=2;p{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const i={sidebar_position:1},o="Cambia lingua",c={unversionedId:"settings/appearance/change-language",id:"settings/appearance/change-language",title:"Cambia lingua",description:"Grazie all'aiuto dei volontari, l'app di Cwtch \xe8 stata tradotta in molte lingue.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/change-language.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/change-language",permalink:"/it/docs/settings/appearance/change-language",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/change-language.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Appearance",permalink:"/it/docs/category/appearance"},next:{title:"Modalit\xe0 chiara/scura e scomposizione dei temi",permalink:"/it/docs/settings/appearance/light-dark-mode"}},l={},p=[],s={toc:p},u="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,a.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"cambia-lingua"},"Cambia lingua"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"Grazie all'aiuto dei volontari"),", l'app di Cwtch \xe8 stata tradotta in molte lingue."),(0,r.kt)("p",null,"Per cambiare la lingua che Cwtch utilizza:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Apri le Impostazioni"),(0,r.kt)("li",{parentName:"ol"},'L\'impostazione in cima \xe8 "Lingua", \xe8 possibile utilizzare il menu a tendina per selezionare la lingua che si desidera utilizzare.')))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/83643414.f98f85cb.js b/build-staging/it/assets/js/83643414.f98f85cb.js new file mode 100644 index 00000000..5e05ff44 --- /dev/null +++ b/build-staging/it/assets/js/83643414.f98f85cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6098],{6946:e=>{e.exports=JSON.parse('{"title":"Groups","slug":"/category/groups","permalink":"/it/docs/category/groups","navigation":{"previous":{"title":"Removing a Conversation","permalink":"/it/docs/chat/delete-contact"},"next":{"title":"Un\'introduzione ai gruppi di Cwtch","permalink":"/it/docs/groups/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/876f085b.d32dc0bc.js b/build-staging/it/assets/js/876f085b.d32dc0bc.js new file mode 100644 index 00000000..e2be0c17 --- /dev/null +++ b/build-staging/it/assets/js/876f085b.d32dc0bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9645],{239:e=>{e.exports=JSON.parse('{"title":"Aspetto","slug":"/category/appearance","permalink":"/it/docs/category/appearance","navigation":{"previous":{"title":"Un\'introduzione alle impostazioni dell\'app di Cwtch","permalink":"/it/docs/settings/introduction"},"next":{"title":"Cambia lingua","permalink":"/it/docs/settings/appearance/change-language"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8838b5d9.2f73078b.js b/build-staging/it/assets/js/8838b5d9.2f73078b.js new file mode 100644 index 00000000..ef5ee4be --- /dev/null +++ b/build-staging/it/assets/js/8838b5d9.2f73078b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9239],{3177:e=>{e.exports=JSON.parse('{"title":"Impostazioni","slug":"/category/settings","permalink":"/it/docs/category/settings","navigation":{"previous":{"title":"Come sbloccare un server","permalink":"/it/docs/servers/unlock-server"},"next":{"title":"Un\'introduzione alle impostazioni dell\'app di Cwtch","permalink":"/it/docs/settings/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/88d0c547.9912f681.js b/build-staging/it/assets/js/88d0c547.9912f681.js new file mode 100644 index 00000000..be83bdd5 --- /dev/null +++ b/build-staging/it/assets/js/88d0c547.9912f681.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2081],{3905:(e,t,a)=>{a.d(t,{Zo:()=>l,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),p=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},l=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=p(a),u=r,m=d["".concat(c,".").concat(u)]||d[u]||h[u]||o;return a?n.createElement(m,i(i({ref:t},l),{},{components:a})):n.createElement(m,i({ref:t},l))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,i=new Array(o);i[0]=u;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const o={sidebar_position:1},i="Cwtch Security Handbook",s={unversionedId:"intro",id:"intro",title:"Cwtch Security Handbook",description:"Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/intro.md",sourceDirName:".",slug:"/intro",permalink:"/it/security/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Risk Model",permalink:"/it/security/risk"}},c={},p=[{value:"What is Cwtch?",id:"what-is-cwtch",level:2},{value:"A (Brief) History of Metadata Resistant Chat",id:"a-brief-history-of-metadata-resistant-chat",level:2}],l={toc:p},d="wrapper";function h(e){let{components:t,...a}=e;return(0,r.kt)(d,(0,n.Z)({},l,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"cwtch-security-handbook"},"Cwtch Security Handbook"),(0,r.kt)("p",null,"Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes."),(0,r.kt)("p",null,(0,r.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/2.png",alt:null})),(0,r.kt)("h2",{id:"what-is-cwtch"},"What is Cwtch?"),(0,r.kt)("p",null,"Cwtch (/k\u028at\u0283/ - a Welsh word roughly translating to \u201ca hug that creates a safe place\u201d) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Decentralized and Open"),": There is no \u201cCwtch service\u201d or \u201cCwtch network\u201d. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Privacy Preserving"),": All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Metadata Resistant"),": Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.")),(0,r.kt)("h2",{id:"a-brief-history-of-metadata-resistant-chat"},"A (Brief) History of Metadata Resistant Chat"),(0,r.kt)("p",null,"In recent years, public awareness of the need and benefits of end-to-end encrypted solutions has increased with applications like ",(0,r.kt)("a",{parentName:"p",href:"https://signalapp.org"},"Signal"),", ",(0,r.kt)("a",{parentName:"p",href:"https://whatsapp.com"},"Whatsapp")," and ",(0,r.kt)("a",{parentName:"p",href:"https://wire.org"},"Wire")," now providing users with secure communications."),(0,r.kt)("p",null,"However, these tools require various levels of metadata exposure to function, and much of this metadata can be used to gain details about how and why a person is using a tool to communicate. ",(0,r.kt)("a",{parentName:"p",href:"https://www.researchgate.net/profile/Peter_Kieseberg/publication/299984940_Privacy_and_data_protection_in_smartphone_messengers/links/5a1a9c29a6fdcc50adeb1335/Privacy-and-data-protection-in-smartphone-messengers.pdf"},"[rottermanner2015privacy]"),"."),(0,r.kt)("p",null,"One tool that did seek to reduce metadata is ",(0,r.kt)("a",{parentName:"p",href:"https://ricochet.im"},"Ricochet")," first released in 2014. Ricochet used Tor v2 onion services to provide secure end-to-end encrypted communication, and to protect the metadata of communications."),(0,r.kt)("p",null,"There were no centralized servers that assist in routing Ricochet conversations. No one other than the parties involved in a conversation could know that such a conversation is taking place."),(0,r.kt)("p",null,"Ricochet wasn't without limitations; there was no multi-device support, nor is there a mechanism for supporting group communication or for a user to send messages while a contact is offline."),(0,r.kt)("p",null,"This made adoption of Ricochet a difficult proposition; with even those in environments that would be served best by metadata resistance unaware that it exists ",(0,r.kt)("a",{parentName:"p",href:"https://www.academia.edu/download/53192589/ermoshina-12.pdf"},"[ermoshina2017can]")," ",(0,r.kt)("a",{parentName:"p",href:"https://eprints.gla.ac.uk/116203/1/116203.pdf"},"[renaud2014doesn]"),"."),(0,r.kt)("p",null,"Additionally, any solution to decentralized, metadata resistant communication faces ",(0,r.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"fundamental problems")," when it comes to efficiency, privacy and group security (as defined by ",(0,r.kt)("a",{parentName:"p",href:"https://code.briarproject.org/briar/briar/-/wikis/Fundamental-Problems"},"transcript consensus and consistency"),")."),(0,r.kt)("p",null,"Modern alternatives to Ricochet include ",(0,r.kt)("a",{parentName:"p",href:"https://briarproject.org"},"Briar"),", ",(0,r.kt)("a",{parentName:"p",href:"https://www.zbay.app/"},"Zbay")," and ",(0,r.kt)("a",{parentName:"p",href:"https://www.ricochetrefresh.net/"},"Ricochet Refresh")," - each tool seeks to optimize for a different set of trade-offs e.g. Briar seeks to allow people to communicate ",(0,r.kt)("a",{parentName:"p",href:"https://briarproject.org/how-it-works/"},"even when underlying network infrastructure is down")," while providing resistant to metadata surveillance."),(0,r.kt)("hr",null),(0,r.kt)("p",null,"The Cwtch project began in 2017 as an extension protocol for Ricochet providing group conversations via untrusted servers, with an eye to enabling decentralized, metadata resistant applications (like shared lists and bulletin board)"),(0,r.kt)("p",null,"An alpha version of Cwtch was ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/blog/2019/02/14/cwtch-alpha/"},"was launched in February 2019"),", and since then the Cwtch team (run by the ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca"},"Open Privacy Research Society"),") has conducted research and development into Cwtch and the underlying protocols and libraries and problem spaces."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8918cacc.c76c44c5.js b/build-staging/it/assets/js/8918cacc.c76c44c5.js new file mode 100644 index 00000000..9d272a95 --- /dev/null +++ b/build-staging/it/assets/js/8918cacc.c76c44c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8907],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},m=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},l="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),l=p(n),g=o,f=l["".concat(c,".").concat(g)]||l[g]||u[g]||i;return n?r.createElement(f,a(a({ref:t},m),{},{components:n})):r.createElement(f,a({ref:t},m))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[l]="string"==typeof e?e:o,a[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:6},a="Formattazione messaggio",s={unversionedId:"settings/experiments/message-formatting",id:"settings/experiments/message-formatting",title:"Formattazione messaggio",description:"When enabled, this experiment changes the conversation compose box to add message formatting UX.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/message-formatting.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/message-formatting",permalink:"/it/docs/settings/experiments/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/message-formatting.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Esperimento Link cliccabili",permalink:"/it/docs/settings/experiments/clickable-links"},next:{title:"QR Codes",permalink:"/it/docs/settings/experiments/qrcodes"}},c={},p=[],m={toc:p},l="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"formattazione-messaggio"},"Formattazione messaggio"),(0,o.kt)("p",null,"When enabled, this experiment changes the conversation compose box to add ",(0,o.kt)("a",{parentName:"p",href:"/docs/chat/message-formatting"},"message formatting")," UX."),(0,o.kt)("p",null,"This experiment is now enabled by default."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/89f86a37.6c1214b1.js b/build-staging/it/assets/js/89f86a37.6c1214b1.js new file mode 100644 index 00000000..db51d850 --- /dev/null +++ b/build-staging/it/assets/js/89f86a37.6c1214b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9759],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>g});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),s=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),m=s(a),u=n,g=m["".concat(l,".").concat(u)]||m[u]||h[u]||o;return a?r.createElement(g,i(i({ref:t},p),{},{components:a})):r.createElement(g,i({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[m]="string"==typeof e?e:n,i[1]=c;for(var s=2;s{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/it/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"29 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"release",permalink:"/it/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/it/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/it/blog/cwtch-documentation"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},m="wrapper";function h(e){let{components:t,...o}=e;return(0,n.kt)(m,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,n.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})))}h.isMDXComponent=!0},6094:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8a8a5858.2b7a17f7.js b/build-staging/it/assets/js/8a8a5858.2b7a17f7.js new file mode 100644 index 00000000..baa23a47 --- /dev/null +++ b/build-staging/it/assets/js/8a8a5858.2b7a17f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1739],{5717:a=>{a.exports=JSON.parse('{"label":"cwtch","permalink":"/it/blog/tags/cwtch","allTagsPath":"/it/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8aa5d230.868664e0.js b/build-staging/it/assets/js/8aa5d230.868664e0.js new file mode 100644 index 00000000..2bfa5f4b --- /dev/null +++ b/build-staging/it/assets/js/8aa5d230.868664e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9516],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(r),m=o,f=p["".concat(l,".").concat(m)]||p[m]||h[m]||s;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,a=new Array(s);a[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,a[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const s={},a="Cwtch Server",i={unversionedId:"components/cwtch/server",id:"components/cwtch/server",title:"Cwtch Server",description:"The goal of the Cwtch protocol is to enable group communication through Untrusted Infrastructure.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/server.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/server",permalink:"/it/security/components/cwtch/server",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/it/security/components/cwtch/groups"},next:{title:"Cwtch UI",permalink:"/it/security/category/cwtch-ui"}},l={},c=[{value:"Malicious Servers",id:"malicious-servers",level:2},{value:"Detectable Faults",id:"detectable-faults",level:3},{value:"Efficiency",id:"efficiency",level:2}],u={toc:c},p="wrapper";function h(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cwtch-server"},"Cwtch Server"),(0,o.kt)("p",null,"The goal of the Cwtch protocol is to enable group communication through ",(0,o.kt)("strong",{parentName:"p"},"Untrusted Infrastructure"),"."),(0,o.kt)("p",null,"Unlike in relay-based schemes where the groups assign a leader, set of leaders, or a trusted third party server to ensure that every member of the group can send and receive messages in a timely manner (even if members are offline) - untrusted infrastructure has a goal of realizing those properties without the assumption of trust."),(0,o.kt)("p",null,"The original Cwtch paper defined a set of properties that Cwtch Servers were expected to provide:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Cwtch Server may be used by multiple groups or just one."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server, without collaboration of a group member, should never learn the identity of participants within a group."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server should never learn the content of any communication."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch Server should never be able to distinguish messages as belonging to a particular group.")),(0,o.kt)("p",null,"We note here that these properties are a superset of the design aims of Private Information Retrieval structures."),(0,o.kt)("h2",{id:"malicious-servers"},"Malicious Servers"),(0,o.kt)("p",null,"We expect the presence of malicious entities within the Cwtch ecosystem."),(0,o.kt)("p",null,"We also prioritize decentralization and permissionless entry into the ecosystem and as such we do not base any security claims on the following:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Any non-collusion assumptions between a set of Cwtch servers"),(0,o.kt)("li",{parentName:"ul"},"Any third-party defined verification process")),(0,o.kt)("p",null,"Peers themselves are encouraged to set up and run Cwtch servers where they can guarantee more efficient properties by relaxing trust and security assumptions - however, by default, we design the protocol to be secure without these assumptions - sacrificing efficiency where necessary."),(0,o.kt)("h3",{id:"detectable-faults"},"Detectable Faults"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"If a Cwtch server fails to relay a specific message to a subset of group members then there will be a detectable gap in the message tree of certain peers that can be discovered through peer-to-peer gossip."),(0,o.kt)("li",{parentName:"ul"},"A Cwtch server cannot modify any message without the key material known to the group (any attempt to do so for a subset of group members will result in identical behavior to failing to relay a message)."),(0,o.kt)("li",{parentName:"ul"},"While a server ",(0,o.kt)("em",{parentName:"li"},"can")," duplicate messages, these will have no impact on the group message tree (because of encryption, nonces and message identities) - the source of the duplication is not knowable to a peer.")),(0,o.kt)("h2",{id:"efficiency"},"Efficiency"),(0,o.kt)("p",null,'As of writing, only 1 protocol is known for achieving the desired properties, naive PIR or "the server sends everything, and the peers sift through it".'),(0,o.kt)("p",null,"This has an obvious impact on bandwidth efficiency, especially for peers using mobile devices, as such we are actively developing new protocols in which the privacy and efficiency guarantees can be traded-off in different ways."),(0,o.kt)("p",null,"As of writing, the servers allow both a complete download of all stored messages, and a request to download messages from a certain specified message."),(0,o.kt)("p",null,"All peers when they first join a group on a new server download all messages from the server, and from then on download only new messages."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Note"),": This behaviour does permit a mild form of metadata analysis. The server can new messages for each suspected unique profile, and then use these unique message signatures to track unique sessions over time ( via requests for new messages)."),(0,o.kt)("p",null,"This is mitigated by 2 confounding factors:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Profiles can refresh their connections at any time - resulting in fresh server session."),(0,o.kt)("li",{parentName:"ol"},'Profiles can "resync" from a server at any time - resulting in a new call to download all messages. The most common usecase for this behaviour is to fetch older messages from a group.')),(0,o.kt)("p",null,"In combination, these 2 mitigations place bounds on what the server is able to infer however we still cannot provide full metadata-resistance."),(0,o.kt)("p",null,"For potential future solutions to this problem see ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/niwl"},"Niwl")),(0,o.kt)("h1",{id:"protecting-the-server-from-malicious-peers"},"Protecting the Server from Malicious Peers"),(0,o.kt)("p",null,"The main risk to servers come in the form of spam generated by peers. In the prototype of Cwtch a spamguard mechanism was put in place that required peers to conduct some arbitrary proof of work given a server-specified parameter."),(0,o.kt)("p",null,"This is not a robust solution in the presence of a determined adversary with a significant amount of resources, and thus one of the main external risks to the Cwtch system becomes censorship-via-resource exhaustion."),(0,o.kt)("p",null,"We have outlined a potential solution to this in ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/research/OPTR2019-01/"},"token based services")," but note that this also requires further development."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8d811565.c9c12fe6.js b/build-staging/it/assets/js/8d811565.c9c12fe6.js new file mode 100644 index 00000000..7fbe21d3 --- /dev/null +++ b/build-staging/it/assets/js/8d811565.c9c12fe6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3587],{302:e=>{e.exports=JSON.parse('{"title":"Building a Cwtch App","slug":"/category/building-a-cwtch-app","permalink":"/it/developing/category/building-a-cwtch-app","navigation":{"previous":{"title":"Release and Packaging Process","permalink":"/it/developing/release"},"next":{"title":"Getting Started","permalink":"/it/developing/building-a-cwtch-app/intro"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8e3a693e.956fc1bf.js b/build-staging/it/assets/js/8e3a693e.956fc1bf.js new file mode 100644 index 00000000..a70ee353 --- /dev/null +++ b/build-staging/it/assets/js/8e3a693e.956fc1bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7970],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function s(e){for(var r=1;r=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):s(s({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||i;return t?n.createElement(v,s(s({ref:r},p),{},{components:t})):n.createElement(v,s({ref:r},p))}));function v(e,r){var t=arguments,o=r&&r.mdxType;if("string"==typeof e||o){var i=t.length,s=new Array(i);s[0]=m;var a={};for(var c in r)hasOwnProperty.call(r,c)&&(a[c]=r[c]);a.originalType=e,a[u]="string"==typeof e?e:o,s[1]=a;for(var l=2;l{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var n=t(7462),o=(t(7294),t(3905));const i={sidebar_position:6},s="Come sbloccare un server",a={unversionedId:"servers/unlock-server",id:"servers/unlock-server",title:"Come sbloccare un server",description:"Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/unlock-server.md",sourceDirName:"servers",slug:"/servers/unlock-server",permalink:"/it/docs/servers/unlock-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/unlock-server.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Come condividere il tuo pacchetto di chiavi del server",permalink:"/it/docs/servers/share-key"},next:{title:"Settings",permalink:"/it/docs/category/settings"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,o.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"come-sbloccare-un-server"},"Come sbloccare un server"),(0,o.kt)("p",null,":::attenzione Esperimenti necessari"),(0,o.kt)("p",null,"Questa funzione richiede ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l' ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Esperimento di server hosting")," attivato."),(0,o.kt)("p",null,":::"),(0,o.kt)("p",null,"Se hai protetto il tuo server con una password, dovr\xe0 essere sbloccato ogni volta che riavvii l'applicazione."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Vai all'icona del server"),(0,o.kt)("li",{parentName:"ol"},"Clicca sull'icona di sblocco rosa"),(0,o.kt)("li",{parentName:"ol"},"Inserisci la password del tuo server"),(0,o.kt)("li",{parentName:"ol"},"Premi Sblocca")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8e8114dc.d55afec6.js b/build-staging/it/assets/js/8e8114dc.d55afec6.js new file mode 100644 index 00000000..e5848153 --- /dev/null +++ b/build-staging/it/assets/js/8e8114dc.d55afec6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9923],{1809:e=>{e.exports=JSON.parse('{"label":"developer-documentation","permalink":"/it/blog/tags/developer-documentation","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/8fe7a387.ed7b87ab.js b/build-staging/it/assets/js/8fe7a387.ed7b87ab.js new file mode 100644 index 00000000..1005c15b --- /dev/null +++ b/build-staging/it/assets/js/8fe7a387.ed7b87ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5233],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>g});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=i.createContext({}),s=function(e){var t=i.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=s(e.components);return i.createElement(p.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),d=s(n),h=a,g=d["".concat(p,".").concat(h)]||d[h]||m[h]||r;return n?i.createElement(g,o(o({ref:t},c),{},{components:n})):i.createElement(g,o({ref:t},c))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=h;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[d]="string"==typeof e?e:a,o[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const r={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"3 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"autobindings",permalink:"/it/blog/tags/autobindings"},{label:"libcwtch",permalink:"/it/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/it/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/it/blog/autobindings"}},p={authorsImageUrls:[void 0]},s=[{value:"The Structure of an Application Experiment",id:"the-structure-of-an-application-experiment",level:2},{value:"New Required Management APIs",id:"new-required-management-apis",level:3},{value:"Adding Support for Application Experiments in the Spec File",id:"adding-support-for-application-experiments-in-the-spec-file",level:3},{value:"Generation-Time Inclusion",id:"generation-time-inclusion",level:3},{value:"Cwtch UI Integration",id:"cwtch-ui-integration",level:3},{value:"Nightlies & Next Steps",id:"nightlies--next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:s},d="wrapper";function m(e){let{components:t,...r}=e;return(0,a.kt)(d,(0,i.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"the-structure-of-an-application-experiment"},"The Structure of an Application Experiment"),(0,a.kt)("p",null,"An application-level experiment consists of:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"A set of top-level APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadServer"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DeleteServer")," - these are the APIs that we want to expose to calling applications."),(0,a.kt)("li",{parentName:"ol"},"An encapsulating structure for the set of APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ServersFunctionality")," - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity."),(0,a.kt)("li",{parentName:"ol"},"A global variable that exists at the top level of libCwtch, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"var serverExperiment *servers.ServersFunctionality servers")," - our single pointer to the underlying functionality."),(0,a.kt)("li",{parentName:"ol"},"A set of management-related APIs, e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"Init"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"UpdateSettings"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"OnACNEvent")," - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers)."),(0,a.kt)("li",{parentName:"ol"},"Management code within ",(0,a.kt)("inlineCode",{parentName:"li"},"_startCwtch")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"_reconnectCwtch")," that calls the management APIs on the global variable.")),(0,a.kt)("p",null,"From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on ",(0,a.kt)("inlineCode",{parentName:"p"},"application")," or a specific ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"."),(0,a.kt)("p",null,"Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template."),(0,a.kt)("h3",{id:"new-required-management-apis"},"New Required Management APIs"),(0,a.kt)("p",null,"To achieve this weaving, we now require application-level experiments to implement an ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandlerInterface")," interface and expose itself via an\ninitialize constructor ",(0,a.kt)("inlineCode",{parentName:"p"},"Init(acn, appDir) -> EventHandlerInterface"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"Enable(app, acn)"),"."),(0,a.kt)("p",null,"For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface."),(0,a.kt)("p",null,"We can then generate, and optionally include blocks of code like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"}," = .Init(&globalACN, appDir)\n eventHandler.AddModule()\n .Enable(application, &globalACN)\n")),(0,a.kt)("p",null,"and place them at specific points in the code. ",(0,a.kt)("inlineCode",{parentName:"p"},"EventHandler")," has also been extended to maintain a collection of ",(0,a.kt)("inlineCode",{parentName:"p"},"modules")," so that it can\npass on interesting events."),(0,a.kt)("h3",{id:"adding-support-for-application-experiments-in-the-spec-file"},"Adding Support for Application Experiments in the Spec File"),(0,a.kt)("p",null,"We have introduced a new ",(0,a.kt)("inlineCode",{parentName:"p"},"!")," operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option ",(0,a.kt)("inlineCode",{parentName:"p"},"exp")," which will call the function on the configured experiment, and ",(0,a.kt)("inlineCode",{parentName:"p"},"global")," to allow the setting up\nof a global functionality within the library."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},' # Server Hosting Experiment\n !serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"\n !serverExperiment global serverExperiment *servers.ServersFunctionality servers\n !serverExperiment exp CreateServer application password string:description bool:autostart\n !serverExperiment exp SetServerAttribute application string:handle string:key string:val\n !serverExperiment exp LoadServers application acn password\n !serverExperiment exp LaunchServers application acn\n !serverExperiment exp LaunchServer application string:handle\n !serverExperiment exp StopServer application string:handle\n !serverExperiment exp StopServers application\n !serverExperiment exp DestroyServers\n !serverExperiment exp DeleteServer application string:handle password\n')),(0,a.kt)("h3",{id:"generation-time-inclusion"},"Generation-Time Inclusion"),(0,a.kt)("p",null," Without any arguments provided ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," will not generate code for any experiments."),(0,a.kt)("p",null," In order to determine what experimental code to generate, ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings")," now interprets arguments as enabled compile time experiments, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"generate-bindings serverExperiment")," will turn on\ngeneration of server hosting code, per the spec file above."),(0,a.kt)("h3",{id:"cwtch-ui-integration"},"Cwtch UI Integration"),(0,a.kt)("p",null,"The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"c_LoadServers")," - if it doesn't then the UI is safe to assume the\nfeature is not available."),(0,a.kt)("figure",null,(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7365).Z,width:"1290",height:"754"})),(0,a.kt)("figcaption",null,"A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.")),(0,a.kt)("h2",{id:"nightlies--next-steps"},"Nightlies & Next Steps"),(0,a.kt)("p",null,"We are now publishing ",(0,a.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/libCwtch-autobindings-v0.0.2/"},"nightlies")," of autobinding derived libCwtch-go, along with ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.2"},"Repliqate scripts")," for reproducibility."),(0,a.kt)("p",null,"With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11."),(0,a.kt)("p",null,"However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),".")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}m.isMDXComponent=!0},7365:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/dev9-host-disabled-3d95df692e95765ccc97b4da4e35b23e.png"},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9009e554.cdd0c2e4.js b/build-staging/it/assets/js/9009e554.cdd0c2e4.js new file mode 100644 index 00000000..c6761298 --- /dev/null +++ b/build-staging/it/assets/js/9009e554.cdd0c2e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1871],{7202:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/planning","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9034063a.b3f2b831.js b/build-staging/it/assets/js/9034063a.b3f2b831.js new file mode 100644 index 00000000..f7f7c970 --- /dev/null +++ b/build-staging/it/assets/js/9034063a.b3f2b831.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1602],{2430:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/libcwtch","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9148c1ad.a9bddf70.js b/build-staging/it/assets/js/9148c1ad.a9bddf70.js new file mode 100644 index 00000000..49d2c134 --- /dev/null +++ b/build-staging/it/assets/js/9148c1ad.a9bddf70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9477],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(n),d=a,f=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:3},i="Colonne dell' IU (Interfaccia Utente)",c={unversionedId:"settings/appearance/ui-columns",id:"settings/appearance/ui-columns",title:"Colonne dell' IU (Interfaccia Utente)",description:"1. Clicca sull'icona impostazione",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/ui-columns.md",sourceDirName:"settings/appearance",slug:"/settings/appearance/ui-columns",permalink:"/it/docs/settings/appearance/ui-columns",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/appearance/ui-columns.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Modalit\xe0 chiara/scura e scomposizione dei temi",permalink:"/it/docs/settings/appearance/light-dark-mode"},next:{title:"Modalit\xe0 Streamer/Presentazione",permalink:"/it/docs/settings/appearance/streamer-mode"}},l={},s=[],p={toc:s},u="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"colonne-dell-iu-interfaccia-utente"},"Colonne dell' IU (Interfaccia Utente)"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Clicca sull'icona impostazione"),(0,a.kt)("li",{parentName:"ol"},"Clicca su singola"),(0,a.kt)("li",{parentName:"ol"},"Seleziona la configurazione delle colonne che vuoi usare")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/917f768f.e40a65e1.js b/build-staging/it/assets/js/917f768f.e40a65e1.js new file mode 100644 index 00000000..61e60ead --- /dev/null +++ b/build-staging/it/assets/js/917f768f.e40a65e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1210],{3905:(a,e,t)=>{t.d(e,{Zo:()=>N,kt:()=>h});var m=t(7294);function s(a,e,t){return e in a?Object.defineProperty(a,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[e]=t,a}function n(a,e){var t=Object.keys(a);if(Object.getOwnPropertySymbols){var m=Object.getOwnPropertySymbols(a);e&&(m=m.filter((function(e){return Object.getOwnPropertyDescriptor(a,e).enumerable}))),t.push.apply(t,m)}return t}function p(a){for(var e=1;e=0||(s[t]=a[t]);return s}(a,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(a);for(m=0;m=0||Object.prototype.propertyIsEnumerable.call(a,t)&&(s[t]=a[t])}return s}var i=m.createContext({}),l=function(a){var e=m.useContext(i),t=e;return a&&(t="function"==typeof a?a(e):p(p({},e),a)),t},N=function(a){var e=l(a.components);return m.createElement(i.Provider,{value:e},a.children)},o="mdxType",k={inlineCode:"code",wrapper:function(a){var e=a.children;return m.createElement(m.Fragment,{},e)}},c=m.forwardRef((function(a,e){var t=a.components,s=a.mdxType,n=a.originalType,i=a.parentName,N=r(a,["components","mdxType","originalType","parentName"]),o=l(t),c=s,h=o["".concat(i,".").concat(c)]||o[c]||k[c]||n;return t?m.createElement(h,p(p({ref:e},N),{},{components:t})):m.createElement(h,p({ref:e},N))}));function h(a,e){var t=arguments,s=e&&e.mdxType;if("string"==typeof a||s){var n=t.length,p=new Array(n);p[0]=c;var r={};for(var i in e)hasOwnProperty.call(e,i)&&(r[i]=e[i]);r.originalType=a,r[o]="string"==typeof a?a:s,p[1]=r;for(var l=2;l{t.r(e),t.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>k,frontMatter:()=>n,metadata:()=>r,toc:()=>l});var m=t(7462),s=(t(7294),t(3905));const n={sidebar_position:2},p="Authentication Protocol",r={unversionedId:"components/tapir/authentication_protocol",id:"components/tapir/authentication_protocol",title:"Authentication Protocol",description:"Each peer, given an open connection $C$:",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/tapir/authentication_protocol.md",sourceDirName:"components/tapir",slug:"/components/tapir/authentication_protocol",permalink:"/it/security/components/tapir/authentication_protocol",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Packet Format",permalink:"/it/security/components/tapir/packet_format"},next:{title:"Cwtch",permalink:"/it/security/category/cwtch"}},i={},l=[{value:"Cryptographic Properties",id:"cryptographic-properties",level:3}],N={toc:l},o="wrapper";function k(a){let{components:e,...t}=a;return(0,s.kt)(o,(0,m.Z)({},N,t,{components:e,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"authentication-protocol"},"Authentication Protocol"),(0,s.kt)("p",null,"Each peer, given an open connection ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"C")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"C")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"))))),":"),(0,s.kt)("div",{className:"math math-display"},(0,s.kt)("span",{parentName:"div",className:"katex-display"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML",display:"block"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"z"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"p"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"h"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"m"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"r"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"a"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"l"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"I"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"d"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"e"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"n"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"i"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"y"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"I"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"I"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"P"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mrow",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("mi",{parentName:"msup"},"i")),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msup"},"P"),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("msup",{parentName:"mrow"},(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"P"),(0,s.kt)("mi",{parentName:"msub"},"e")),(0,s.kt)("msub",{parentName:"msup"},(0,s.kt)("mi",{parentName:"msub"},"i"),(0,s.kt)("mi",{parentName:"msub"},"e"))),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"="),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"E"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mo",{parentName:"mrow"},"\u2192"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow"},"\u2190"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mspace",{parentName:"mrow",linebreak:"newline"}),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"k"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("msub",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msub"},"c"),(0,s.kt)("mi",{parentName:"msub"},"p")),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")"),(0,s.kt)("mo",{parentName:"mrow"},(0,s.kt)("mover",{parentName:"mo"},(0,s.kt)("mo",{parentName:"mover"},(0,s.kt)("mo",{parentName:"mo"},"=")),(0,s.kt)("mo",{parentName:"mover",stretchy:"false",lspace:"0em",rspace:"0em"},"?"))),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"n"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"c"),(0,s.kt)("mi",{parentName:"mrow"},"r"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"p"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"."),(0,s.kt)("mi",{parentName:"mrow"},"L"),(0,s.kt)("mi",{parentName:"mrow"},"a"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"e"),(0,s.kt)("mi",{parentName:"mrow"},"s"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mi",{parentName:"mrow"},"C"),(0,s.kt)("mi",{parentName:"mrow"},"o"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"m"),(0,s.kt)("mi",{parentName:"mrow"},"i"),(0,s.kt)("mi",{parentName:"mrow"},"t"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"I = \\mathrm{InitializeIdentity()} \\\\ I_e = \\mathrm{InitializeEphemeralIdentity()} \\\\ I,I_e \\rightarrow C \\\\ P,P_e \\leftarrow C \\\\ k = \\mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\\\ c = \\mathrm{E}(k, transcript.Commit()) \\\\ c \\rightarrow C \\\\ c_p \\leftarrow C\\\\ \\mathrm{D}(k, c_p) \\stackrel{?}{=} transcript.LatestCommit()")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm",style:{marginRight:"0.01389em"}},"InitializeEphemeralIdentity"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"))),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07847em"}},"I"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.0785em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.958em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P")),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8747em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.113em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.1479em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"P"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,s.kt)("span",{parentName:"span"}))))))),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8979em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3.1362em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"i"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1645em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.357em",marginLeft:"0em",marginRight:"0.0714em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.5em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size3 size1 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"e")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.143em"}},(0,s.kt)("span",{parentName:"span"})))))))))))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"="),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"E"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},"))")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.4306em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2192"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7167em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},"\u2190"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"C")),(0,s.kt)("span",{parentName:"span",className:"mspace newline"}),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.4391em",verticalAlign:"-0.2861em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"D"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"c"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.1514em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight"},"p")))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.2861em"}},(0,s.kt)("span",{parentName:"span"})))))),(0,s.kt)("span",{parentName:"span",className:"mclose"},")"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,s.kt)("span",{parentName:"span",className:"mrel"},(0,s.kt)("span",{parentName:"span",className:"mop op-limits"},(0,s.kt)("span",{parentName:"span",className:"vlist-t"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"1.153em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-3em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span"},(0,s.kt)("span",{parentName:"span",className:"mop"},"="))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.5669em",marginLeft:"0em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"3em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mclose mtight"},"?"))))))))),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"r"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"an"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.02778em"}},"scr"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"i"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"pt"),(0,s.kt)("span",{parentName:"span",className:"mord"},"."),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"L"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"a"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"es"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.07153em"}},"tC"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"o"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"mmi"),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")))))),(0,s.kt)("p",null,"The above represents a sketch protocol, in reality there are a few implementation details worth pointing out:"),(0,s.kt)("p",null,"Once derived from the key derivation function (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"K"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"D"),(0,s.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\mathrm{KDF}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord mathrm"},"KDF")))))),") the key (",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"k")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"k")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.03148em"}},"k"))))),") is set ",(0,s.kt)("em",{parentName:"p"},"on")," the connection, meaning the authentication app doesn't do the encryption or decryption explicitly."),(0,s.kt)("p",null,"The concatenation of parts of the 3DH exchange is strictly ordered:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"DH of the Long term identity of the outbound connection by the ephemeral key of the inbound connection."),(0,s.kt)("li",{parentName:"ul"},"DH of the Long term identity of the inbound connection by the ephemeral key of the outbound connection."),(0,s.kt)("li",{parentName:"ul"},"DH of the two ephemeral identities of the inbound and outbound connections.")),(0,s.kt)("p",null,"This strict ordering ensures both sides of the connection derive the ",(0,s.kt)("em",{parentName:"p"},"same")," session key."),(0,s.kt)("h3",{id:"cryptographic-properties"},"Cryptographic Properties"),(0,s.kt)("p",null,"During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come from their peer (or at least, someone with possession of their peers secret key as it related to their onion address)."),(0,s.kt)("p",null,"Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and all encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant repudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied that a single message in the transcript must have originated from a peer, there is no way of linking any other message to the session."),(0,s.kt)("p",null,"Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the session key is made public it can be used to forge new messages in the transcript - and as such, any standalone transcript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation."))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/935f2afb.9e813847.js b/build-staging/it/assets/js/935f2afb.9e813847.js new file mode 100644 index 00000000..3c4520a9 --- /dev/null +++ b/build-staging/it/assets/js/935f2afb.9e813847.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Avanti","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Che cos\u2019\xe8 Cwtch?","href":"/it/docs/intro","docId":"intro"},{"type":"category","label":"Getting started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Supported Platforms","href":"/it/docs/getting-started/supported_platforms","docId":"getting-started/supported_platforms"}],"href":"/it/docs/category/getting-started"},{"type":"category","label":"Profili","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Un\'introduzione ai profili di Cwtch","href":"/it/docs/profiles/introduction","docId":"profiles/introduction"},{"type":"link","label":"Creare un nuovo profilo","href":"/it/docs/profiles/create-a-profile","docId":"profiles/create-a-profile"},{"type":"link","label":"Cambiare il tuo nome visualizzato","href":"/it/docs/profiles/change-name","docId":"profiles/change-name"},{"type":"link","label":"Modificare la tua password","href":"/it/docs/profiles/change-password","docId":"profiles/change-password"},{"type":"link","label":"Modificare la tua immagine del profilo","href":"/it/docs/profiles/change-profile-image","docId":"profiles/change-profile-image"},{"type":"link","label":"Sbloccare profili crittografati","href":"/it/docs/profiles/unlock-profile","docId":"profiles/unlock-profile"},{"type":"link","label":"Eliminare un profilo","href":"/it/docs/profiles/delete-profile","docId":"profiles/delete-profile"},{"type":"link","label":"Backup o esportazione di un profilo","href":"/it/docs/profiles/exporting-profile","docId":"profiles/exporting-profile"},{"type":"link","label":"Importare un profilo","href":"/it/docs/profiles/importing-a-profile","docId":"profiles/importing-a-profile"},{"type":"link","label":"Setting Availability Status","href":"/it/docs/profiles/availability-status","docId":"profiles/availability-status"},{"type":"link","label":"Setting Profile Attributes","href":"/it/docs/profiles/profile-info","docId":"profiles/profile-info"}],"href":"/it/docs/category/profiles"},{"type":"category","label":"Conversations","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Un\'introduzione alla chat p2p di Cwtch","href":"/it/docs/chat/introduction","docId":"chat/introduction"},{"type":"link","label":"Starting a New Conversation","href":"/it/docs/chat/add-contact","docId":"chat/add-contact"},{"type":"link","label":"Accettare/Declinare nuove conversazioni","href":"/it/docs/chat/accept-deny-new-conversation","docId":"chat/accept-deny-new-conversation"},{"type":"link","label":"Sharing Cwtch Addresses","href":"/it/docs/chat/share-address-with-friends","docId":"chat/share-address-with-friends"},{"type":"link","label":"Salvare la cronologia delle conversazioni","href":"/it/docs/chat/save-conversation-history","docId":"chat/save-conversation-history"},{"type":"link","label":"Formattazione messaggio","href":"/it/docs/chat/message-formatting","docId":"chat/message-formatting"},{"type":"link","label":"Accessing Conversation Settings","href":"/it/docs/chat/conversation-settings","docId":"chat/conversation-settings"},{"type":"link","label":"Rispondere a un messaggio","href":"/it/docs/chat/reply-to-message","docId":"chat/reply-to-message"},{"type":"link","label":"Condividere un file","href":"/it/docs/chat/share-file","docId":"chat/share-file"},{"type":"link","label":"Bloccare un contatto","href":"/it/docs/chat/block-contact","docId":"chat/block-contact"},{"type":"link","label":"Sbloccare un contatto","href":"/it/docs/chat/unblock-contact","docId":"chat/unblock-contact"},{"type":"link","label":"Removing a Conversation","href":"/it/docs/chat/delete-contact","docId":"chat/delete-contact"}],"href":"/it/docs/category/conversations"},{"type":"category","label":"Groups","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Un\'introduzione ai gruppi di Cwtch","href":"/it/docs/groups/introduction","docId":"groups/introduction"},{"type":"link","label":"Creare un nuovo gruppo","href":"/it/docs/groups/create-group","docId":"groups/create-group"},{"type":"link","label":"Inviare inviti a un gruppo","href":"/it/docs/groups/send-invite","docId":"groups/send-invite"},{"type":"link","label":"Accettare un Invito a un gruppo","href":"/it/docs/groups/accept-group-invite","docId":"groups/accept-group-invite"},{"type":"link","label":"Come lasciare un gruppo","href":"/it/docs/groups/leave-group","docId":"groups/leave-group"},{"type":"link","label":"Modificare il nome di un gruppo","href":"/it/docs/groups/edit-group-name","docId":"groups/edit-group-name"},{"type":"link","label":"Gestire i server","href":"/it/docs/groups/manage-known-servers","docId":"groups/manage-known-servers"}],"href":"/it/docs/category/groups"},{"type":"category","label":"Servers","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduzione ai server","href":"/it/docs/servers/introduction","docId":"servers/introduction"},{"type":"link","label":"Come creare un server","href":"/it/docs/servers/create-server","docId":"servers/create-server"},{"type":"link","label":"Come modificare un server","href":"/it/docs/servers/edit-server","docId":"servers/edit-server"},{"type":"link","label":"Come eliminare un server","href":"/it/docs/servers/delete-server","docId":"servers/delete-server"},{"type":"link","label":"Come condividere il tuo pacchetto di chiavi del server","href":"/it/docs/servers/share-key","docId":"servers/share-key"},{"type":"link","label":"Come sbloccare un server","href":"/it/docs/servers/unlock-server","docId":"servers/unlock-server"}],"href":"/it/docs/category/servers"},{"type":"category","label":"Impostazioni","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Un\'introduzione alle impostazioni dell\'app di Cwtch","href":"/it/docs/settings/introduction","docId":"settings/introduction"},{"type":"category","label":"Aspetto","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cambia lingua","href":"/it/docs/settings/appearance/change-language","docId":"settings/appearance/change-language"},{"type":"link","label":"Modalit\xe0 chiara/scura e scomposizione dei temi","href":"/it/docs/settings/appearance/light-dark-mode","docId":"settings/appearance/light-dark-mode"},{"type":"link","label":"Colonne dell\' IU (Interfaccia Utente)","href":"/it/docs/settings/appearance/ui-columns","docId":"settings/appearance/ui-columns"},{"type":"link","label":"Modalit\xe0 Streamer/Presentazione","href":"/it/docs/settings/appearance/streamer-mode","docId":"settings/appearance/streamer-mode"}],"href":"/it/docs/category/appearance"},{"type":"category","label":"Comportamento","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Blocca connessioni sconosciute","href":"/it/docs/settings/behaviour/block-unknown-connections","docId":"settings/behaviour/block-unknown-connections"},{"type":"link","label":"Policy di notifica","href":"/it/docs/settings/behaviour/notification-policy","docId":"settings/behaviour/notification-policy"},{"type":"link","label":"Contenuto notifica","href":"/it/docs/settings/behaviour/notification-content","docId":"settings/behaviour/notification-content"}],"href":"/it/docs/category/behaviour"},{"type":"category","label":"Experiments","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Groups Experiment","href":"/it/docs/settings/experiments/group-experiment","docId":"settings/experiments/group-experiment"},{"type":"link","label":"Hosting di un server","href":"/it/docs/settings/experiments/server-hosting","docId":"settings/experiments/server-hosting"},{"type":"link","label":"Condivisione file","href":"/it/docs/settings/experiments/file-sharing","docId":"settings/experiments/file-sharing"},{"type":"link","label":"Anteprime immagine e immagini del profilo","href":"/it/docs/settings/experiments/image-previews-and-profile-pictures","docId":"settings/experiments/image-previews-and-profile-pictures"},{"type":"link","label":"Esperimento Link cliccabili","href":"/it/docs/settings/experiments/clickable-links","docId":"settings/experiments/clickable-links"},{"type":"link","label":"Formattazione messaggio","href":"/it/docs/settings/experiments/message-formatting","docId":"settings/experiments/message-formatting"},{"type":"link","label":"QR Codes","href":"/it/docs/settings/experiments/qrcodes","docId":"settings/experiments/qrcodes"}],"href":"/it/docs/category/experiments"}],"href":"/it/docs/category/settings"},{"type":"link","label":"Tor","href":"/it/docs/tor","docId":"tor"},{"type":"category","label":"Contribuisci","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Developing Cwtch","href":"/it/docs/contribute/developing","docId":"contribute/developing"},{"type":"link","label":"Testare Cwtch","href":"/it/docs/contribute/testing","docId":"contribute/testing"},{"type":"link","label":"Translating Cwtch","href":"/it/docs/contribute/translate","docId":"contribute/translate"},{"type":"link","label":"Documentation Style Guide","href":"/it/docs/contribute/documentation","docId":"contribute/documentation"},{"type":"link","label":"Stickers","href":"/it/docs/contribute/stickers","docId":"contribute/stickers"}],"href":"/it/docs/category/contribute"},{"type":"category","label":"Platforms","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Running Cwtch on Tails","href":"/it/docs/platforms/tails","docId":"platforms/tails"}],"href":"/it/docs/category/platforms"}]},"docs":{"chat/accept-deny-new-conversation":{"id":"chat/accept-deny-new-conversation","title":"Accettare/Declinare nuove conversazioni","description":"1. Vai al tuo profilo","sidebar":"tutorialSidebar"},"chat/add-contact":{"id":"chat/add-contact","title":"Starting a New Conversation","description":"1. Seleziona un profilo","sidebar":"tutorialSidebar"},"chat/block-contact":{"id":"chat/block-contact","title":"Bloccare un contatto","description":"1. Dalla finestra di una conversazione","sidebar":"tutorialSidebar"},"chat/conversation-settings":{"id":"chat/conversation-settings","title":"Accessing Conversation Settings","description":"In a conversation window, click on the Settings icon in the top bar.","sidebar":"tutorialSidebar"},"chat/delete-contact":{"id":"chat/delete-contact","title":"Removing a Conversation","description":"This feature will result in irreversible deletion. This cannot be undone.","sidebar":"tutorialSidebar"},"chat/introduction":{"id":"chat/introduction","title":"Un\'introduzione alla chat p2p di Cwtch","description":"Cwtch utilizza i servizi onion di Tor v3 per stabilire connessioni anonime, peer-to-peer tra profili.","sidebar":"tutorialSidebar"},"chat/message-formatting":{"id":"chat/message-formatting","title":"Formattazione messaggio","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento di formattazione messaggio attivato.","sidebar":"tutorialSidebar"},"chat/reply-to-message":{"id":"chat/reply-to-message","title":"Rispondere a un messaggio","description":"1. Seleziona un messaggio a cui desideri rispondere","sidebar":"tutorialSidebar"},"chat/save-conversation-history":{"id":"chat/save-conversation-history","title":"Salvare la cronologia delle conversazioni","description":"Come impostazione predefinita, per la privacy, Cwtch non conserva la cronologia delle conversazioni tra diverse sessioni.","sidebar":"tutorialSidebar"},"chat/share-address-with-friends":{"id":"chat/share-address-with-friends","title":"Sharing Cwtch Addresses","description":"There are many ways to share a Cwtch address.","sidebar":"tutorialSidebar"},"chat/share-file":{"id":"chat/share-file","title":"Condividere un file","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento di condivisione file attivato.","sidebar":"tutorialSidebar"},"chat/unblock-contact":{"id":"chat/unblock-contact","title":"Sbloccare un contatto","description":"1. Seleziona il contatto nella tua lista conversazioni. I contatti bloccati vengono spostati in fondo alla lista.","sidebar":"tutorialSidebar"},"contribute/developing":{"id":"contribute/developing","title":"Developing Cwtch","description":"This section documents some ways to get started with Cwtch Development.","sidebar":"tutorialSidebar"},"contribute/documentation":{"id":"contribute/documentation","title":"Documentation Style Guide","description":"This section documents the expected structure and quality of Cwtch documentation.","sidebar":"tutorialSidebar"},"contribute/stickers":{"id":"contribute/stickers","title":"Stickers","description":"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email erinn@openprivacy.ca with details and an address for us to mail stickers to.","sidebar":"tutorialSidebar"},"contribute/testing":{"id":"contribute/testing","title":"Testare Cwtch","description":"Questa sezione documenta alcuni modi per iniziare a testare Cwtch.","sidebar":"tutorialSidebar"},"contribute/translate":{"id":"contribute/translate","title":"Translating Cwtch","description":"Se vuoi contribuire con delle traduzioni all\'applicazione di Cwtch o a questo manuale, ecco come fare","sidebar":"tutorialSidebar"},"getting-started/supported_platforms":{"id":"getting-started/supported_platforms","title":"Supported Platforms","description":"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).","sidebar":"tutorialSidebar"},"groups/accept-group-invite":{"id":"groups/accept-group-invite","title":"Accettare un Invito a un gruppo","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"groups/create-group":{"id":"groups/create-group","title":"Creare un nuovo gruppo","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"groups/edit-group-name":{"id":"groups/edit-group-name","title":"Modificare il nome di un gruppo","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"groups/introduction":{"id":"groups/introduction","title":"Un\'introduzione ai gruppi di Cwtch","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"groups/leave-group":{"id":"groups/leave-group","title":"Come lasciare un gruppo","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"groups/manage-known-servers":{"id":"groups/manage-known-servers","title":"Gestire i server","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"groups/send-invite":{"id":"groups/send-invite","title":"Inviare inviti a un gruppo","description":"Questa funzione richiede Esperimenti abilitati e l\'Esperimento Gruppi attivato.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Che cos\u2019\xe8 Cwtch?","description":"Cwtch (/k\u028at\u0283/ - una parola gallese che si traduce approssimativamente in \u201cun abbraccio che crea un luogo sicuro\u201d) \xe8 un\'applicazione di messaggistica decentralizzata, rispettosa della privacy e resistente ai metadati.","sidebar":"tutorialSidebar"},"platforms/tails":{"id":"platforms/tails","title":"Running Cwtch on Tails","description":"This functionality is currently only available in the Nightly Release builds of Cwtch.","sidebar":"tutorialSidebar"},"profiles/availability-status":{"id":"profiles/availability-status","title":"Setting Availability Status","description":"This functionality is currently only available in the Nightly Release builds of Cwtch.","sidebar":"tutorialSidebar"},"profiles/change-name":{"id":"profiles/change-name","title":"Cambiare il tuo nome visualizzato","description":"1. Nel men\xfa Gestisci profili, premi la matita accanto al profilo che vuoi modificare","sidebar":"tutorialSidebar"},"profiles/change-password":{"id":"profiles/change-password","title":"Modificare la tua password","description":"1. Clicca sulla matita accanto al profilo che vuoi modificare","sidebar":"tutorialSidebar"},"profiles/change-profile-image":{"id":"profiles/change-profile-image","title":"Modificare la tua immagine del profilo","description":"Questa funzione richiede Esperimenti abilitati e sia Condivisione file sia Anteprime immagine e immagini dei profili attivate.","sidebar":"tutorialSidebar"},"profiles/create-a-profile":{"id":"profiles/create-a-profile","title":"Creare un nuovo profilo","description":"1. Clicca sul pulsante di azione \\"+\\" nell\'angolo in basso a destra e seleziona \\"Nuovo profilo\\"","sidebar":"tutorialSidebar"},"profiles/delete-profile":{"id":"profiles/delete-profile","title":"Eliminare un profilo","description":"Questa funzione comporter\xe0 la cancellazione irreversibile di materiale chiave. Non pu\xf2 essere annullata.","sidebar":"tutorialSidebar"},"profiles/exporting-profile":{"id":"profiles/exporting-profile","title":"Backup o esportazione di un profilo","description":"Nella schermata di Gestione del profilo:","sidebar":"tutorialSidebar"},"profiles/importing-a-profile":{"id":"profiles/importing-a-profile","title":"Importare un profilo","description":"1. Clicca sul pulsante di azione \\"+\\" nell\'angolo in basso a destra e seleziona \\"Importa profilo\\"","sidebar":"tutorialSidebar"},"profiles/introduction":{"id":"profiles/introduction","title":"Un\'introduzione ai profili di Cwtch","description":"Su Cwtch puoi creare uno o pi\xfa Profili. Ogni profilo genera una coppia di chiavi ed25519 casuale compatibile con la rete Tor.","sidebar":"tutorialSidebar"},"profiles/profile-info":{"id":"profiles/profile-info","title":"Setting Profile Attributes","description":"This functionality is currently only available in the Nightly Release builds of Cwtch.","sidebar":"tutorialSidebar"},"profiles/unlock-profile":{"id":"profiles/unlock-profile","title":"Sbloccare profili crittografati","description":"Quando riavvii Cwtch, se hai usato una password per proteggere il tuo profilo, esso non verr\xe0 caricato per impostazione predefinita, e dovrai sbloccarlo.","sidebar":"tutorialSidebar"},"servers/create-server":{"id":"servers/create-server","title":"Come creare un server","description":"Questa funzione richiede Esperimenti abilitati e l\' Esperimento di server hosting attivato.","sidebar":"tutorialSidebar"},"servers/delete-server":{"id":"servers/delete-server","title":"Come eliminare un server","description":"Questa funzione richiede Esperimenti abilitati e l\' Esperimento di server hosting attivato.","sidebar":"tutorialSidebar"},"servers/edit-server":{"id":"servers/edit-server","title":"Come modificare un server","description":"Questa funzione richiede Esperimenti abilitati e l\' Esperimento di server hosting attivato.","sidebar":"tutorialSidebar"},"servers/introduction":{"id":"servers/introduction","title":"Introduzione ai server","description":"Questa funzione richiede Esperimenti abilitati e l\' Esperimento di server hosting attivato.","sidebar":"tutorialSidebar"},"servers/share-key":{"id":"servers/share-key","title":"Come condividere il tuo pacchetto di chiavi del server","description":"Questa funzione richiede Esperimenti abilitati e l\' Esperimento di server hosting attivato.","sidebar":"tutorialSidebar"},"servers/unlock-server":{"id":"servers/unlock-server","title":"Come sbloccare un server","description":"Questa funzione richiede Esperimenti abilitati e l\' Esperimento di server hosting attivato.","sidebar":"tutorialSidebar"},"settings/appearance/change-language":{"id":"settings/appearance/change-language","title":"Cambia lingua","description":"Grazie all\'aiuto dei volontari, l\'app di Cwtch \xe8 stata tradotta in molte lingue.","sidebar":"tutorialSidebar"},"settings/appearance/light-dark-mode":{"id":"settings/appearance/light-dark-mode","title":"Modalit\xe0 chiara/scura e scomposizione dei temi","description":"1. Clicca sull\'icona impostazione","sidebar":"tutorialSidebar"},"settings/appearance/streamer-mode":{"id":"settings/appearance/streamer-mode","title":"Modalit\xe0 Streamer/Presentazione","description":"La modalit\xe0 Streamer/Presentazione rende l\'applicazione visivamente pi\xf9 privata. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens.","sidebar":"tutorialSidebar"},"settings/appearance/ui-columns":{"id":"settings/appearance/ui-columns","title":"Colonne dell\' IU (Interfaccia Utente)","description":"1. Clicca sull\'icona impostazione","sidebar":"tutorialSidebar"},"settings/behaviour/block-unknown-connections":{"id":"settings/behaviour/block-unknown-connections","title":"Blocca connessioni sconosciute","description":"By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. \xc8 possibile modificare questo comportamento tramite l\'impostazione \\"Blocco connessioni sconosciute\\".","sidebar":"tutorialSidebar"},"settings/behaviour/notification-content":{"id":"settings/behaviour/notification-content","title":"Contenuto notifica","description":"1. Vai alle impostazioni","sidebar":"tutorialSidebar"},"settings/behaviour/notification-policy":{"id":"settings/behaviour/notification-policy","title":"Policy di notifica","description":"1. Vai alle impostazioni","sidebar":"tutorialSidebar"},"settings/experiments/clickable-links":{"id":"settings/experiments/clickable-links","title":"Esperimento Link cliccabili","description":"Questa funzione, se abilitata, presenta un rischio di deanonimizzazione.","sidebar":"tutorialSidebar"},"settings/experiments/file-sharing":{"id":"settings/experiments/file-sharing","title":"Condivisione file","description":"These setting enables Cwtch filesharing functionality. This reveals the \\"Share File\\" option in the conversation pane, and allows you to download files from conversations.","sidebar":"tutorialSidebar"},"settings/experiments/group-experiment":{"id":"settings/experiments/group-experiment","title":"Groups Experiment","description":"Enables Cwtch to connect to untrusted servers and use them to host private, asynchronous, groups.","sidebar":"tutorialSidebar"},"settings/experiments/image-previews-and-profile-pictures":{"id":"settings/experiments/image-previews-and-profile-pictures","title":"Anteprime immagine e immagini del profilo","description":"This experiment requires the File Sharing experiment enabled.","sidebar":"tutorialSidebar"},"settings/experiments/message-formatting":{"id":"settings/experiments/message-formatting","title":"Formattazione messaggio","description":"When enabled, this experiment changes the conversation compose box to add message formatting UX.","sidebar":"tutorialSidebar"},"settings/experiments/qrcodes":{"id":"settings/experiments/qrcodes","title":"QR Codes","description":"This documentation page is a stub. You can help by expanding it.","sidebar":"tutorialSidebar"},"settings/experiments/server-hosting":{"id":"settings/experiments/server-hosting","title":"Hosting di un server","description":"L\'hosting di un server \xe8 attualmente una funzione sperimentale in Cwtch, non \xe8 tra le impostazioni predefinite.","sidebar":"tutorialSidebar"},"settings/introduction":{"id":"settings/introduction","title":"Un\'introduzione alle impostazioni dell\'app di Cwtch","description":"Aspetto","sidebar":"tutorialSidebar"},"tor":{"id":"tor","title":"Tor","description":"Cwtch utilizza Tor per routing e connessioni. L\'utilizzo dei servizi nascosti di Tor per ospitare profili e connessioni \\"effimere\\" generate al volo durante la creazione di una connessione fornisce forti garanzie di anonimato agli utenti di Cwtch.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/937969ee.9ce0fad1.js b/build-staging/it/assets/js/937969ee.9ce0fad1.js new file mode 100644 index 00000000..6a26b5b5 --- /dev/null +++ b/build-staging/it/assets/js/937969ee.9ce0fad1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[854],{2959:a=>{a.exports=JSON.parse('{"label":"planning","permalink":"/it/blog/tags/planning","allTagsPath":"/it/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9785.e0c467d7.js b/build-staging/it/assets/js/9785.e0c467d7.js new file mode 100644 index 00000000..b1c5c624 --- /dev/null +++ b/build-staging/it/assets/js/9785.e0c467d7.js @@ -0,0 +1 @@ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9785],{3905:(e,t,n)=>{"use strict";n.d(t,{Zo:()=>u,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=o.createContext({}),s=function(e){var t=o.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=s(e.components);return o.createElement(i.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=s(n),p=a,f=m["".concat(i,".").concat(p)]||m[p]||d[p]||r;return n?o.createElement(f,c(c({ref:t},u),{},{components:n})):o.createElement(f,c({ref:t},u))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,c=new Array(r);c[0]=p;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l[m]="string"==typeof e?e:a,c[1]=l;for(var s=2;s{"use strict";n.d(t,{Z:()=>u});var o=n(7294),a=n(5999),r=n(5281),c=n(7462),l=n(6010);const i={iconEdit:"iconEdit_Z9Sw"};function s(e){let{className:t,...n}=e;return o.createElement("svg",(0,c.Z)({fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,l.Z)(i.iconEdit,t),"aria-hidden":"true"},n),o.createElement("g",null,o.createElement("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})))}function u(e){let{editUrl:t}=e;return o.createElement("a",{href:t,target:"_blank",rel:"noreferrer noopener",className:r.k.common.editThisPage},o.createElement(s,null),o.createElement(a.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page"},"Edit this page"))}},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var o=n(7462),a=n(7294),r=n(6010),c=n(5999),l=n(6668),i=n(9960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};function u(e){let{as:t,id:n,...u}=e;const{navbar:{hideOnScroll:m}}=(0,l.L)();if("h1"===t||!n)return a.createElement(t,(0,o.Z)({},u,{id:void 0}));const d=(0,c.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return a.createElement(t,(0,o.Z)({},u,{className:(0,r.Z)("anchor",m?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n}),u.children,a.createElement(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d},"\u200b"))}},1506:(e,t,n)=>{"use strict";n.d(t,{Z:()=>he});var o=n(7294),a=n(3905),r=n(7462),c=n(5742);var l=n(2389),i=n(6010),s=n(2949),u=n(6668);function m(){const{prism:e}=(0,u.L)(),{colorMode:t}=(0,s.I)(),n=e.theme,o=e.darkTheme||n;return"dark"===t?o:n}var d=n(5281),p=n(7594),f=n.n(p);const g=/title=(?["'])(?.*?)\1/,h=/\{(?<range>[\d,-]+)\}/,y={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function b(e,t){const n=e.map((e=>{const{start:n,end:o}=y[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${o})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:o,magicComments:a,metastring:r}=t;if(r&&h.test(r)){const e=r.match(h).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${r}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,o=f()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(o),code:n}}if(void 0===o)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);default:return b(Object.keys(y),t)}}(o,a),l=n.split("\n"),i=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),s=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let p=0;p<l.length;){const e=l[p].match(c);if(!e){p+=1;continue}const t=e.slice(1).find((e=>void 0!==e));s[t]?i[s[t]].range+=`${p},`:u[t]?i[u[t]].start=p:m[t]&&(i[m[t]].range+=`${i[m[t]].start}-${p-1},`),l.splice(p,1)}n=l.join("\n");const d={};return Object.entries(i).forEach((e=>{let[t,{range:n}]=e;f()(n).forEach((e=>{d[e]??=[],d[e].push(t)}))})),{lineClassNames:d,code:n}}const E={codeBlockContainer:"codeBlockContainer_Ckt0"};function k(e){let{as:t,...n}=e;const a=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[o,a]=e;const r=t[o];r&&"string"==typeof a&&(n[r]=a)})),n}(m());return o.createElement(t,(0,r.Z)({},n,{style:a,className:(0,i.Z)(n.className,E.codeBlockContainer,d.k.common.codeBlock)}))}const N={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function C(e){let{children:t,className:n}=e;return o.createElement(k,{as:"pre",tabIndex:0,className:(0,i.Z)(N.codeBlockStandalone,"thin-scrollbar",n)},o.createElement("code",{className:N.codeBlockLines},t))}var w=n(902);const B={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Z(e,t){const[n,a]=(0,o.useState)(),r=(0,o.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,o.useEffect)((()=>{r()}),[r]),function(e,t,n){void 0===n&&(n=B);const a=(0,w.zX)(t),r=(0,w.Ql)(n);(0,o.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,r),()=>t.disconnect()}),[e,a,r])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),r())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}const T={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]};var L={Prism:n(7410).Z,theme:T};function j(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _(){return _=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},_.apply(this,arguments)}var x=/\r\n|\r|\n/,O=function(e){0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},S=function(e,t){var n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)};function P(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&-1===t.indexOf(o)&&(n[o]=e[o]);return n}var z=function(e){function t(){for(var t=this,n=[],o=arguments.length;o--;)n[o]=arguments[o];e.apply(this,n),j(this,"getThemeDict",(function(e){if(void 0!==t.themeDict&&e.theme===t.prevTheme&&e.language===t.prevLanguage)return t.themeDict;t.prevTheme=e.theme,t.prevLanguage=e.language;var n=e.theme?function(e,t){var n=e.plain,o=Object.create(null),a=e.styles.reduce((function(e,n){var o=n.languages,a=n.style;return o&&!o.includes(t)||n.types.forEach((function(t){var n=_({},e[t],a);e[t]=n})),e}),o);return a.root=n,a.plain=_({},n,{backgroundColor:null}),a}(e.theme,e.language):void 0;return t.themeDict=n})),j(this,"getLineProps",(function(e){var n=e.key,o=e.className,a=e.style,r=_({},P(e,["key","className","style","line"]),{className:"token-line",style:void 0,key:void 0}),c=t.getThemeDict(t.props);return void 0!==c&&(r.style=c.plain),void 0!==a&&(r.style=void 0!==r.style?_({},r.style,a):a),void 0!==n&&(r.key=n),o&&(r.className+=" "+o),r})),j(this,"getStyleForToken",(function(e){var n=e.types,o=e.empty,a=n.length,r=t.getThemeDict(t.props);if(void 0!==r){if(1===a&&"plain"===n[0])return o?{display:"inline-block"}:void 0;if(1===a&&!o)return r[n[0]];var c=o?{display:"inline-block"}:{},l=n.map((function(e){return r[e]}));return Object.assign.apply(Object,[c].concat(l))}})),j(this,"getTokenProps",(function(e){var n=e.key,o=e.className,a=e.style,r=e.token,c=_({},P(e,["key","className","style","token"]),{className:"token "+r.types.join(" "),children:r.content,style:t.getStyleForToken(r),key:void 0});return void 0!==a&&(c.style=void 0!==c.style?_({},c.style,a):a),void 0!==n&&(c.key=n),o&&(c.className+=" "+o),c})),j(this,"tokenize",(function(e,t,n,o){var a={code:t,grammar:n,language:o,tokens:[]};e.hooks.run("before-tokenize",a);var r=a.tokens=e.tokenize(a.code,a.grammar,a.language);return e.hooks.run("after-tokenize",a),r}))}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.render=function(){var e=this.props,t=e.Prism,n=e.language,o=e.code,a=e.children,r=this.getThemeDict(this.props),c=t.languages[n];return a({tokens:function(e){for(var t=[[]],n=[e],o=[0],a=[e.length],r=0,c=0,l=[],i=[l];c>-1;){for(;(r=o[c]++)<a[c];){var s=void 0,u=t[c],m=n[c][r];if("string"==typeof m?(u=c>0?u:["plain"],s=m):(u=S(u,m.type),m.alias&&(u=S(u,m.alias)),s=m.content),"string"==typeof s){var d=s.split(x),p=d.length;l.push({types:u,content:d[0]});for(var f=1;f<p;f++)O(l),i.push(l=[]),l.push({types:u,content:d[f]})}else c++,t.push(u),n.push(s),o.push(0),a.push(s.length)}c--,t.pop(),n.pop(),o.pop(),a.pop()}return O(l),i}(void 0!==c?this.tokenize(t,o,c,n):[o]),className:"prism-code language-"+n,style:void 0!==r?r.root:{},getLineProps:this.getLineProps,getTokenProps:this.getTokenProps})},t}(o.Component);const A=z,I={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function W(e){let{line:t,classNames:n,showLineNumbers:a,getLineProps:c,getTokenProps:l}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const s=c({line:t,className:(0,i.Z)(n,a&&I.codeLine)}),u=t.map(((e,t)=>o.createElement("span",(0,r.Z)({key:t},l({token:e,key:t})))));return o.createElement("span",s,a?o.createElement(o.Fragment,null,o.createElement("span",{className:I.codeLineNumber}),o.createElement("span",{className:I.codeLineContent},u)):u,o.createElement("br",null))}var M=n(5999);function H(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"}))}function D(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))}const V={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function R(e){let{code:t,className:n}=e;const[a,r]=(0,o.useState)(!1),c=(0,o.useRef)(void 0),l=(0,o.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const o=document.createElement("textarea"),a=document.activeElement;o.value=e,o.setAttribute("readonly",""),o.style.contain="strict",o.style.position="absolute",o.style.left="-9999px",o.style.fontSize="12pt";const r=document.getSelection(),c=r.rangeCount>0&&r.getRangeAt(0);n.append(o),o.select(),o.selectionStart=0,o.selectionEnd=e.length;let l=!1;try{l=document.execCommand("copy")}catch{}o.remove(),c&&(r.removeAllRanges(),r.addRange(c)),a&&a.focus()}(t),r(!0),c.current=window.setTimeout((()=>{r(!1)}),1e3)}),[t]);return(0,o.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),o.createElement("button",{type:"button","aria-label":a?(0,M.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,M.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,M.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.Z)("clean-btn",n,V.copyButton,a&&V.copyButtonCopied),onClick:l},o.createElement("span",{className:V.copyButtonIcons,"aria-hidden":"true"},o.createElement(H,{className:V.copyButtonIcon}),o.createElement(D,{className:V.copyButtonSuccessIcon})))}function $(e){return o.createElement("svg",(0,r.Z)({viewBox:"0 0 24 24"},e),o.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"}))}const F={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function q(e){let{className:t,onClick:n,isEnabled:a}=e;const r=(0,M.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return o.createElement("button",{type:"button",onClick:n,className:(0,i.Z)("clean-btn",t,a&&F.wordWrapButtonEnabled),"aria-label":r,title:r},o.createElement($,{className:F.wordWrapButtonIcon,"aria-hidden":"true"}))}function G(e){let{children:t,className:n="",metastring:a,title:c,showLineNumbers:l,language:s}=e;const{prism:{defaultLanguage:d,magicComments:p}}=(0,u.L)(),f=s??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??d,h=m(),y=function(){const[e,t]=(0,o.useState)(!1),[n,a]=(0,o.useState)(!1),r=(0,o.useRef)(null),c=(0,o.useCallback)((()=>{const n=r.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[r,e]),l=(0,o.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=r.current,n=e>t||r.current.querySelector("code").hasAttribute("style");a(n)}),[r]);return Z(r,l),(0,o.useEffect)((()=>{l()}),[e,l]),(0,o.useEffect)((()=>(window.addEventListener("resize",l,{passive:!0}),()=>{window.removeEventListener("resize",l)})),[l]),{codeBlockRef:r,isEnabled:e,isCodeScrollable:n,toggle:c}}(),b=function(e){return e?.match(g)?.groups.title??""}(a)||c,{lineClassNames:E,code:C}=v(t,{metastring:a,language:f,magicComments:p}),w=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return o.createElement(k,{as:"div",className:(0,i.Z)(n,f&&!n.includes(`language-${f}`)&&`language-${f}`)},b&&o.createElement("div",{className:N.codeBlockTitle},b),o.createElement("div",{className:N.codeBlockContent},o.createElement(A,(0,r.Z)({},L,{theme:h,code:C,language:f??"text"}),(e=>{let{className:t,tokens:n,getLineProps:a,getTokenProps:r}=e;return o.createElement("pre",{tabIndex:0,ref:y.codeBlockRef,className:(0,i.Z)(t,N.codeBlock,"thin-scrollbar")},o.createElement("code",{className:(0,i.Z)(N.codeBlockLines,w&&N.codeBlockLinesWithNumbering)},n.map(((e,t)=>o.createElement(W,{key:t,line:e,getLineProps:a,getTokenProps:r,classNames:E[t],showLineNumbers:w})))))})),o.createElement("div",{className:N.buttonGroup},(y.isEnabled||y.isCodeScrollable)&&o.createElement(q,{className:N.codeButton,onClick:()=>y.toggle(),isEnabled:y.isEnabled}),o.createElement(R,{className:N.codeButton,code:C}))))}function U(e){let{children:t,...n}=e;const a=(0,l.Z)(),c=function(e){return o.Children.toArray(e).some((e=>(0,o.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof c?G:C;return o.createElement(i,(0,r.Z)({key:String(a)},n),c)}var Q=n(9960);var X=n(6043);const Y={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function J(e){return!!e&&("SUMMARY"===e.tagName||J(e.parentElement))}function K(e,t){return!!e&&(e===t||K(e.parentElement,t))}function ee(e){let{summary:t,children:n,...a}=e;const c=(0,l.Z)(),s=(0,o.useRef)(null),{collapsed:u,setCollapsed:m}=(0,X.u)({initialState:!a.open}),[d,p]=(0,o.useState)(a.open),f=o.isValidElement(t)?t:o.createElement("summary",null,t??"Details");return o.createElement("details",(0,r.Z)({},a,{ref:s,open:d,"data-collapsed":u,className:(0,i.Z)(Y.details,c&&Y.isBrowser,a.className),onMouseDown:e=>{J(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;J(t)&&K(t,s.current)&&(e.preventDefault(),u?(m(!1),p(!0)):m(!0))}}),f,o.createElement(X.z,{lazy:!1,collapsed:u,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{m(e),p(!e)}},o.createElement("div",{className:Y.collapsibleContent},n)))}const te={details:"details_b_Ee"},ne="alert alert--info";function oe(e){let{...t}=e;return o.createElement(ee,(0,r.Z)({},t,{className:(0,i.Z)(ne,te.details,t.className)}))}var ae=n(2503);function re(e){return o.createElement(ae.Z,e)}const ce={containsTaskList:"containsTaskList_mC6p"};const le={img:"img_ev3q"};const ie="admonition_LlT9",se="admonitionHeading_tbUL",ue="admonitionIcon_kALy",me="admonitionContent_S0QG";const de={note:{infimaClassName:"secondary",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:o.createElement(M.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:o.createElement(M.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 16 16"},o.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:o.createElement(M.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},pe={secondary:"note",important:"info",success:"tip",warning:"danger"};function fe(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=o.Children.toArray(e),n=t.find((e=>o.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n,rest:a}}(e.children);return{...e,title:e.title??t,children:n}}const ge={head:function(e){const t=o.Children.map(e.children,(e=>o.isValidElement(e)?function(e){if(e.props?.mdxType&&e.props.originalType){const{mdxType:t,originalType:n,...a}=e.props;return o.createElement(e.props.originalType,a)}return e}(e):e));return o.createElement(c.Z,e,t)},code:function(e){const t=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return o.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")||(0,o.isValidElement)(e)&&t.includes(e.props?.mdxType)))?o.createElement("code",e):o.createElement(U,e)},a:function(e){return o.createElement(Q.Z,e)},pre:function(e){return o.createElement(U,(0,o.isValidElement)(e.children)&&"code"===e.children.props?.originalType?e.children.props:{...e})},details:function(e){const t=o.Children.toArray(e.children),n=t.find((e=>o.isValidElement(e)&&"summary"===e.props?.mdxType)),a=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return o.createElement(oe,(0,r.Z)({},e,{summary:n}),a)},ul:function(e){return o.createElement("ul",(0,r.Z)({},e,{className:(t=e.className,(0,i.Z)(t,t?.includes("contains-task-list")&&ce.containsTaskList))}));var t},img:function(e){return o.createElement("img",(0,r.Z)({loading:"lazy"},e,{className:(t=e.className,(0,i.Z)(t,le.img))}));var t},h1:e=>o.createElement(re,(0,r.Z)({as:"h1"},e)),h2:e=>o.createElement(re,(0,r.Z)({as:"h2"},e)),h3:e=>o.createElement(re,(0,r.Z)({as:"h3"},e)),h4:e=>o.createElement(re,(0,r.Z)({as:"h4"},e)),h5:e=>o.createElement(re,(0,r.Z)({as:"h5"},e)),h6:e=>o.createElement(re,(0,r.Z)({as:"h6"},e)),admonition:function(e){const{children:t,type:n,title:a,icon:r}=fe(e),c=function(e){const t=pe[e]??e,n=de[t];return n||(console.warn(`No admonition config found for admonition type "${t}". Using Info as fallback.`),de.info)}(n),l=a??c.label,{iconComponent:s}=c,u=r??o.createElement(s,null);return o.createElement("div",{className:(0,i.Z)(d.k.common.admonition,d.k.common.admonitionType(e.type),"alert",`alert--${c.infimaClassName}`,ie)},o.createElement("div",{className:se},o.createElement("span",{className:ue},u),l),o.createElement("div",{className:me},t))},mermaid:n(1875).Z};function he(e){let{children:t}=e;return o.createElement(a.Zo,{components:ge},t)}},2244:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var o=n(7294),a=n(6010),r=n(9960);function c(e){const{permalink:t,title:n,subLabel:c,isNext:l}=e;return o.createElement(r.Z,{className:(0,a.Z)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t},c&&o.createElement("div",{className:"pagination-nav__sublabel"},c),o.createElement("div",{className:"pagination-nav__label"},n))}},3008:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var o=n(7294),a=n(6010),r=n(9960);const c={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function l(e){let{permalink:t,label:n,count:l}=e;return o.createElement(r.Z,{href:t,className:(0,a.Z)(c.tag,l?c.tagWithCount:c.tagRegular)},n,l&&o.createElement("span",null,l))}},1526:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var o=n(7294),a=n(6010),r=n(5999),c=n(3008);const l={tags:"tags_jXut",tag:"tag_QGVx"};function i(e){let{tags:t}=e;return o.createElement(o.Fragment,null,o.createElement("b",null,o.createElement(r.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list"},"Tags:")),o.createElement("ul",{className:(0,a.Z)(l.tags,"padding--none","margin-left--sm")},t.map((e=>{let{label:t,permalink:n}=e;return o.createElement("li",{key:n,className:l.tag},o.createElement(c.Z,{label:t,permalink:n}))}))))}},7594:(e,t)=>{function n(e){let t,n=[];for(let o of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(o))n.push(parseInt(o,10));else if(t=o.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,o,a,r]=t;if(o&&r){o=parseInt(o),r=parseInt(r);const e=o<r?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(r+=e);for(let t=o;t!==r;t+=e)n.push(t)}}return n}t.default=n,e.exports=n}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/97ac6d59.270edd8e.js b/build-staging/it/assets/js/97ac6d59.270edd8e.js new file mode 100644 index 00000000..3c70e385 --- /dev/null +++ b/build-staging/it/assets/js/97ac6d59.270edd8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6758],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var i=t(7294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);r&&(i=i.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,i)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){n(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function c(e,r){if(null==e)return{};var t,i,n=function(e,r){if(null==e)return{};var t,i,n={},o=Object.keys(e);for(i=0;i<o.length;i++)t=o[i],r.indexOf(t)>=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)t=o[i],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var s=i.createContext({}),l=function(e){var r=i.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return i.createElement(s.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return i.createElement(i.Fragment,{},r)}},v=i.forwardRef((function(e,r){var t=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(t),v=n,m=u["".concat(s,".").concat(v)]||u[v]||d[v]||o;return t?i.createElement(m,a(a({ref:r},p),{},{components:t})):i.createElement(m,a({ref:r},p))}));function m(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var o=t.length,a=new Array(o);a[0]=v;var c={};for(var s in r)hasOwnProperty.call(r,s)&&(c[s]=r[s]);c.originalType=e,c[u]="string"==typeof e?e:n,a[1]=c;for(var l=2;l<o;l++)a[l]=t[l];return i.createElement.apply(null,a)}return i.createElement.apply(null,t)}v.displayName="MDXCreateElement"},4124:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var i=t(7462),n=(t(7294),t(3905));const o={sidebar_position:5},a="Come condividere il tuo pacchetto di chiavi del server",c={unversionedId:"servers/share-key",id:"servers/share-key",title:"Come condividere il tuo pacchetto di chiavi del server",description:"Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/share-key.md",sourceDirName:"servers",slug:"/servers/share-key",permalink:"/it/docs/servers/share-key",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/share-key.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Come eliminare un server",permalink:"/it/docs/servers/delete-server"},next:{title:"Come sbloccare un server",permalink:"/it/docs/servers/unlock-server"}},s={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,n.kt)(u,(0,i.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"come-condividere-il-tuo-pacchetto-di-chiavi-del-server"},"Come condividere il tuo pacchetto di chiavi del server"),(0,n.kt)("p",null,":::attenzione Esperimenti necessari"),(0,n.kt)("p",null,"Questa funzione richiede ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l' ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Esperimento di server hosting")," attivato."),(0,n.kt)("p",null,":::"),(0,n.kt)("p",null,"Il pacchetto di chiavi del server \xe8 il pacchetto di dati di cui un'app Cwtch ha bisogno per poter usare un server. Se vuoi solo far conoscere agli altri utenti Cwtch il tuo server, puoi condividere questo pacchetto con loro. Chi riceve il pacchetto avr\xe0 a quel punto la capacit\xe0 di creare i propri gruppi sul server."),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Vai all'icona del server"),(0,n.kt)("li",{parentName:"ol"},"Seleziona il server desiderato"),(0,n.kt)("li",{parentName:"ol"},'Utilizza l\'icona di "copia indirizzo" per copiare le chiavi del server'),(0,n.kt)("li",{parentName:"ol"},"Non condividere le chiavi con persone di cui non ti fidi")),(0,n.kt)("div",{width:"400"},(0,n.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,n.kt)("source",{src:"/video/Server_Keys.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/98bd2791.74ddfe18.js b/build-staging/it/assets/js/98bd2791.74ddfe18.js new file mode 100644 index 00000000..b8761b56 --- /dev/null +++ b/build-staging/it/assets/js/98bd2791.74ddfe18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8909],{6058:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/repliqate","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9944c673.96d5ab3f.js b/build-staging/it/assets/js/9944c673.96d5ab3f.js new file mode 100644 index 00000000..38b3f13e --- /dev/null +++ b/build-staging/it/assets/js/9944c673.96d5ab3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6457],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,o=function(e,t){if(null==e)return{};var n,a,o={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=a.createContext({}),l=function(e){var t=a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},u=function(e){var t=l(e.components);return a.createElement(c.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},p=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=l(n),p=o,m=d["".concat(c,".").concat(p)]||d[p]||h[p]||i;return n?a.createElement(m,r(r({ref:t},u),{},{components:n})):a.createElement(m,r({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=p;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:o,r[1]=s;for(var l=2;l<i;l++)r[l]=n[l];return a.createElement.apply(null,r)}return a.createElement.apply(null,n)}p.displayName="MDXCreateElement"},3832:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var a=n(7462),o=(n(7294),n(3905));const i={sidebar_position:2},r="Risk Model",s={unversionedId:"risk",id:"risk",title:"Risk Model",description:"Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/risk.md",sourceDirName:".",slug:"/risk",permalink:"/it/security/risk",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Cwtch Security Handbook",permalink:"/it/security/intro"},next:{title:"Cwtch Components",permalink:"/it/security/category/cwtch-components"}},c={},l=[{value:"Threat Model",id:"threat-model",level:2},{value:"Active Attacks",id:"active-attacks",level:3},{value:"Misrepresentation Attacks",id:"misrepresentation-attacks",level:4},{value:"A note on Physical Attacks",id:"a-note-on-physical-attacks",level:2}],u={toc:l},d="wrapper";function h(e){let{components:t,...i}=e;return(0,o.kt)(d,(0,a.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"risk-model"},"Risk Model"),(0,o.kt)("p",null,"Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking."),(0,o.kt)("p",null,(0,o.kt)("img",{src:n(5448).Z,width:"1920",height:"1080"})),(0,o.kt)("p",null,"Cwtch was originally conceived as an extension of the metadata resistant protocol Ricochet to support asynchronous, multi-peer group communications through the use of discardable, untrusted, anonymous infrastructure."),(0,o.kt)("p",null,"Since then, Cwtch has evolved into a protocol in its own right, this section will outline the various known risks that Cwtch attempts to mitigate and will be heavily referenced throughout the rest of the document when discussing the various sub-components of the Cwtch Architecture."),(0,o.kt)("h2",{id:"threat-model"},"Threat Model"),(0,o.kt)("p",null,"It is important to identify and understand that metadata is ubiquitous in communication protocols, it is indeed necessary for such protocols to function efficiently and at scale. However, information that is useful to facilitating peers and servers is also highly relevant to adversaries wishing to exploit such information."),(0,o.kt)("p",null,"For our problem definition, we will assume that the content of a communication is encrypted in such a way that an adversary is practically unable to break (see ",(0,o.kt)("a",{parentName:"p",href:"/security/category/tapir"},"tapir")," and ",(0,o.kt)("a",{parentName:"p",href:"security/category/cwtch"},"cwtch")," for details on the encryption that we use, a and as such we will focus to the context to the communication metadata."),(0,o.kt)("p",null,"We seek to protect the following communication contexts:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Who is involved in a communication? It may be possible to identify people or simply device or network identifiers. E.g., \u201cthis communication involves Alice, a journalist, and Bob a government employee.\u201d."),(0,o.kt)("li",{parentName:"ul"},"Where are the participants of the conversation? E.g., \u201cduring this communication Alice was in France and Bob was in Canada.\u201d"),(0,o.kt)("li",{parentName:"ul"},"When did a conversation take place? The timing and length of communication can reveal a large amount about the nature of a call, e.g., \u201cBob a government employee, talked to Alice on the phone for an hour yesterday evening. This is the first time they have communicated.\u201d *How was the conversation mediated? Whether a conversation took place over an encrypted or unencrypted email can provide useful intelligence. E.g., \u201cAlice sent an encrypted email to Bob yesterday, whereas they usually only send plaintext emails to each other.\u201d"),(0,o.kt)("li",{parentName:"ul"},"What is the conversation about? Even if the content of the communication is encrypted it is sometimes possible to derive a probable context of a conversation without knowing exactly what is said, e.g. \u201ca person called a pizza store at dinner time\u201d or \u201csomeone called a known suicide hotline number at 3am.\u201d")),(0,o.kt)("p",null,"Beyond individual conversations, we also seek to defend against context correlation attacks, whereby multiple conversations are analyzed to derive higher level information:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Relationships: Discovering social relationships between a pair of entities by analyzing the frequency and length of their communications over a period of time. E.g. Carol and Eve call each other every single day for multiple hours at a time."),(0,o.kt)("li",{parentName:"ul"},"Cliques: Discovering social relationships between a group of entities that all interact with each other. E.g. Alice, Bob and Eve all communicate with each other."),(0,o.kt)("li",{parentName:"ul"},"Loosely Connected Cliques and Bridge Individuals: Discovering groups that communicate to each other through intermediaries by analyzing communication chains (e.g. everytime Alice talks to Bob she talks to Carol almost immediately after; Bob and Carol never communicate.)"),(0,o.kt)("li",{parentName:"ul"},"Pattern of Life: Discovering which communications are cyclical and predictable. E.g. Alice calls Eve every Monday evening for around an hour.")),(0,o.kt)("h3",{id:"active-attacks"},"Active Attacks"),(0,o.kt)("h4",{id:"misrepresentation-attacks"},"Misrepresentation Attacks"),(0,o.kt)("p",null,"Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks based around misrepresentation i.e. people pretending to be other people:"),(0,o.kt)("p",null,"A basic flow of one of these attacks is as follows, although other flows also exist:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Alice has a friend named Bob and another called Eve"),(0,o.kt)("li",{parentName:"ul"},"Eve finds out Alice has a friend named Bob"),(0,o.kt)("li",{parentName:"ul"},"Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)"),(0,o.kt)("li",{parentName:"ul"},'Eve calls this new account "Eve New Account" and adds Alice as a friend.'),(0,o.kt)("li",{parentName:"ul"},'Eve then changes her name on "Eve New Account" to "Bob"'),(0,o.kt)("li",{parentName:"ul"},'Alice sends messages intended for "Bob" to Eve\'s fake Bob account')),(0,o.kt)("p",null,"Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them is for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply ",(0,o.kt)("em",{parentName:"p"},"won't-happen"),"."),(0,o.kt)("p",null,"As such we aim to provide some user-experience hints in the ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," to guide people in making choices around whether to trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users."),(0,o.kt)("h2",{id:"a-note-on-physical-attacks"},"A note on Physical Attacks"),(0,o.kt)("p",null,"Cwtch does not consider attacks that require physical access (or equivalent) to the users machine as practically defendable. However, in the interests of good security engineering, throughout this document we will still refer to attacks or conditions that require such privilege and point out where any mitigations we have put in place will fail."))}h.isMDXComponent=!0},5448:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/4-698e941dd333a7200cddec8d926e9ca9.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9947de33.8f316599.js b/build-staging/it/assets/js/9947de33.8f316599.js new file mode 100644 index 00000000..592debea --- /dev/null +++ b/build-staging/it/assets/js/9947de33.8f316599.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8098],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=p(n),d=o,h=u["".concat(s,".").concat(d)]||u[d]||m[d]||i;return n?r.createElement(h,a(a({ref:t},l),{},{components:n})):r.createElement(h,a({ref:t},l))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},7771:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={},a="Input",c={unversionedId:"components/ui/input",id:"components/ui/input",title:"Input",description:"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/input.md",sourceDirName:"components/ui",slug:"/components/ui/input",permalink:"/it/security/components/ui/input",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Image Previews",permalink:"/it/security/components/ui/image_previews"},next:{title:"Message Overlays",permalink:"/it/security/components/ui/overlays"}},s={},p=[{value:"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices",id:"risk-interception-of-cwtch-content-or-metadata-through-an-ime-on-mobile-devices",level:2}],l={toc:p},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"input"},"Input"),(0,o.kt)("h2",{id:"risk-interception-of-cwtch-content-or-metadata-through-an-ime-on-mobile-devices"},"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")),(0,o.kt)("p",null,"Any component that has the potential to intercept data between a person, and the Cwtch app is a potential security risk."),(0,o.kt)("p",null,"One of the most likely interceptors is a 3rd party IME (Input Method Editor) commonly used by people to generate characters not natively supported by their device."),(0,o.kt)("p",null,"Even benign and stock IME apps may unintentionally leak information about the contents of a persons message e.g. through cloud synchronization, cloud translation or personal dictionaries."),(0,o.kt)("p",null,"Ultimately, this problem cannot be solved by Cwtch alone, and is a wider risk impacting the entire mobile ecosystem."),(0,o.kt)("p",null,"A similar risk exists on desktop through the use of similar input applications (in addition to software keyloggers), however we consider that fully outside the scope of Cwtch risk assessment (in line with other attacks on the security of the underlying operating system itself)."),(0,o.kt)("p",null,"This is partially mitigated in Cwtch 1.2 through the use of ",(0,o.kt)("inlineCode",{parentName:"p"},"enableIMEPersonalizedLearning: false"),". See ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/142"},"this PR")," for more information."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9b12a270.6003290e.js b/build-staging/it/assets/js/9b12a270.6003290e.js new file mode 100644 index 00000000..25730cdd --- /dev/null +++ b/build-staging/it/assets/js/9b12a270.6003290e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9249],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>g});var r=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function o(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?a(Object(i),!0).forEach((function(t){n(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):a(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function c(e,t){if(null==e)return{};var i,r,n=function(e,t){if(null==e)return{};var i,r,n={},a=Object.keys(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)i=a[r],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var s=r.createContext({}),l=function(e){var t=r.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},d=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,a=e.originalType,s=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),p=l(i),h=n,g=p["".concat(s,".").concat(h)]||p[h]||u[h]||a;return i?r.createElement(g,o(o({ref:t},d),{},{components:i})):r.createElement(g,o({ref:t},d))}));function g(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=i.length,o=new Array(a);o[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:n,o[1]=c;for(var l=2;l<a;l++)o[l]=i[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,i)}h.displayName="MDXCreateElement"},9816:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=i(7462),n=(i(7294),i(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/it/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"10 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/it/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"repliqate",permalink:"/it/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/it/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/it/blog/cwtch-testing-i"}},s={authorsImageUrls:[void 0]},l=[{value:"Changes Necessary for Reproducible Android Bindings",id:"changes-necessary-for-reproducible-android-bindings",level:2},{value:"Repliqate Scripts",id:"repliqate-scripts",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],d={toc:l},p="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,r.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(4756).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"changes-necessary-for-reproducible-android-bindings"},"Changes Necessary for Reproducible Android Bindings"),(0,n.kt)("p",null,"After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Insufficient path stripping introduced by Android NDK tools")," - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/android/ndk/wiki/Changelog-r22"},"changed the binutils and default linker")," to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our ",(0,n.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-platform-support"},"long term support plan"),", we will be moving towards adopting the latest NDK in the future."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Paths in DWARF entries")," - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.")),(0,n.kt)("figure",null,(0,n.kt)("p",null,(0,n.kt)("a",{target:"_blank",href:i(4560).Z},(0,n.kt)("img",{src:i(9842).Z,width:"1863",height:"428"}))),(0,n.kt)("figcaption",null,"Vimdiff comparing the decoded (",(0,n.kt)("code",null,"readelf --debug-dump=line"),") DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("strong",{parentName:"li"},"Go Compiler Acquisition")," - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there ",(0,n.kt)("em",{parentName:"li"},"was")," a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.")),(0,n.kt)("h2",{id:"repliqate-scripts"},"Repliqate Scripts"),(0,n.kt)("p",null,"With those issues now fixed, Cwtch Android bindings are ",(0,n.kt)("strong",{parentName:"p"},"officially reproducible!")," The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script"},"cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script")," in the ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/"},"Cwtch Repliqate scripts repository"),"."),(0,n.kt)("p",null,"This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:i(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},4560:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/files/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},9842:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/aar-diff-cefdff70043215f9b9244cbc0a179078.png"},4756:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"},4515:(e,t,i)=>{i.d(t,{Z:()=>r});const r=i.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9dd8190d.904f5daf.js b/build-staging/it/assets/js/9dd8190d.904f5daf.js new file mode 100644 index 00000000..0fc2bc01 --- /dev/null +++ b/build-staging/it/assets/js/9dd8190d.904f5daf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2688],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),s=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=s(e.components);return i.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(n),g=a,m=h["".concat(c,".").concat(g)]||h[g]||d[g]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=g;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var s=2;s<o;s++)r[s]=n[s];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}g.displayName="MDXCreateElement"},7561:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var i=n(7462),a=(n(7294),n(3905));const o={title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/it/blog/autobindings",source:"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",date:"2023-02-24T00:00:00.000Z",formattedDate:"24 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"autobindings",permalink:"/it/blog/tags/autobindings"},{label:"libcwtch",permalink:"/it/blog/tags/libcwtch"}],readingTime:4.545,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Autogenerating Cwtch Bindings",description:"In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.",slug:"autobindings",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Compile-time Optional Application Experiments (Autobindings)",permalink:"/it/blog/autobindings-ii"},nextItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/it/blog/cwtch-testing-ii"}},c={authorsImageUrls:[void 0]},s=[{value:"A Brief History of Cwtch Bindings",id:"a-brief-history-of-cwtch-bindings",level:2},{value:"Cwtch Autobindings",id:"cwtch-autobindings",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:s},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to ",(0,a.kt)("strong",{parentName:"p"},"automatically generate")," these bindings: ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings"),"."),(0,a.kt)("p",null,"This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"path to Cwtch Stable"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})),(0,a.kt)("h2",{id:"a-brief-history-of-cwtch-bindings"},"A Brief History of Cwtch Bindings"),(0,a.kt)("p",null,"Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/therecipe/qt"},"therecipe/qt"),". However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework."),(0,a.kt)("p",null,"As part of early prototyping efforts for Flutter we built out a first version of ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libCwtch-go"),", and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings."),(0,a.kt)("p",null,"This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#the-cwtch-experiment-landscape"},"experimental features")," - handle settings, ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#bindings"},"duplication of logic between Cwtch and libCwtch-go"),", and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#appendix-a-special-behaviour-defined-by-libcwtch-go"},"special behaviour in libCwtch-go that better belongs in the core Cwtch library"),"."),(0,a.kt)("p",null,"As part of a broader effort to ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"refine the Cwtch API in preparation for Cwtch Stable")," we have taken the opportunity to fix many of these problems."),(0,a.kt)("h2",{id:"cwtch-autobindings"},"Cwtch Autobindings"),(0,a.kt)("p",null,"The current ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockContact")," API implementation is:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"//export c_BlockContact\nfunc c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {\n BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))\n}\n\nfunc BlockContact(profileOnion string, conversationID int) {\n profile := application.GetPeer(profileOnion)\n if profile != nil {\n profile.BlockConversation(conversationID)\n }\n}\n")),(0,a.kt)("p",null,"All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively."),(0,a.kt)("p",null,"In the new ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings"},"cwtch-autobindings")," we reduce these multiple lines to ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec#L19"},"a single one"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"profile BlockConversation conversation\n")),(0,a.kt)("p",null,"Defining a ",(0,a.kt)("inlineCode",{parentName:"p"},"profile"),"-level function, called ",(0,a.kt)("inlineCode",{parentName:"p"},"BlockConversation")," which takes in a single parameter of type ",(0,a.kt)("inlineCode",{parentName:"p"},"conversation"),"."),(0,a.kt)("p",null,"Using a similar boilerplate-reduction for the reset of ",(0,a.kt)("inlineCode",{parentName:"p"},"lib.go")," yields ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/README.md#spec-file-format"},"5-basic function prototypes"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CreateProfile")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"BlockConversation")),(0,a.kt)("li",{parentName:"ul"},"Profile-level functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"GetMessage")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"DownloadFile")),(0,a.kt)("li",{parentName:"ul"},"Experimental Profile-level feature functions that return data e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareFile"))),(0,a.kt)("p",null,"Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/autobindings/src/branch/main/spec"},"described in fewer than 50 lines, including comments"),". Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.)."),(0,a.kt)("h2",{id:"next-steps"},"Next Steps"),(0,a.kt)("p",null,"Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments"))," (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on ",(0,a.kt)("inlineCode",{parentName:"li"},"cwtch-server"),"). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dart Library generation"),": since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/cwtch"},"Dart-side")," of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-rs"},"libcwtch-rs")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Documentation generation"),": another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with ",(0,a.kt)("a",{parentName:"li",href:"https://cwtch.im"},"docs.cwtch.im"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch API"),": This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the ",(0,a.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design"},"Cwtch Stable API redesign"),". In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.")),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9e2a7473.b225b622.js b/build-staging/it/assets/js/9e2a7473.b225b622.js new file mode 100644 index 00000000..5475b1ac --- /dev/null +++ b/build-staging/it/assets/js/9e2a7473.b225b622.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1258],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=i.createContext({}),c=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},p=function(e){var t=c(e.components);return i.createElement(s.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=c(n),u=a,m=h["".concat(s,".").concat(u)]||h[u]||d[u]||o;return n?i.createElement(m,r(r({ref:t},p),{},{components:n})):i.createElement(m,r({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:a,r[1]=l;for(var c=2;c<o;c++)r[c]=n[c];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},8725:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var i=n(7462),a=(n(7294),n(3905));const o={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/it/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"13 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"},{label:"api",permalink:"/it/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/it/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/it/blog/path-to-cwtch-stable"}},s={authorsImageUrls:[void 0]},c=[{value:"Clarifying Terminology",id:"clarifying-terminology",level:3},{value:"Tenets of the Cwtch API Design",id:"tenets-of-the-cwtch-api-design",level:3},{value:"The Cwtch Experiment Landscape",id:"the-cwtch-experiment-landscape",level:3},{value:"The Problem with Experiments",id:"the-problem-with-experiments",level:3},{value:"Restricting Powerful Cwtch APIs",id:"restricting-powerful-cwtch-apis",level:3},{value:"Pre-Registered Hooks",id:"pre-registered-hooks",level:4},{value:"<code>ProtocolEngine</code> Subsystems",id:"protocolengine-subsystems",level:4},{value:"Impact on Enabling (Powerful) New Functionality",id:"impact-on-enabling-powerful-new-functionality",level:4},{value:"Application Experiments",id:"application-experiments",level:2},{value:"Bindings",id:"bindings",level:2},{value:"Timelines and Next Actions",id:"timelines-and-next-actions",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2},{value:"Appendix A: Special Behaviour Defined by libcwtch-go",id:"appendix-a-special-behaviour-defined-by-libcwtch-go",level:2}],p={toc:c},h="wrapper";function d(e){let{components:t,...o}=e;return(0,a.kt)(h,(0,i.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,a.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,a.kt)("p",null,"As we move out of Beta and ",(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,a.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(4867).Z,width:"1005",height:"481"})),(0,a.kt)("h3",{id:"clarifying-terminology"},"Clarifying Terminology"),(0,a.kt)("p",null,"Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtch")," refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Cwtchlib")," refers to the ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"reference implementation of the Cwtch Protocol")," / Application framework, currently written in Go."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Bindings")," refers to C/Java/Kotlin/Rust bindings (primarily ",(0,a.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"libcwtch-go"),") that act as an interface between Cwtchlib and downstream applications."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.")),(0,a.kt)("h3",{id:"tenets-of-the-cwtch-api-design"},"Tenets of the Cwtch API Design"),(0,a.kt)("p",null,"Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Robustness")," - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Completeness")," - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Security")," \u2013 experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.")),(0,a.kt)("h3",{id:"the-cwtch-experiment-landscape"},"The Cwtch Experiment Landscape"),(0,a.kt)("p",null,"A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Groups")," \u2013 the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Hybrid Groups")," - we have plans to upgrade the Groups experience to a more flexible \u201chybrid-groups\u201d protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," \u2013 like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Server Hosting")," \u2013 the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Message Formatting")," \u2013 notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search / Microblogging")," \u2013 proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status / Profile Metadata")," \u2013 proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.")),(0,a.kt)("h3",{id:"the-problem-with-experiments"},"The Problem with Experiments"),(0,a.kt)("p",null,"We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the ",(0,a.kt)("inlineCode",{parentName:"p"},"SendMessages")," interface that only allows callers to send messages."),(0,a.kt)("p",null,"We have also worked to package experimental functionality into so-called ",(0,a.kt)("strong",{parentName:"p"},"Gated Functionalities")," that are only available if a given experiment is turned on."),(0,a.kt)("p",null,"Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"SendMessages")," \u2013 there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing)."),(0,a.kt)("li",{parentName:"ul"},"The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality."),(0,a.kt)("li",{parentName:"ul"},"This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.")),(0,a.kt)("h3",{id:"restricting-powerful-cwtch-apis"},"Restricting Powerful Cwtch APIs"),(0,a.kt)("p",null,"To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through ",(0,a.kt)("inlineCode",{parentName:"li"},"Application")," and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile."),(0,a.kt)("li",{parentName:"ul"},"Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a ",(0,a.kt)("inlineCode",{parentName:"li"},"RestrictedCwtchConversationInterface")," which decorates a Cwtch Profile interface such that it can only interact with a single conversation \u2013 these can then be passed into hooks and interface functions to limit their impact."),(0,a.kt)("li",{parentName:"ul"},"Registered Hooks at pre-specified points with restricted capabilities \u2013 to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," to control which experiments get access to which events at a given time.")),(0,a.kt)("h4",{id:"pre-registered-hooks"},"Pre-Registered Hooks"),(0,a.kt)("p",null,"In order to implement certain functionality actions need to take place in-between events handled by ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),". As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group)."),(0,a.kt)("p",null,"This is currently only possible with invasive changes to the ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort."),(0,a.kt)("p",null,"We are introducing a new set of Cwtch APIs designed for this purpose:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnNewPeerMessage")," - hooked prior to inserting the message into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnPeerMessageConfirmed")," \u2013 hooked after a peer message has been inserted into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEncryptedGroupMessage")," \u2013 hooked after receiving an encrypted message from a group server."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnGroupMessageReceived")," \u2013 hooked after a successful decryption of a group message, but before inserting it into the database."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactRequestValue")," \u2013 hooked on request of a scoped (the permission level of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"public")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation")," level attributes), zoned ( relating to a specific feature e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"filesharing")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"chat"),"), and keyed (the name of the attribute e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"name")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest"),") value from a contact."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnContactReceiveValue")," \u2013 hooked on receipt of a requested scoped,zoned, and keyed value from a contact.")),(0,a.kt)("p",null,"Including the following APIs for managing hooked functionality:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the extension is interested processing."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," - returns a set of experiments that the extension is interested in being notified about"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," - to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeer")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (assuming all experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," is active)")),(0,a.kt)("h4",{id:"protocolengine-subsystems"},(0,a.kt)("inlineCode",{parentName:"h4"},"ProtocolEngine")," Subsystems"),(0,a.kt)("p",null,"As mentioned in our experiment summary, some functionality needs to be implemented directly in the ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),". The ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus)."),(0,a.kt)("p",null,"Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine"),"."),(0,a.kt)("p",null,"At the moment is this done through the concept of informal \u201csubsystems\u201d, modular add-ons to ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," ecosystem. "),(0,a.kt)("p",null,"We are formalizing this subsystem into an interface, similar to the hooked functionality in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," - returns a set of events that the subsystem needs to consume to operate."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," \u2013 to be called by ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," whenever an event registered with ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterEvents")," is called (when all the experiments registered through ",(0,a.kt)("inlineCode",{parentName:"li"},"RegisterExperiments")," are active)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"RegisterContexts")," - returns the set of contexts that the subsystem implements e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"im.cwtch.filesharing"))),(0,a.kt)("p",null,"This also requires a formalization of two ",(0,a.kt)("em",{parentName:"p"},"engine specific")," events (for use on the event bus):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SendCwtchMessage")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage")," that is used internally in ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," for messages between subsystems."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CwtchMessageReceived")," \u2013 encapsulating the existing ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.")),(0,a.kt)("p",null,"And the introduction of three ",(0,a.kt)("strong",{parentName:"p"},"additional")," ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEnine")," specific events:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StartEngineSubsystem")," \u2013 replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"StopEngineSubsystem")," \u2013 replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SubsystemStatus")," \u2013 a generic event that can be published by subsystems with a collection of fields useful for debugging")),(0,a.kt)("p",null,"This will allow us to move the following functionality, currently part of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," itself, into generic subsystems:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Attribute Lookup Handling")," - this functionality is currently part of the overloaded ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage")," function, filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter of the ",(0,a.kt)("inlineCode",{parentName:"li"},"CwtchPeerMessage"),". As such it can be entirely delegated to a subsystem. "),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Chunk Request Handling")," \u2013 this is also part of handlePeerMessage, also filtered using the ",(0,a.kt)("inlineCode",{parentName:"li"},"Context")," parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by ",(0,a.kt)("inlineCode",{parentName:"li"},"handlePeerMessage"),")"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing Start File Share/Stop File Share")," \u2013 this is currently part of the ",(0,a.kt)("inlineCode",{parentName:"li"},"handleEvent")," behaviour of ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," and can be moved into an ",(0,a.kt)("inlineCode",{parentName:"li"},"OnEvent")," handler of the file sharing subsystem (where such events are already processed).")),(0,a.kt)("p",null,"The introduction of pre-registered hooks in combination with the formalizations of ",(0,a.kt)("inlineCode",{parentName:"p"},"ProtocolEngine")," subsystems will allow the follow functionality, currently implemented in ",(0,a.kt)("inlineCode",{parentName:"p"},"CwtchPeer")," or libcwtch-go to be moved to standalone packages:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Filesharing")," makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Filesharing also depends on the file sharing subsystem to be enabled in a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine"),". This subsystem is responsible for processing chunk requests."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Profile Images")," \u2013 we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Legacy Groups")," \u2013 while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Status/Profile Metadata")," \u2013 status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.")),(0,a.kt)("h4",{id:"impact-on-enabling-powerful-new-functionality"},"Impact on Enabling (Powerful) New Functionality"),(0,a.kt)("p",null,"None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Search")," \u2013 a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Non Chat Conversation Contexts")," - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.")),(0,a.kt)("h2",{id:"application-experiments"},"Application Experiments"),(0,a.kt)("p",null,"One kind of experiment we haven\u2019t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting \u2013 this allows a Cwtch desktop client to setup and manage Cwtch Servers."),(0,a.kt)("p",null,"This kind of functionality doesn\u2019t belong in Cwtchlib \u2013 as it would necessarily introduce unrelated dependencies into the core library."),(0,a.kt)("p",null,"This functionality also doesn\u2019t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface."),(0,a.kt)("h2",{id:"bindings"},"Bindings"),(0,a.kt)("p",null,"The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications."),(0,a.kt)("p",null,"We can split the bindings into four core areas:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Management")," - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Application Experiments")," - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Core Profile Management")," - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Experimental Profile Features")," \u2013 auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.")),(0,a.kt)("p",null,"The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings."),(0,a.kt)("p",null,"In an ideal future, all of these bindings could be ",(0,a.kt)("strong",{parentName:"p"},"generated automatically")," from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)"),(0,a.kt)("p",null,"We can define three types of C/Java/Kotlin interface function templates:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileMethodName(profilehandle String, args...)")," \u2013 which directly resolves the Cwtch Profile and calls the function."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ProfileExperimentalMethodName(profilehandle String, args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ApplicationExperimentalMethodName(args...)")," \u2013 which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.")),(0,a.kt)("p",null,"All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ",(0,a.kt)("inlineCode",{parentName:"p"},"ProfileInterface")," for the first, exported methods of the various ",(0,a.kt)("inlineCode",{parentName:"p"},"Functionalities")," for the second, and ",(0,a.kt)("inlineCode",{parentName:"p"},"ApplicationExperiment")," definitions for the third."),(0,a.kt)("h2",{id:"timelines-and-next-actions"},"Timelines and Next Actions"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Freeze any changes to the bindings interface")," - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 \u2013 until we have implemented the proposed changes into cwtchlib."),(0,a.kt)("li",{parentName:"ul"},"As part of Cwtch 1.11 and 1.12 Release Cycles",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Implement the ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," Subsystem Design as outlined above."),(0,a.kt)("li",{parentName:"ul"},"Implement the Hooks API."),(0,a.kt)("li",{parentName:"ul"},"Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib \u2013 with the exception of behaviour related to Application Experiments (i.e. Server Hosting)."),(0,a.kt)("li",{parentName:"ul"},"Move event handling from the bindings into Application."),(0,a.kt)("li",{parentName:"ul"},"Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) \u2013 keeping the existing interface definitions."))),(0,a.kt)("li",{parentName:"ul"},"Once Automated UI Tests have been integrated into the Cwtch UI Repository:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings ",(0,a.kt)("strong",{parentName:"li"},"and")," a dart calling convention library from cwtchlib and any configured application experiments libraries"),(0,a.kt)("li",{parentName:"ul"},"Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process)."),(0,a.kt)("li",{parentName:"ul"},"At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.")))),(0,a.kt)("p",null,"As these changes are made, and these goals met we will be posting about them here! Subscribe to our ",(0,a.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,a.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,a.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all Cwtch development."),(0,a.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,a.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,a.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,a.kt)("p",null,"Donations of ",(0,a.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,a.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,a.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"A Photo of Cwtch Stickers",src:n(4515).Z,width:"1024",height:"768"})),(0,a.kt)("h2",{id:"appendix-a-special-behaviour-defined-by-libcwtch-go"},"Appendix A: Special Behaviour Defined by libcwtch-go"),(0,a.kt)("p",null,"The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Application Settings",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Including Enabling / Disabling Experiment"))),(0,a.kt)("li",{parentName:"ul"},"ACN Process Management - starting/stopping/restarting/configuring Tor."),(0,a.kt)("li",{parentName:"ul"},"Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)"),(0,a.kt)("li",{parentName:"ul"},"Logging Levels - configuring appropriate logging levels (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"INFO")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"DEBUG"),")"),(0,a.kt)("li",{parentName:"ul"},"Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled."),(0,a.kt)("li",{parentName:"ul"},"UI Contact Structures - aggregating contact information for the main Cwtch UI."),(0,a.kt)("li",{parentName:"ul"},"Group Experiment Functionality",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Experiment Gating"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfoList"),(0,a.kt)("li",{parentName:"ul"},"GetServerInfo"),(0,a.kt)("li",{parentName:"ul"},"UI Server Struct Definition"))),(0,a.kt)("li",{parentName:"ul"},"Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients."),(0,a.kt)("li",{parentName:"ul"},'"Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".'),(0,a.kt)("li",{parentName:"ul"},"Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled)."),(0,a.kt)("li",{parentName:"ul"},"Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process."),(0,a.kt)("li",{parentName:"ul"},"Cwtch Profile Engine Activation - starting/stopping a ",(0,a.kt)("inlineCode",{parentName:"li"},"ProtocolEngine")," when requested by the UI, or in response to changes in ACN state."),(0,a.kt)("li",{parentName:"ul"},"UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event."),(0,a.kt)("li",{parentName:"ul"},"File sharing restarts "),(0,a.kt)("li",{parentName:"ul"},"UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting ",(0,a.kt)("inlineCode",{parentName:"li"},"handle")," to a ",(0,a.kt)("inlineCode",{parentName:"li"},"conversation id"),"). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself."),(0,a.kt)("li",{parentName:"ul"},"Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)")))}d.isMDXComponent=!0},4867:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"},4515:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9e4087bc.582408aa.js b/build-staging/it/assets/js/9e4087bc.582408aa.js new file mode 100644 index 00000000..6b05be93 --- /dev/null +++ b/build-staging/it/assets/js/9e4087bc.582408aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3608],{3169:(e,t,a)=>{a.r(t),a.d(t,{default:()=>o});var r=a(7294),l=a(9960),n=a(5999),c=a(1944),m=a(7961);function s(e){let{year:t,posts:a}=e;return r.createElement(r.Fragment,null,r.createElement("h3",null,t),r.createElement("ul",null,a.map((e=>r.createElement("li",{key:e.metadata.date},r.createElement(l.Z,{to:e.metadata.permalink},e.metadata.formattedDate," - ",e.metadata.title))))))}function i(e){let{years:t}=e;return r.createElement("section",{className:"margin-vert--lg"},r.createElement("div",{className:"container"},r.createElement("div",{className:"row"},t.map(((e,t)=>r.createElement("div",{key:t,className:"col col--4 margin-vert--lg"},r.createElement(s,e)))))))}function o(e){let{archive:t}=e;const a=(0,n.I)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),l=(0,n.I)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),s=function(e){const t=e.reduceRight(((e,t)=>{const a=t.metadata.date.split("-")[0],r=e.get(a)??[];return e.set(a,[t,...r])}),new Map);return Array.from(t,(e=>{let[t,a]=e;return{year:t,posts:a}}))}(t.blogPosts);return r.createElement(r.Fragment,null,r.createElement(c.d,{title:a,description:l}),r.createElement(m.Z,null,r.createElement("header",{className:"hero hero--primary"},r.createElement("div",{className:"container"},r.createElement("h1",{className:"hero__title"},a),r.createElement("p",{className:"hero__subtitle"},l))),r.createElement("main",null,s.length>0&&r.createElement(i,{years:s}))))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/9f1c7621.b2660e0a.js b/build-staging/it/assets/js/9f1c7621.b2660e0a.js new file mode 100644 index 00000000..6afe45c0 --- /dev/null +++ b/build-staging/it/assets/js/9f1c7621.b2660e0a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1312],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>g});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function s(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=l(a),h=r,g=u["".concat(p,".").concat(h)]||u[h]||d[h]||i;return a?n.createElement(g,o(o({ref:t},c),{},{components:a})):n.createElement(g,o({ref:t},c))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:r,o[1]=s;for(var l=2;l<i;l++)o[l]=a[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},4387:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const i={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,s={permalink:"/it/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"17 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"support",permalink:"/it/blog/tags/support"},{label:"testing",permalink:"/it/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/it/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/it/blog/cwtch-android-reproducibility"}},p={authorsImageUrls:[void 0]},l=[{value:"Constraining Cwtch UI Fields",id:"constraining-cwtch-ui-fields",level:2},{value:"More Automated UI Tests",id:"more-automated-ui-tests",level:2},{value:"New Release of Cwtchbot",id:"new-release-of-cwtchbot",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:l},u="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(u,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,r.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6097).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"constraining-cwtch-ui-fields"},"Constraining Cwtch UI Fields"),(0,r.kt)("p",null,"Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3785).Z},(0,r.kt)("img",{src:a(6561).Z,width:"410",height:"90"}))),(0,r.kt)("figcaption",null,"Screenshot demonstrating how certain strings would violate the bounds of their containers.")),(0,r.kt)("p",null,"These cases were fixed by parenting impacted elements in a ",(0,r.kt)("inlineCode",{parentName:"p"},"Container")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"clip: hardEdge")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"decoration:BoxDecoration()")," (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration)."),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(3551).Z},(0,r.kt)("img",{src:a(9812).Z,width:"427",height:"76"}))),(0,r.kt)("figcaption",null,"Now these clipped strings are tightly constrained to their container bounds.")),(0,r.kt)("p",null,"These fixes are available in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/testing#cwtch-nightlies"},"latest Cwtch Nightly"),", and will be officially released in Cwtch 1.11."),(0,r.kt)("h2",{id:"more-automated-ui-tests"},"More Automated UI Tests"),(0,r.kt)("p",null,"We have added two new sets of automated UI tests to our pipeline:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"02: Global Settings")," - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/628"},"PR: 628"),")"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("em",{parentName:"li"},"04: Profile Management")," - these tests check that creating, unlocking, and deleting a profile work as expected. (",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/pulls/632"},"PR: 632"),")")),(0,r.kt)("h2",{id:"new-release-of-cwtchbot"},"New Release of Cwtchbot"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"Cwtchbot")," has been updated to use the latest Cwtch 0.18.10 API."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3551:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-after-452769c3b44432627b4533b37b3e9053.png"},3785:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},6097:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"},9812:(e,t,a)=>{a.d(t,{Z:()=>n});const n="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAasAAABMCAIAAABcRQ+0AAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO2deUBU57n/n3Nm34cBZhiYYVhkXwURxAV0kLggauK1McSkadIm2i1tr/mV5N70Nm1q9zXVtvc2aWLV2zSrsTFBiGiMYECibAIjwjBsMwPD7Ps55/4xhhIYYVhC7C/vR/+YOed93+/zDMzDe97lebHnD+4FBAKB+PxR06nFP2sbEAgE4jMDRUAEAvH5BUVABALx+QVFQAQC8fkFRUAEAvH5hf7pNS2JUUkUKpEsRhApE4RL2QIhmy+iMRgAQPh8brvFbbPaxg02o96iHzINak1D2k/PGAQCgZjJEkdABostT8mUrUiTxidLE5Jvq8pk8iWRfElkhCpx8qLhZo+hr0d/4/pId7vP415awxAIBGImSxYBxXJFbHaBMitPGn8r8Fmt1qampra2tp6eHq1Wq9frLRaL2+0GADabLRKJoqKiYmNjk5OTc3JyioqKpAnJ0oTkTHWFoa9H19Yy0NpkHhlcKvMQCARiJksQASUxqvj84ri8ImFkFADodLrTp0/X1tZevnz5dlXcbjeO426X++rVq3Q6vXRtiQQTSIQSM9glsvCY+GRpfHLSmtL+lsa+K5fQ0zECgfiUWFQEZPH4SWs2Jq0pFUcpAKCuru748eM1NTVzVuRxeU8+/sSHHzW9eea0ShH75aqHaGZK3zfYbun56R9+UVS8pqqqSq1WZ9+1KzZnlaahXtNwzuOwL8ZUBAKBmMnCI6AiIzd5bZkqpwAA6urqjhw5Mkunbyo4hlduqViZkD1hmWCz2dvLt0VwJGatEaPhToeDpKiampqamprCwsKDBw+q1eqC3fdLE1J6Pqgd7Li6YGsRCARiJguKgBiWXro1vXSrIEKq0+kOHz586tSp0Guz2exdm7a7BqxZaZkRYeEbVq91jdpJH0HDMLvdQVJkoNjly5cvX75cWVlZXV2tyimQxKg668901p8BilqIzQgEAjGDea8H5AhEBburCvc8KIiQnjx5ctOmTfMKfwCQkZrO93AoP8VhsMPDw8P4Iq/NAwCAgZ/wU58McKdOndq0adPJkycFEdLCPQ8W7K7iCETztRmBQCCCMr8IKIiQ5e/cl6neAQDV1dWHDh1yuVzzlcxITfdYXEABHaOnJaXQKBrpJwAAo+Eur5skyGnlXS7XoUOHqqurASBTvSN/5z5BhGy+oggEAjGTeURAQYRs5bY9SWs2Wq3WqqqqY8eOLUySz+H53X4KKBrQlDEK0k9SBAUANB5DNzro8/uC1jp27FhVVZXVak1as3Hltj0oCCIQiMUTagTkCEQ5W3YnFm4wGAz79u07f/78wjUxAIoCCiiSxHEa6SOAojAa7mX4R8f0JDm9DzjJ+fPn9+3bZzAYEgs35GzZjR6HEQjEIgktAmJY5uYdgd7fQw89dO3atcVIerwenEEHDEggHQ4H4fYDAI1B09uMo0b97HWvXbv20EMPBXqCmZt3AIYtxhIEAvE5J6S54PTSrYGxvwMHDiwy/AFAt6Zne5Ka9GMYEzebLaSfBAAan3GpsdFiscxZ/dq1awcOHDh+/HimeodjwtR57u1F2rMMVBx6Vhgpsxr1vU3vX69/Z9rdtJIteTv2ep1OfW9Xa80bQXfCzN5CgHt//CegqHFdf9f7Nbq2KzMLhCK0/oGvxmbnO80Tuo6W5tePf7ZCc3q9bEKheB2KEOJOA5szS74iI7do78OCCGl1dfWCx/5uiWFYrCK2vFR9f8W9gGMjFsMrb7zy8Ob9jhGrV0z+6MVftF/vCLGp/fv3Hz582DZmaHz5z2idIAKBWAA1nVrazoKMWUqwePyV2/dKE5JPnjz585//fDFiXA73sS9++dDXvpOfk8fksegsukDAz8/Jo9yE3+Vr13efOV/j9XlDbK21tVUul+cXFtGZ7OGuViLkistP6vry9Q9+NXX9ZtuY3jamX1v1aNHehzQN50i/P1Bgyzf+M0NdIU/O6P+okS0Q3f2fvxRFxejaW0JvAQDWVj2at+PepMKSnkvvAcC2b39/RVHpjcb6qZbMKcQWiHY88aPU9Zs5QvGopjNx9YZtj3/PaTFNDA0sv1AoXi+b0JxehyKEuNPoNVrmGAdMWrNRlVOg0+mefvrpxSiJheIfP/3DL+z+NwGfz2AwAhdpOI3D4fAVIjyKdfGjBvs89709/fTTOp1OlVOQtGbjYmz7tJEmJBn7NKTfF5dXlLxWHZ9frO/t9rn/uYqIIwrrvlgrT84AgI0PP85gc9rOnppXCwAgUcR1XXhXEBmlylldtPehyPik/pbGaZbMKaTIyPV53KbB/pj03AhVYl7FXrvJ2Pvh+5+JUCheL5vQnF6HIoS4A5mtDyiJUeVVfoHNF1ZXV3d0hPp8OhOhQPCT7z27MnsljUabeRej4Xaf4/W33xwzjc+rWb/fbzQat2/fzguTGHq7Xba5xxA/E5xWszIzT5aYQni9SWtKR7ra6v/866kFuCJx2oa7KJJMXb+ZFxZ++dUXRzWd82oBACiCSN1QzhWJBREyRUZux3v/aH33jWll5hQyDWplK9Jis1f5ve7U9eUep+3Ci8+5P/nBLptQKF4vm9CcXocihLjT6DVaZpsJic8vFkcp6urq5rvrYyocNuc/vl2dlZ6F47f6myRFulwuDpszeSVCEpGfk9d9Q0PNc8fbqVOn7rnnHrVaHZ9ffMemkDH2aVg8vtflwOn05jdPzBxod1ktDA7H63Qa+28EHc6fswUA0DTW5++6z+d2eV3O+ud/E3Sofk6hj6FwnKZpPBd0OH/ZhELxetmEQvF6TiHEHchtn4LFckVcXhEAHDlyZOGt43jllor83Lypvb9uTc+2vZVdvT2TV+h0+oqEFRw2ZwESAfPi8orEcsWC7fy0Of2zp0488cjpnz0V9NsVt7KQ8PkmhgcuvPicY2L8337w3NqqR6cWYAtEbL6AJIjRno7r9e8krl5f9fPnpz37p67fTBEESRKaS+/p2q4U7/vy3mePMD75kYYiJEtMIXw+XduV5tePL1goLFrp93r9Xs+FF58zjwxu+9b3t3/nmWle8yURhM9nG9M3v36cwebMNCZ1/WaeWOL3edvPnrpe/86nJxTKx1u878sUSXoc9rNHDuvarixMCHEHctsIGJtdIIyMqqurmyXjC5POwD4Gx3E6bXqPUiQUbd5YxuVwp14Ml0iy0jP5XN4nmmIwJ7uE8+Ly5ct1dXXCyKjY7IIFVA+Rgrv3P/T7v2WoKyavMBYUr4Miliu73j8rW5EKABsf+RaLyw8Mt0+SuGotRZLGPk10WrZQKs/dtsdlNWsazk0tI0/NGh/s97ndsTmr4vOLE1atHdfenDaYtWxCssRUTcM5niQicfWG/J37IhOSZs7Xz2nMsgmF4vWSCCHuQIKPAzJY7LwdX+CFhf/whz/s7e0NWpNBZ5Tnlo5M6EVcEZvBihSFKyNi9GbjZAEMw1TK2B2bttK8OI1Fn9z7wePytm3eKhJ+YkfHlWstzVev+HzBt8TNjtPp3LlzJ53J7L/SQBL+uSvcntIvfXPjI9/O2lzZc+k9v9czeT0mLUeakDx0vdXY1wMA6+5/rOSL3+AIRIMdHy1GLoAwUhafX4wBJKxaFxYde+XNkwPXmqYWMI8OylMyZStSCa83ZZ0aKOrCS793mk1Ty5B+nzw5U6JQEV5v0pqN47q+s0cOf1ZCTDZXtbKIKxKzuLz4vCLNpXPNb56YrzHLJhSK10sihLjTuO04oDwlUxqfrNPpZkl3KuYKB8dHwngiuUTOoNH8pL9d2zW1AIvB5DO5tkELU4AzeEygKDqbEbQpDIMNGzb0Dw+8U/Ouw+GYrxs1NTU6nU4ZnyxPyRxobZ5v9alExie57TY2X5Cprmh+47ZDOSRBkISfJInFaE0yMayLW1nkdTmshuELL/5u5mCWz+1y26wUSQJAf0vjh6++NLORgdbm7PJdHocdp9Gv/uPvHcEWii+bUGvNG2mlW1wWMwDUP/+boD+UOY1ZNqFQvF4SIcQdSPAV0QV3789UVxw9evTZZ5+9XU0eiwsAHp/HTxLKiJgwnqhD1018HBQwwBh0RkJs3H8eeiohLp4iKYqiaIxgc8EYxuaxxZFhhjHj95/5QcPlhgmLeZbdwUF56qmnDhw40F53uum1ha/ZTly9YcMDBzvqz6SsVZtHBt/66ZOTtwIfyIevHeuoO73g9hEIxCJRZuZt+OLXZxuDoqih69fOHvlxKK3VdGqD9wEDpx3V1tbOUtnhcU6+HhofzkvLHTbrxyy3VrRQQPkJvzRalpieyKaxvG5vIAXWNDAMY3JYwnARRsNFAtG3HvtGcV5h7du1A/pBrUHnI0J9KK6trT1w4MDkIU0LI2FVsd/n7ag9LUtMDYtW8sThDvP8FujMl9xtexJXr+cIRDQG0+tyWEaHm988YbjZPbXM+ge+Kk/OYPH4GIZ7nHb9jesfnPjT1OGwcGV8we77xXIFi8snCL/bbu1rvnTl1MlPuFawLqtsBy8snMHh+t1uh3m84723pw11LZvQkni9bEKheL0kQoiQwDAAwD5+MZP5ricJMg4oiVHlV95rtVqffPLJoHVmguO0L6mrGrubHe5/PsNSQK1cuXLLXVuEYSIGk4HTaDgGGAYYjuM4TqPRmGwmT8QXSIR0Bt3v8o1r9DQ6TRUbmx6elB2TzsDpPcO9IfozNDT0yCOPSKKiB641LXhhYOGeBy36kY73TovlClliKgA1dL01cGvaOGDB3fvv+tpTPo878BYAMtUV6x84uGrXfbnb7klZV8bkcAML01YUlZR88RsFu+/P2bI7Pr/YY7OaR4cCVdbc+0iWugIADH09Y9peoEAan6TMzu9rvjT5xdj+nWeUWfkeh83Q220eHWSyufLkDHlyxuQQO1sg2vat/5JEx1oNI/ob151mE18SochYyRNLJldsrCgqWVv1KJsvHBu4abzZ7XW5JApVbHaBc2LcNNi/zEJL4vWyCYXi9ZIIIULEahhpq3kTp9GiVqTNvGsbN5x44uGbTRdDbC34OKBEoQKApqYgg7gsBksiCJuwmT0+T2D+N1oSpTMOifnCmNgYu3v6EN7Q0LDX66WJaBwBl83jUCRJEiQFt4IajU7HaTiGgc/pHWrp9xE+tpRPo9NkGTHimHAhV9A9fKNjoGuGFcFpampSq9UShWphCwOzNley+cLui7UA0HWhJnXd5qik9BDr5lfuy9y8w2oY7WtpoDOYQqnc7/MCQOLq9cX3PmI3jd24fJ7OZCszVxbf92XT8IDVMMIWiBJWrXXZrbVHfzKmvTXXtPqeBzI2bc/fdd+Fv/wOAFLXl0fGJ49pe6c+j299/HuyFWmp68u73q8BgMJ7HuCKwjQN5y7+9Q+BAoII2dZvPh2XV/Tha8cC38CMTdsxDG98+fmAdwAQl1e04YGvpW/cqmmsX06hpfJ62YTm9HqphBCfFUEWoIhkMQDQ1tY28xaHxU5XJCdGqVYmZCXI4nLjMyMEEsDgi/seEIaLD3zpK4poBYP+z+kOl8tFkiSGAYYBTsNoDBqDzWCwmEw2k8li0ug4hgHhJQxdI5aRCZxFx2k4ANA5DF6UICJOujo9Hws5/1XA4IDxC0CZme9zuwJ7qqyGEYthWCxXhJKHlcHmJK/dZNWPvP6Db188drT++d+c+vF322reBIBMdYXP7Xr7V//V8L9/fv+l3ze/cYLJ5WdtrgQAZcZKJoc72N4y+bUBgA9ffclls4hl0YG30oRkDMMCTU1y9cyrGIZFxq0IvBVFKTwO2+T3EwBsY3pdewuTw1Nm5Qeu8CWRpsH+yWABAP0tjeO6m3xJ5DILLZXXyyY0p9dLJYT4rAjSBxREygCgp6dn5i2/3+/xe8dtE06PM4wvlvDF73c2UhRVuqGUB9zKrRXFq4v6tP3Xe7qGRoa5XO72u7byeXygAg/uH0NRgGEURQWiG+EjTH1jOJvOELAAA6CAAgrDMGG85AsP3vth/9WOrpA25AUMDhg/X9gCkUQZ57Ka8ypuzQt5XU4ag5leuuXyKy/OXjc+bw2bL+xrvjTzllAqNw32T/6Wu2wWn9spCJcCgFAmBwCLYaTi0LNh0cqJYd3pnz0FAB67jcUTBMpzhGLC7/N53Hu+/1u2QKRru3L+hd+OdLf7vR6OKCxQhsXjue223G170jaUA4Zfrz9z9cyrZv0QAITJFQDAYHOYbI7TMlH6pW8qMlZ6nPb3Xzoyqul0mici45PZApHbZlk2oSXxetmEQvF6qYQQnxXBImC4FAC02iDPkk6P63J3M0GSJEV6/F6nx+32eQCg+4OOtqFOVXLCuqLiNQVFq1bmE34Cx3Emk2nXW3wmN1fCp7PogGE4HSP9BE6n+VxeigS73uq2OAmfz2vxskRsBp/lGLYKYkV0DhOn417Ce+PmjRA9CRgcMH6+ZJXtYLDYjMio9I3bpl6XrZj7QTgsWgkATsvEtOsRqkQ6kyVNSCl77IlP3MAwAHDbbQAQrojjhYU3vf7Xor1fUmbl69qukIQfp99aK+5zu2g0etKaUpfNou/tVmTkBq6TBEGj3/rB+b1eJoerzMofaG2WKOMVGSuvnnnV7/EAAJ3JCjRC+H1MLk8cldz0+l/zKvYmrFo7qukkCD+GYRyhyG2zLJvQkni9bEKheL1UQojPiiA/ALZACAB6fZB0zSRFTp5k5PF5x3zjgf5aJFPyRu1p77u+438/cf/eqvVFxXweHwAoijJeH3UZ7BiG0ZgMDAcmj9XVc1Mg5HExJpvJYgvZOIcuTpVatSazZgwoABwEKnFAok/b75myLHl2AgYHjJ8v8pQsr9Nx/NCXpl7c+eRPxfIYoVRuNYzMUtfrcgIAVyyZdn1M20v4fKbB/tM//4+ZtfqvNKzadR9bIHKYxgr3fJGiSJOuf1qZiRGdKne13+flCETSuCTbuGFmOw6TUZSafbPp4orCDWyBaKgzSKpEp2VCECEd6W4vuHs/g8WeOVO0bEJL5fWyCc3p9VIJIeYF9zZ9ZwZr3ju1gowDsvkiAAglXfOtOQ0KXqg9YXFYXW7XTW3fj3/9k8f+/evvvFfjcDr8Th9OYkABRsO9To/b4jIOjz3/xitHThzXG8YooMLSZMKEMDqXIUqMYIdxSYIEDAscnAQAVrstdE8CBgeMnxfhyvgwuWL84znESYx9GhqdkV66dfJK0H17+t5ukiTkKZkzb9lNxrCY2Ljcwpm3HOZxt80qiJB2f1BHkcSYtnfmypvBjo+Aonji8KHOa4Bhw11BRmYt+mEMx0mSsBpHSZK4ESwdk2NinCsM63r/rNflcNss7bVvfVZCS+X1sgnN6fVSCSHmhSzYRDAAsHn83G175tXU9D4gTqPTGAwAcLvdITZBAXW+44NbrynK4/X29vX+8Oc/kkvlD27fv/WebQwZVxAlcgxZTd16sZC3d/s2h8eTvjadJ+VRtFtjhDQmLSwtksLBqbfpm3V2iZchYB9/ZfrGo1kIGExjBN92MgtpJXfhdPrMP++axvqk4o2BbZ7OiXEAiM1eRZLktEXRw12toz2d0alZO5/82WhPO+H3SxRxoz0drTVvtNedLtr70NqqR2NzCiz6YUGETCSTf3DiT4HdAm67VSxXFN/7iMdpb3rtrzMNM/ZpfB63LDElOiVzTNt76eR/zywzMawDgPTSrXQmS9NQH3QdgNNswnB888HvYhje/MbxmWvQlk1oqbxeNqFQvF4SIUQoMNicFYUlyWs3CSOjgpfAsKzNlbyw8N4P35+WJ+12hDQMwWFycuIzbE6bZqTPR/hSFUl8FtdgHR8cGyYpksNkS0URTo9LzBPRcPz6oIaiKD9BOK3e02fqm5s6FdFycYSYw2fTSVwVpizasprDZc/sT2E4Pu60vnOxXszl/e3yyw/ed39Pb6iDgItBlpjqdTqmZdYEAGOfxmbUi2UxYTGxHefejssriohNFETIej6om1by3d/9cOPD35IlpaWW3EX6/U6zaQQoAOj5oI7weTPLdigz8+JXFRNer21MLwiXBiKg3+vBcZrZMNT48vPTVs9OQvi8DJZwqKvt3P/8MmgBx8Q4AGAYfv38u40vPx+0jM/jDshdPfPq7Q7BWDahJfF62YRC8XpJhBChkLW5MmfL3bOXoTNZycWb5CmZrzz99VDaDLIrbv+vjtGZzKSkpMnT0MU8UWZs2pBpWMAR8FhcwEDAEdwc7ZOHRdndjhiJvN84MDox6vX5IoXhvXotANBp9F2F29anrdNZjG2abrvDwefxKRqFAQYYJhYLv/zYfTw+FwAIggAA0u23DZgtw+Y/nXpFbx4fsfV7KIdrPivmORyORqPxe73HvrU/9FoIBOJfhbwdX5gzAgawjRtCiYDBd8W57Ra+JFIkEgUiIIZhXr+3TdvpI/wDxiEcwwUcPo7jE3az1jBIARUbqRi3ToxZJwDA6rqV6V4eJtuQXRwtkSpk0tWJaeMWy5jFzIrkuq1unoRPY9Id3RNevsND+j648pFSFBkjiqAIkoHT0lSJ4zZzOEfWPxHqWugAIpEoYPy8aiEQiH8VWt76W/f7n9iqm1VemVayxT5ufPuX35t6nQg5R1SwCGiz8iWRMplsdHQUACiKcnpcALe6YwQQJvvE5GsAqPnoPZf3E4OGDBojOy5j3GSz273x0dFMBjM6WhYVGY4z6DQ5nUbHSYIk/CRh99Hp2Nq0bMLlB5ICDAOKSlclfNjV6ifYAlaY2T0WohsAIJPJAsaHXgWBQPxrMW2iKZDRhwJqwVv4g0xuBmbrVSpViE1MC38AECkKX5dW1Nnfe+1Gl8ftZQvY/AgBjUGnCNI1YbcbrWaD2WQw2SfsLpPDPeH0ON2EnwCKAoBwkYjL5mCASbhSHJtHztSAwWipAQKBCJ0gfUCbUQ8AyckLzLPCpDPyE3NVUkUYX+Lxer0+H0mRkSlyl9XlmXAAgM/vr7/aPDRmyEtOV0RIO7W941bL6tRMeXgEBsCg0fKS0t776DILuAJmmMUTamgPGBwwHoFAIEIhSAS06IcAICsra2EthvHFG7PWEQTJpNFrWxspitrF2eSt66Azb2kNj49d6rhKUuSIySgLCx80jpIUhWP49qJ1NBwHgBRF3IXWK36CCOfJbN4JkgopV2DA4IDxCAQCEQpBHjNNg1oAKChYyLEbTDojPzHHanfXtlwes5jj5THFWbksFhMoivARgQXUfoKgKBIA3F6PVj9MfJwMdTIPlkQoDBMIAYCOM1m0UBd5BwwOGI9AIBChEKQPaBrSGm72SBOSCwsLZzkmKSh8Dn9LXpnT5fMTpIjPj4uSs8VceYbSMmSyjVoCiQ9iIiJlkshR0z9PFOGzuamxcXTarXBMw/GcxKTrgx02j8VLhLQrrrCwUCgUGm72LCw1VlhMbP6Oe6NTs9rOnvroH39XZuZllu0Qy5VMLtfv8Yxpe8//5XfTzn5Vf+XfY3P++UfCbbOc/O5XAq+T1mzMVFfwwsJxOt1pNl098+qNxvMLsAqBQHzaBF8RbejrkSYkl5WVzSsCMmj0NamrpKIIUkDFRESyGEwMA9JHep0eu9E2uYmOxWRWFpe+dal+dGIMAPgcblleUVxU9NSmkhQqi3fM6XUGFZpJWVlZwOzQrZ1kw4Nfi81e5bSYJrPO0ugMj8P+0emX7SZDTHpuYsG6dVWP1v7hp1Nr0RgM05D2zR89Ma211PWbC+7eP9LT0XHubZ/LGZORa9EPL8AqBAIxJzevXFJkrNS2LvxEquARUH/jeqa6oqKiYpZzQmZCAVgdtjZtpzIiRsgVBOKJz+UdadNRJPVxEcAAosMj9paWX77ebjCbSnNXRYdHMj+ZJCNcIE6OTrjW3xFijuiKioqA2aFbO5VrZ15rqz11/y/+Enjbf/Vy/9VboX+w46owMmpm4gOcziD9QdYcJa8tM/Zpao/+JPC2r6VhYSYhEIg5MfZpXv3+44tpIXgEHOluN/T1KOOTy8vLZzkubhoE4W/sbr7a185hsiWCsCR5YnJMYmykIlIczqQxPg6CAAA4hkkEorK8Qh/h57BYOIYBAIWBw+WwOGy6saE+vVZvNoYY/srLy5VKpaGvZ6S7PURTp3Lhxedud0uZla/MzItQrei+eBYAssp35my5+/r5d668eZLGYBDBzvYMi1E2nPyfBZiBQCCWn+AR0Odx69papPHJVVVVoUdACsBH+H0uu81lN1rHe0f661rP8zi8Xz7zU5lCSbgJiqT8Lp/f7QMKAmlTMQxoLDqdy8RomMVp++mvnuu5qfETfh/h94e8qruqqgoAdG0tge2iS8WO/3c4IjYBAAx9PYHTEd02q8syEVh0TaMzwpTKB393gvD5bGOGjvdO32g8H5dXhGM4i8vf8/3fckUSn8fV13yp8e8vLKFVCARiCbltZoSB1qakNaVqtXoB8yEAQFGUj/D5CJ/L6/6wtVkVr2JzuXArA/Qni2K3/nXoum8O9Vud88iIBQCFhYVqtdpqHB1YxFhAUN76SbVYrojNXpW6bnPpw4+/8vTXNQ3nJk8j66w/4/d6xgf6lJl5aSV3Fezer7/RxQ+LIClyxZrSnkvv6dpbssoqU9ZvHtf1BQ6vQCAQdxq33XRhHhnsb2kEgIMHDy5GgKKoV956zWKzAhbo9GEY/sn/GAYYuNyut945bbaY59t+wLz+lsZP44Bq88hg67tvNL3+V0G4NGnNxqm3bjSe729ptI3pO+vPfHDiT2wePz5/jcUwguO0znNvt777xsTQwIUXn3NaTEFTByIQiDuB2bad9V25ZB4dVKvVlZWVi9EY0Y++9Ldj7ts/olIUdeHSxQ8+vDTfg9IrKyvVarV5dLDvSpBjOpYKt8MGFOW/vf2E30cB+D0eXdsVn9sVeHaexB9ymmsEArHMzJYf0DSk1TTUF+y+v7q6+uzZs5PJshbA66dPpSSmbFGX0+l0AKCA8nq9LCYLACiKuq7peuHEi/p/rJQAAAUuSURBVDa7fV5tcjic6upqANA01C9sGeDtWLWrSqJQjXS3m0cG5ckZyqx8m8nY19Kwoqgku3xn14WznfVn1I8eMvZrDDd7xFExaSVbnBZT4FF3uKstPr/YaZkYut6aun4zi8tH08EIxB3LHBlSNQ3npAkpqpyCZ5555tChQwuW8RP+Xx79DZvNKllbwqDTKZKaMJujpDKSJG/09f741z/r1807hD3zzDNKpVJ7rWlybG6pcFnNbH529l276SwW4fWaRwavnnkFALjCMF5YBFcs4YnDmRxupnoHo4Lj93gs+uHmN08EMhW/99+/KHvsibSSLdnluxzm8Y9Ov7ywGWoEArEMBMmQOg1FRm7R3ocFEdLq6upjx44tRozNYn3z0a/v3r7T7/d39lzPTMvQDmiffPZ7fdq++Ta1f//+w4cP28YMjS//ebAjyKk9CAQCMTs1ndq5008NdlztrD8DAIcPHy4pKVmMntvj+c0fnyMIgiRJ49iY2+0+8vwfFxD+SkpKDh8+DACd9WdQ+EMgEAsmpAR8nfVn2uveAoCjR4/m5OQsRk8oEOI47vF6hoYHcRxfEZ843xZycnKOHj0KAO11bwVCMwKBQCyM0FKQUlT72bc0DeeEQuELL7ywmCC4tnANAHR0dXZpuul0elFBIYfNDr16Tk7OCy+8IBQKNQ3n2s++BaFtGkEgEIighJqE2WWzXHvn9d7LF6RS6cmTJxfwOMxiMpUxyrsrdlEUdfrdt691tE2YzcoY5arcfB6XF/Qo3mmUlJScPHlSKpX2Xr5w7Z3XZ56TjUAgEPOCtrMgI8SiXqfDNDTAYLOjV6Tec889RqOxtbU1lIpMJrNo1epd23fuu/sLSYkrRg36o3/5o8vtjlOq0pJS8nJWxilVIqHYOG6c5XC4/fv3HzlyhMViaRrOXT3zmm0M5YJGIBCLotdomUcEBACv02Hs0wAG0oSUsrIyuVx+8eJFf7AUKVNhs9n377kvXhXvdruaWq688L8v9Wn7SZLs6ulyezwMOiNcIomSRfUP9OuNQU754HA4hw8ffvzxxwGgve6ta2+/uuBTURAIBGKSXqNl7tUwQcCw9NKt6aVbBRFSnU53+PDhU6emHzc+FTqdLuQLGEym3+93u1wOl/PjZjAGg8HjcJlMJklRNpvV7Zm+faKysrK6ulqpVNrGDJ31Zzrrz6CxPwQCsSTUdGoXFAEBAECRkZu8tkyVUwAAdXV1R44cWUAChVkoLCw8ePCgWq0GAO21pp4PatHCFwQCsYQsKgICAIvHT1qzMWlNqThKAQB1dXXHjx8PPZvW7SgvL6+qqgrEPvPooKahXtNwzuOY3545BAKBmJ3FRsAAkhhVfH5xXF6RMDIKAHQ63enTp2tra+fbJSwsLCwrK6uoqFAqlQBgNY72tzT2Xbm0tHt+EQgEIsDSRMAAYrkiNrtAmZUnjb910LDVam1qampra+vp6dFqtXq93mKxuN1uAGCz2SKRSCaTqVSq5OTkrKysgoICoVAYqGjo69G1tQy0Nn0aCa8QCAQiwFJGwAAMFluekilbkSaNT5YmzO/MdcPNHkNfj/7G9ZHu9qXN9oxAIBAzqenUzpEbZr74PO6B1uZATnlJjEqiUIlkMYJImSBcyhYI2XwRjcEAAMLnc9stbpvVNm6wGfUW/ZBpUIuedhEIxDKzxBFwKqahIEENp9EBgAz5DBAEAoH49PgUI2BQUOxDIBB3DqHuC0YgEIj//0AREIFAfH5BERCBQHx+QREQgUB8fvk/oU/HigH/qfEAAAAASUVORK5CYII="},6561:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/dl7-before-38cd04ba78b67745560d72a1872e4443.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a02b4022.36668ac2.js b/build-staging/it/assets/js/a02b4022.36668ac2.js new file mode 100644 index 00000000..e56df715 --- /dev/null +++ b/build-staging/it/assets/js/a02b4022.36668ac2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3492],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=p(a),u=r,d=m["".concat(s,".").concat(u)]||m[u]||h[u]||i;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:r,o[1]=l;for(var p=2;p<i;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},4889:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/cwtch-nightly-1-12",source:"@site/blog/2023-06-16-cwtch-1.12.md",title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",date:"2023-06-16T00:00:00.000Z",formattedDate:"16 giugno 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"release",permalink:"/it/blog/tags/release"}],readingTime:2.455,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.12",description:"Cwtch Beta 1.12 is now available for download",slug:"cwtch-nightly-1-12",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog13_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/it/blog/cwtch-stable-roadmap-update-june"},nextItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/it/blog/cwtch-nightly-v.11-74"}},s={authorsImageUrls:[void 0]},p=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},m="wrapper";function h(e){let{components:t,...i}=e;return(0,r.kt)(m,(0,n.Z)({},c,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.12 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new features like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"profile attributes"),", support for new platforms like ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/platforms/tails"},"Tails"),", and multiple improvements to performance and stability."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(159).Z,width:"1004",height:"480"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(8173).Z},(0,r.kt)("img",{src:a(5726).Z,width:"1388",height:"828"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.12")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Profile Attributes")," - profiles can now be augmented with ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/profile-info"},"additional public information")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Availability Status")," - you can now notify contacts that you ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/profiles/availability-status"},"are ",(0,r.kt)("strong",{parentName:"a"},"away")," or ",(0,r.kt)("strong",{parentName:"a"},"busy"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Five New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Japanese"),", ",(0,r.kt)("strong",{parentName:"li"},"Korean"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili")," and ",(0,r.kt)("strong",{parentName:"li"},"Swedish")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Support for Tails")," - adds an ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/docs/platforms/tails"},"OnionGrater")," configuration and a new ",(0,r.kt)("inlineCode",{parentName:"li"},"CWTCH_TAILS")," environment variable that enables special Tor behaviour."))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Based on Flutter 3.10"),(0,r.kt)("li",{parentName:"ul"},"Inter is now the main UI font"),(0,r.kt)("li",{parentName:"ul"},"New Font Scaling setting"),(0,r.kt)("li",{parentName:"ul"},"New Network Management code to better manage Tor on unstable networks"),(0,r.kt)("li",{parentName:"ul"},"File Sharing Experiment Fixes",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Fix performance issues for file bubble"),(0,r.kt)("li",{parentName:"ul"},"Allow restarting of file shares that have timed out"),(0,r.kt)("li",{parentName:"ul"},"Fix NPE in FileBubble caused by deleting the underlying file"),(0,r.kt)("li",{parentName:"ul"},"Move from RetVal to UpdateConversationAttributes to minimze UI thread issues"))),(0,r.kt)("li",{parentName:"ul"},"Updates to Linux install scripts to support more distributions"),(0,r.kt)("li",{parentName:"ul"},"Add a Retry Peer connection to prioritize connection attempts for certain conversations"),(0,r.kt)("li",{parentName:"ul"},"Updates to ",(0,r.kt)("inlineCode",{parentName:"li"},"_FlDartProject")," to allow custom setting of Flutter asset paths"))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Slovak"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Swahili"),", ",(0,r.kt)("strong",{parentName:"li"},"Swedish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Japanese")," (29%), ",(0,r.kt)("strong",{parentName:"li"},"Korean")," (23%), ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.12 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"libCwtch-autobindings-2023-06-13-10-50-v0.0.5"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}h.isMDXComponent=!0},8173:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},159:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog13-54310f46f23705b91f8a0a402a249ef7.png"},5726:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic1.12-a06a0594d75387abb048bc8009f595b2.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a4396826.a9e17b33.js b/build-staging/it/assets/js/a4396826.a9e17b33.js new file mode 100644 index 00000000..7186d097 --- /dev/null +++ b/build-staging/it/assets/js/a4396826.a9e17b33.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5089],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>g});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),u=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),l=u(r),m=i,g=l["".concat(c,".").concat(m)]||l[m]||d[m]||o;return r?n.createElement(g,a(a({ref:t},s),{},{components:r})):n.createElement(g,a({ref:t},s))}));function g(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var p={};for(var c in t)hasOwnProperty.call(t,c)&&(p[c]=t[c]);p.originalType=e,p[l]="string"==typeof e?e:i,a[1]=p;for(var u=2;u<o;u++)a[u]=r[u];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},3760:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>u});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:5},a="Accettare un Invito a un gruppo",p={unversionedId:"groups/accept-group-invite",id:"groups/accept-group-invite",title:"Accettare un Invito a un gruppo",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/accept-group-invite.md",sourceDirName:"groups",slug:"/groups/accept-group-invite",permalink:"/it/docs/groups/accept-group-invite",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/accept-group-invite.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Inviare inviti a un gruppo",permalink:"/it/docs/groups/send-invite"},next:{title:"Come lasciare un gruppo",permalink:"/it/docs/groups/leave-group"}},c={},u=[],s={toc:u},l="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"accettare-un-invito-a-un-gruppo"},"Accettare un Invito a un gruppo"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,i.kt)("p",null,":::"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Se qualcuno ti invia una richiesta di partecipazione a un gruppo"),(0,i.kt)("li",{parentName:"ol"},"Scegli se vuoi o meno unirti a questo gruppo"),(0,i.kt)("li",{parentName:"ol"},"Ora il gruppo \xe8 nella tua lista dei contatti")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Group_acceptinvite.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a65a3c47.547749ae.js b/build-staging/it/assets/js/a65a3c47.547749ae.js new file mode 100644 index 00000000..2632e8b9 --- /dev/null +++ b/build-staging/it/assets/js/a65a3c47.547749ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7591],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var o=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,o)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,o,n=function(e,t){if(null==e)return{};var a,o,n={},r=Object.keys(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o<r.length;o++)a=r[o],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=o.createContext({}),p=function(e){var t=o.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return o.createElement(c.Provider,{value:t},e.children)},h="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),h=p(a),u=n,m=h["".concat(c,".").concat(u)]||h[u]||d[u]||r;return a?o.createElement(m,i(i({ref:t},s),{},{components:a})):o.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,i=new Array(r);i[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var p=2;p<r;p++)i[p]=a[p];return o.createElement.apply(null,i)}return o.createElement.apply(null,a)}u.displayName="MDXCreateElement"},5432:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var o=a(7462),n=(a(7294),a(3905));const r={title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/it/blog/cwtch-developer-documentation",source:"@site/blog/2023-04-28-developer-docs.md",title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",date:"2023-04-28T00:00:00.000Z",formattedDate:"28 aprile 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/it/blog/tags/developer-documentation"}],readingTime:2.595,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",description:"In this development log we take a look at the new Cwtch developer docs!",slug:"cwtch-developer-documentation",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog9_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",permalink:"/it/blog/cwtch-nightly-v.11-74"},nextItem:{title:"Availability Status and Profile Attributes",permalink:"/it/blog/availability-status-profile-attributes"}},c={authorsImageUrls:[void 0]},p=[{value:"Cwtch Development Handbook",id:"cwtch-development-handbook",level:2},{value:"Release and Packaging Process",id:"release-and-packaging-process",level:3},{value:"Cwtch Application Development and Cwtchbot v0.1.0!",id:"cwtch-application-development-and-cwtchbot-v010",level:3},{value:"New Nightly",id:"new-nightly",level:3},{value:"Help us go further!",id:"help-us-go-further",level:2}],s={toc:p},h="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(h,(0,o.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"One of the larger remaining goals outlined in our ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"Cwtch Stable roadmap update")," is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents. "),(0,n.kt)("p",null,"In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!"),(0,n.kt)("p",null,"We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!"),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(3466).Z,width:"1005",height:"481"})),(0,n.kt)("h2",{id:"cwtch-development-handbook"},"Cwtch Development Handbook"),(0,n.kt)("p",null,"We have created a new documentation section, ",(0,n.kt)("a",{parentName:"p",href:"/developing/intro"},"the developers handbook"),". This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients)."),(0,n.kt)("h3",{id:"release-and-packaging-process"},"Release and Packaging Process"),(0,n.kt)("p",null,"The new handbook features a breakdown of ",(0,n.kt)("a",{parentName:"p",href:"/developing/release"},"Cwtch release processes")," - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created."),(0,n.kt)("h3",{id:"cwtch-application-development-and-cwtchbot-v010"},"Cwtch Application Development and Cwtchbot v0.1.0!"),(0,n.kt)("p",null,"For the first time ever we now have ",(0,n.kt)("a",{parentName:"p",href:"/developing/category/building-a-cwtch-app"},"comprehensive documentation on how to build a Cwtch Application"),". This section of the development handbook covers everything from ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"choosing a Cwtch library"),", to ",(0,n.kt)("a",{parentName:"p",href:"/developing/building-a-cwtch-app/building-an-echobot"},"building your first application"),"."),(0,n.kt)("p",null,"Together with this new documentation we have also ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/sarah/cwtchbot"},"released version 0.1 of the Cwtchbot framework"),", updating calls to use the ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-api-design"},"new Cwtch Stable API"),"."),(0,n.kt)("h3",{id:"new-nightly"},"New Nightly"),(0,n.kt)("p",null,"There is a ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#cwtch-nightlies"},"new Nightly build")," are available from our build server. The latest nightly we recommend testing is ",(0,n.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/flwtch-2023-04-26-20-57-v1.11.0-33-gb4371/"},"2023-04-26-20-57-v1.11.0-33-gb4371"),"."),(0,n.kt)("p",null,"This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the ",(0,n.kt)("a",{parentName:"p",href:"/docs/platforms/tails"},"in-development Tails support"),". "),(0,n.kt)("p",null,"In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices."),(0,n.kt)("p",null,"Please see the contribution documentation for advice on ",(0,n.kt)("a",{parentName:"p",href:"/docs/contribute/testing#submitting-feedback"},"submitting feedback")),(0,n.kt)("p",null,"Subscribe to our ",(0,n.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,n.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,n.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,n.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,n.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,n.kt)("p",null,"Donations of ",(0,n.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,n.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},3466:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/devlog9-db5594c3b12bd5d3baf3fe06894e1a6f.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>o});const o=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a6aa9e1f.8ac198c5.js b/build-staging/it/assets/js/a6aa9e1f.8ac198c5.js new file mode 100644 index 00000000..f9d14373 --- /dev/null +++ b/build-staging/it/assets/js/a6aa9e1f.8ac198c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3089],{46:(e,t,a)=>{a.r(t),a.d(t,{default:()=>u});var n=a(7294),r=a(6010),l=a(2263),i=a(1944),o=a(5281),s=a(9058),m=a(9703),c=a(197),g=a(9985);function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,l.Z)(),{blogDescription:r,blogTitle:o,permalink:s}=t,m="/"===s?a:o;return n.createElement(n.Fragment,null,n.createElement(i.d,{title:m,description:r}),n.createElement(c.Z,{tag:"blog_posts_list"}))}function d(e){const{metadata:t,items:a,sidebar:r}=e;return n.createElement(s.Z,{sidebar:r},n.createElement(g.Z,{items:a}),n.createElement(m.Z,{metadata:t}))}function u(e){return n.createElement(i.FG,{className:(0,r.Z)(o.k.wrapper.blogPages,o.k.page.blogListPage)},n.createElement(p,e),n.createElement(d,e))}},9703:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(5999),l=a(2244);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,r.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(l.Z,{permalink:a,title:n.createElement(r.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),i&&n.createElement(l.Z,{permalink:i,title:n.createElement(r.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},9985:(e,t,a)=>{a.d(t,{Z:()=>i});var n=a(7294),r=a(9460),l=a(390);function i(e){let{items:t,component:a=l.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(r.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a79c88c2.7b161edf.js b/build-staging/it/assets/js/a79c88c2.7b161edf.js new file mode 100644 index 00000000..84627bff --- /dev/null +++ b/build-staging/it/assets/js/a79c88c2.7b161edf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9976],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=r,u=h["".concat(c,".").concat(m)]||h[m]||g[m]||i;return a?n.createElement(u,o(o({ref:t},p),{},{components:a})):n.createElement(u,o({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:r,o[1]=l;for(var s=2;s<i;s++)o[s]=a[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},8553:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/cwtch-stable-api-design",source:"@site/blog/2023-01-13-cwtch-stable-api-design.md",title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",date:"2023-01-13T00:00:00.000Z",formattedDate:"13 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"},{label:"api",permalink:"/it/blog/tags/api"}],readingTime:17.28,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable API Design",description:"The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ",slug:"cwtch-stable-api-design",tags:["cwtch","cwtch-stable","planning","api"],image:"/img/devlog2_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/it/blog/cwtch-bindings-reproducible"},nextItem:{title:"Path to Cwtch Stable",permalink:"/it/blog/path-to-cwtch-stable"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function g(e){let{components:t,...i}=e;return(0,r.kt)(h,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications. "),(0,r.kt)("p",null,"As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages."),(0,r.kt)("p",null,"As we move out of Beta and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable"},"towards Cwtch Stable")," it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing."),(0,r.kt)("p",null,"In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(4867).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},4867:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog2-3f3a0725dfb20a2d49da23dd84274ec2.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a7e50e09.7b745cd8.js b/build-staging/it/assets/js/a7e50e09.7b745cd8.js new file mode 100644 index 00000000..9f76bccd --- /dev/null +++ b/build-staging/it/assets/js/a7e50e09.7b745cd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3763],{4698:s=>{s.exports=JSON.parse('{"label":"bindings","permalink":"/it/blog/tags/bindings","allTagsPath":"/it/blog/tags","count":4}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a8875a35.968c4441.js b/build-staging/it/assets/js/a8875a35.968c4441.js new file mode 100644 index 00000000..46472dff --- /dev/null +++ b/build-staging/it/assets/js/a8875a35.968c4441.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8801],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),m=o,h=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(h,i(i({ref:t},u),{},{components:n})):r.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l<a;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},5023:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:6},i="Documentation Style Guide",s={unversionedId:"contribute/documentation",id:"contribute/documentation",title:"Documentation Style Guide",description:"This section documents the expected structure and quality of Cwtch documentation.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/documentation.md",sourceDirName:"contribute",slug:"/contribute/documentation",permalink:"/it/docs/contribute/documentation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/documentation.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{sidebar_position:6},sidebar:"tutorialSidebar",previous:{title:"Translating Cwtch",permalink:"/it/docs/contribute/translate"},next:{title:"Stickers",permalink:"/it/docs/contribute/stickers"}},c={},l=[{value:"Screenshots and Cast of Characters",id:"screenshots-and-cast-of-characters",level:2},{value:"Dialogue and Content",id:"dialogue-and-content",level:2},{value:"Experiments",id:"experiments",level:2},{value:"Risks",id:"risks",level:2}],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"documentation-style-guide"},"Documentation Style Guide"),(0,o.kt)("p",null,"This section documents the expected structure and quality of Cwtch documentation."),(0,o.kt)("h2",{id:"screenshots-and-cast-of-characters"},"Screenshots and Cast of Characters"),(0,o.kt)("p",null,"Most Cwtch documentation should feature at least one screenshot or animated image. Screenshots of the Cwtch application should be focused on the feature being described by the documentation."),(0,o.kt)("p",null,"To ensure consistency between screenshots we suggest that the profile involved should serve particular, constant, roles."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Alice")," - used to represent the primary profile."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Bob")," - the primary contact, useful when demonstrating peer-to-peer features"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Carol")," - a secondary contact, useful when demonstrating group features"),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("strong",{parentName:"li"},"Mallory")," - representing a malicious peer (to be used when demonstrating blocking functionality)")),(0,o.kt)("h2",{id:"dialogue-and-content"},"Dialogue and Content"),(0,o.kt)("p",null,"Where screenshots and demonstrations show dialogue, conversations, and/or images please keep the conversations short, on a casual topic. Examples include:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Organizing a picnic"),(0,o.kt)("li",{parentName:"ul"},"Sharing photos from a vacation"),(0,o.kt)("li",{parentName:"ul"},"Sending a document for review")),(0,o.kt)("h2",{id:"experiments"},"Experiments"),(0,o.kt)("p",null,"All features that rely on an experiment being enabled should all this out prominently at the top of the page e.g.:"),(0,o.kt)("admonition",{title:"Experiments Required",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"This feature requires ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Experiments Enabled")," and the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Example Experiment")," turned on.")),(0,o.kt)("h2",{id:"risks"},"Risks"),(0,o.kt)("p",null,"If a feature might result in destruction of key material or permanent deletion of state, then these should also be called out at the top of the documentation e.g.:"),(0,o.kt)("admonition",{type:"warning"},(0,o.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,o.kt)("strong",{parentName:"p"},"irreversible")," deletion of key material. This ",(0,o.kt)("strong",{parentName:"p"},"cannot be undone"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/a8c7fdc6.455cd2f8.js b/build-staging/it/assets/js/a8c7fdc6.455cd2f8.js new file mode 100644 index 00000000..194d04c9 --- /dev/null +++ b/build-staging/it/assets/js/a8c7fdc6.455cd2f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4108],{6454:e=>{e.exports=JSON.parse('{"pluginId":"docs-security","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Cwtch Security Handbook","href":"/it/security/intro","docId":"intro"},{"type":"link","label":"Risk Model","href":"/it/security/risk","docId":"risk"},{"type":"category","label":"Cwtch Components","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Cwtch Technical Basics","href":"/it/security/components/intro","docId":"components/intro"},{"type":"link","label":"Component Ecosystem Overview","href":"/it/security/components/ecosystem-overview","docId":"components/ecosystem-overview"},{"type":"category","label":"Connectivity & Tor","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Connectivity","href":"/it/security/components/connectivity/intro","docId":"components/connectivity/intro"}],"href":"/it/security/category/connectivity--tor"},{"type":"category","label":"Tapir","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Packet Format","href":"/it/security/components/tapir/packet_format","docId":"components/tapir/packet_format"},{"type":"link","label":"Authentication Protocol","href":"/it/security/components/tapir/authentication_protocol","docId":"components/tapir/authentication_protocol"}],"href":"/it/security/category/tapir"},{"type":"category","label":"Cwtch","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Message Formats","href":"/it/security/components/cwtch/message_formats","docId":"components/cwtch/message_formats"},{"type":"link","label":"Key Bundles","href":"/it/security/components/cwtch/key_bundles","docId":"components/cwtch/key_bundles"},{"type":"link","label":"Groups","href":"/it/security/components/cwtch/groups","docId":"components/cwtch/groups"},{"type":"link","label":"Cwtch Server","href":"/it/security/components/cwtch/server","docId":"components/cwtch/server"}],"href":"/it/security/category/cwtch"},{"type":"category","label":"Cwtch UI","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Android Service","href":"/it/security/components/ui/android","docId":"components/ui/android"},{"type":"link","label":"Image Previews","href":"/it/security/components/ui/image_previews","docId":"components/ui/image_previews"},{"type":"link","label":"Input","href":"/it/security/components/ui/input","docId":"components/ui/input"},{"type":"link","label":"Message Overlays","href":"/it/security/components/ui/overlays","docId":"components/ui/overlays"}],"href":"/it/security/category/cwtch-ui"}],"href":"/it/security/category/cwtch-components"},{"type":"link","label":"Deployment","href":"/it/security/deployment","docId":"deployment"},{"type":"link","label":"Development","href":"/it/security/development","docId":"development"},{"type":"link","label":"References","href":"/it/security/references","docId":"references"}]},"docs":{"components/connectivity/intro":{"id":"components/connectivity/intro","title":"Connectivity","description":"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.","sidebar":"tutorialSidebar"},"components/cwtch/groups":{"id":"components/cwtch/groups","title":"Groups","description":"For the most part the Cwtch risk model for groups is split into two distinct profiles:","sidebar":"tutorialSidebar"},"components/cwtch/key_bundles":{"id":"components/cwtch/key_bundles","title":"Key Bundles","description":"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant.","sidebar":"tutorialSidebar"},"components/cwtch/message_formats":{"id":"components/cwtch/message_formats","title":"Message Formats","description":"Peer to Peer Messages","sidebar":"tutorialSidebar"},"components/cwtch/server":{"id":"components/cwtch/server","title":"Cwtch Server","description":"The goal of the Cwtch protocol is to enable group communication through Untrusted Infrastructure.","sidebar":"tutorialSidebar"},"components/ecosystem-overview":{"id":"components/ecosystem-overview","title":"Component Ecosystem Overview","description":"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem.","sidebar":"tutorialSidebar"},"components/intro":{"id":"components/intro","title":"Cwtch Technical Basics","description":"This page presents a brief technical overview of the Cwtch protocol.","sidebar":"tutorialSidebar"},"components/tapir/authentication_protocol":{"id":"components/tapir/authentication_protocol","title":"Authentication Protocol","description":"Each peer, given an open connection $C$:","sidebar":"tutorialSidebar"},"components/tapir/packet_format":{"id":"components/tapir/packet_format","title":"Packet Format","description":"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, len bytes of data, and the rest zero padded:","sidebar":"tutorialSidebar"},"components/ui/android":{"id":"components/ui/android","title":"Android Service","description":"Adapted from Integrating FFI processes with Android services","sidebar":"tutorialSidebar"},"components/ui/image_previews":{"id":"components/ui/image_previews","title":"Image Previews","description":"Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename\u2019s extension (and no, we\u2019re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they\u2019ll go to the app\u2019s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.","sidebar":"tutorialSidebar"},"components/ui/input":{"id":"components/ui/input","title":"Input","description":"Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices","sidebar":"tutorialSidebar"},"components/ui/overlays":{"id":"components/ui/overlays","title":"Message Overlays","description":"Adapted from Notes on the Cwtch Chat API","sidebar":"tutorialSidebar"},"deployment":{"id":"deployment","title":"Deployment","description":"Risk: Binaries are replaced on the website with malicious ones","sidebar":"tutorialSidebar"},"development":{"id":"development","title":"Development","description":"The main process to counter malicious actors in development of Cwtch is the openness of the process.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Cwtch Security Handbook","description":"Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes.","sidebar":"tutorialSidebar"},"references":{"id":"references","title":"References","description":"* Atwater, Erinn, and Sarah Jamie Lewis. \\"Token Based Services-Differences from Privacy Pass.\\"","sidebar":"tutorialSidebar"},"risk":{"id":"risk","title":"Risk Model","description":"Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/adfd2a96.2bed8868.js b/build-staging/it/assets/js/adfd2a96.2bed8868.js new file mode 100644 index 00000000..0dc623fc --- /dev/null +++ b/build-staging/it/assets/js/adfd2a96.2bed8868.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4268],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),s=c(r),m=o,f=s["".concat(u,".").concat(m)]||s[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},l),{},{components:r})):n.createElement(f,a({ref:t},l))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var p={};for(var u in t)hasOwnProperty.call(t,u)&&(p[u]=t[u]);p.originalType=e,p[s]="string"==typeof e?e:o,a[1]=p;for(var c=2;c<i;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},2700:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:7},a="Modificare il nome di un gruppo",p={unversionedId:"groups/edit-group-name",id:"groups/edit-group-name",title:"Modificare il nome di un gruppo",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/edit-group-name.md",sourceDirName:"groups",slug:"/groups/edit-group-name",permalink:"/it/docs/groups/edit-group-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/edit-group-name.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7},sidebar:"tutorialSidebar",previous:{title:"Come lasciare un gruppo",permalink:"/it/docs/groups/leave-group"},next:{title:"Gestire i server",permalink:"/it/docs/groups/manage-known-servers"}},u={},c=[],l={toc:c},s="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"modificare-il-nome-di-un-gruppo"},"Modificare il nome di un gruppo"),(0,o.kt)("p",null,":::attenzione Esperimenti necessari"),(0,o.kt)("p",null,"Questa funzione richiede ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,o.kt)("p",null,":::"),(0,o.kt)("p",null,"I nomi dei gruppi sono locali, personali e privati, non saranno condivisi."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Nel pannello della chat vai alle impostazioni"),(0,o.kt)("li",{parentName:"ol"},"Cambia il nome del gruppo"),(0,o.kt)("li",{parentName:"ol"},'Clicca su "Salva"'),(0,o.kt)("li",{parentName:"ol"},"Ora il tuo gruppo ha un nuovo nome")),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/group_edit.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ae271b89.fa96b586.js b/build-staging/it/assets/js/ae271b89.fa96b586.js new file mode 100644 index 00000000..ec8363e4 --- /dev/null +++ b/build-staging/it/assets/js/ae271b89.fa96b586.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7977],{3296:e=>{e.exports=JSON.parse('{"title":"Comportamento","slug":"/category/behaviour","permalink":"/it/docs/category/behaviour","navigation":{"previous":{"title":"Modalit\xe0 Streamer/Presentazione","permalink":"/it/docs/settings/appearance/streamer-mode"},"next":{"title":"Blocca connessioni sconosciute","permalink":"/it/docs/settings/behaviour/block-unknown-connections"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/af23c5f9.b63a4e5e.js b/build-staging/it/assets/js/af23c5f9.b63a4e5e.js new file mode 100644 index 00000000..bd3aec79 --- /dev/null +++ b/build-staging/it/assets/js/af23c5f9.b63a4e5e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3218],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var n=a(7294);function i(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?r(Object(a),!0).forEach((function(t){i(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,i=function(e,t){if(null==e)return{};var a,n,i={},r=Object.keys(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)a=r[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),h=p(a),m=i,d=h["".concat(s,".").concat(m)]||h[m]||u[m]||r;return a?n.createElement(d,o(o({ref:t},c),{},{components:a})):n.createElement(d,o({ref:t},c))}));function d(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[h]="string"==typeof e?e:i,o[1]=l;for(var p=2;p<r;p++)o[p]=a[p];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},4958:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var n=a(7462),i=(a(7294),a(3905));const r={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"31 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/it/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/it/blog/cwtch-nightly-1-11"}},s={authorsImageUrls:[void 0]},p=[{value:"Update on the January Roadmap",id:"update-on-the-january-roadmap",level:2},{value:"A Timeline for Cwtch Stable",id:"a-timeline-for-cwtch-stable",level:2},{value:"Get Involved",id:"get-involved",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],c={toc:p},h="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(h,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,i.kt)("strong",{parentName:"p"},"Beta")," to ",(0,i.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,i.kt)("p",null,"This post ",(0,i.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,i.kt)("p",null,(0,i.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,i.kt)("h2",{id:"update-on-the-january-roadmap"},"Update on the January Roadmap"),(0,i.kt)("p",null,"Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:"),(0,i.kt)("p",null,"(\u2705 means complete, \ud83d\udfe1 means in-progress, \u274c not started.)"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"finalized a feature set that defines Cwtch Stable")," and established a timeline for including these features in upcoming Cwtch Beta releases. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/security/intro"},"Security and Design Documents")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"Infrastructure and ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"Support")," \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"in addition to a new development blog. \u2705"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a ",(0,i.kt)("a",{parentName:"li",href:"/docs/contribute/documentation"},"style guide for documentation"),", and \u2705"),(0,i.kt)("li",{parentName:"ul"},"have used it to ensure that all Cwtch features have consistent documentation available, \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"with at least one screenshot (where applicable). \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published: ",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"Interface Specification Document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Release Process Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-platform-support"},"Support Plan document")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"a Cwtch Packaging Document \ud83d\udfe1"),(0,i.kt)("li",{parentName:"ul"},"a document describing the ",(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-bindings-reproducible"},"Reproducible Builds Process")," \u2705"),(0,i.kt)("li",{parentName:"ul"},"These documents will be available on the newly expanded Cwtch Documentation website \ud83d\udfe1"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. \u2705"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team \u274c"),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable \u2705 (this post!)")),(0,i.kt)("p",null,"While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings"},"Cwtch Autobindings")," with ",(0,i.kt)("a",{parentName:"li",href:"/blog/autobindings-ii"},"compile-time optional experiments")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"/blog/cwtch-nightly-1-11"},"Cwtch 1.11")," - with support for reproducible bindings, two new localizations (Slovak and Korean), in addition to a myriad of bug fixes and performance improvements."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," - a tool for testing and confirming reproducible builds processes based on Qemu, and a Debian Cloud image.")),(0,i.kt)("h2",{id:"a-timeline-for-cwtch-stable"},"A Timeline for Cwtch Stable"),(0,i.kt)("p",null,"Now for the big news, we plan on releasing a candidate Cwtch Stable release during ",(0,i.kt)("strong",{parentName:"p"},"Summer 2023"),". Here is our plan for getting there:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A Cwtch Release Process Document"),(0,i.kt)("li",{parentName:"ul"},"A Cwtch Packaging Document"),(0,i.kt)("li",{parentName:"ul"},"Completion of documentation of existing Cwtch features, including relevant screenshots."))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th April 2023")," the Cwtch team will have also released developer-centric documentation including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"A guide to building Cwtch-apps using official libraries"),(0,i.kt)("li",{parentName:"ul"},"Automatically generated API documentation for libCwtch"))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"30th June 2023")," the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"An implementation of ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/129"},"Conversation Search")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/27"},"Profile statuses")," and other associated information"),(0,i.kt)("li",{parentName:"ul"},"An update to the network handling code to allow for ",(0,i.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/593"},"better Protocol Engine management")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st July 2023")," the Cwtch team will have completed several infrastructure upgrades including:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist."),(0,i.kt)("li",{parentName:"ul"},"Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team"),(0,i.kt)("li",{parentName:"ul"},"New testing environments for F-droid, Whonix, Raspberry Pi and other ",(0,i.kt)("a",{parentName:"li",href:"/docs/getting-started/supported_platforms"},"partially supported systems")))),(0,i.kt)("li",{parentName:"ul"},"By ",(0,i.kt)("strong",{parentName:"li"},"31st August 2023")," the Cwtch team will have a released Cwtch Stable Release Candidate:",(0,i.kt)("ul",{parentName:"li"},(0,i.kt)("li",{parentName:"ul"},"At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable."),(0,i.kt)("li",{parentName:"ul"},"Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("strong",{parentName:"li"},"This does not mark an end to Cwtch development"),", or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.")))),(0,i.kt)("p",null,"This is not all we have planned for the upcoming months. Subscribe to our ",(0,i.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,i.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,i.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,i.kt)("h2",{id:"get-involved"},"Get Involved"),(0,i.kt)("p",null,"We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/developing"},"Developing Cwtch")," - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on."),(0,i.kt)("p",null,"We also also updated our guides on ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/translate"},"Translating Cwtch")," and ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/testing"},"Testing Cwtch"),"."),(0,i.kt)("p",null,"If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to ",(0,i.kt)("inlineCode",{parentName:"p"},"team@cwtch.im")," (or open an issue) with any questions. All types of contributions ",(0,i.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"are eligible for stickers"),"."),(0,i.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,i.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,i.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,i.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,i.kt)("p",null,"Donations of ",(0,i.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,i.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,i.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/af2ce9b1.6fa59457.js b/build-staging/it/assets/js/af2ce9b1.6fa59457.js new file mode 100644 index 00000000..50d810b2 --- /dev/null +++ b/build-staging/it/assets/js/af2ce9b1.6fa59457.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5391],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},y=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),p=l(n),y=o,h=p["".concat(c,".").concat(y)]||p[y]||d[y]||i;return n?r.createElement(h,s(s({ref:t},u),{},{components:n})):r.createElement(h,s({ref:t},u))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,s=new Array(i);s[0]=y;var a={};for(var c in t)hasOwnProperty.call(t,c)&&(a[c]=t[c]);a.originalType=e,a[p]="string"==typeof e?e:o,s[1]=a;for(var l=2;l<i;l++)s[l]=n[l];return r.createElement.apply(null,s)}return r.createElement.apply(null,n)}y.displayName="MDXCreateElement"},1574:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},s="Key Bundles",a={unversionedId:"components/cwtch/key_bundles",id:"components/cwtch/key_bundles",title:"Key Bundles",description:"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/key_bundles.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/key_bundles",permalink:"/it/security/components/cwtch/key_bundles",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Message Formats",permalink:"/it/security/components/cwtch/message_formats"},next:{title:"Groups",permalink:"/it/security/components/cwtch/groups"}},c={},l=[{value:"Verifying Key Bundles",id:"verifying-key-bundles",level:2}],u={toc:l},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"key-bundles"},"Key Bundles"),(0,o.kt)("p",null,"Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant."),(0,o.kt)("p",null,"At the time of writing, key bundles are expected to contain 3 keys:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"A Tor v3 Onion Service Public Key for the Token Board (ed25519)- used to connect to the service over Tor to post and receive messages."),(0,o.kt)("li",{parentName:"ol"},"A Tor v3 Onion Service Public Key for the Token Service (ed25519) - used to acquire tokens to post on the service via a small proof-of-work exercise."),(0,o.kt)("li",{parentName:"ol"},"A Privacy Pass Public Key - used in the token acquisition process (a ristretto curve point) . See: ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"OPTR2019-01"))),(0,o.kt)("p",null,"The key bundle is signed and can be verified via the first v3 onion service key, thus binding it to that particular oninon address."),(0,o.kt)("h2",{id:"verifying-key-bundles"},"Verifying Key Bundles"),(0,o.kt)("p",null,"Profiles who import server key bundles verify them using the following trust-on-first-use (TOFU) algorithm:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Verify the attached signature using the v3 onion address of the server. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"Check that every key type exists. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"If the profile has imported the server key bundle previously, assert that all the keys are the same. (If this fails, the import process is halted)"),(0,o.kt)("li",{parentName:"ol"},"Save the keys to the servers contact entry.")),(0,o.kt)("p",null,"In the future this algorithm will likely be altered to allow the addition of new public keys (e.g. to allow tokens to be acquired via a Zcash address.)"),(0,o.kt)("p",null,'Technically, at steps (2) and (3() the server can be assumed to be malicious, having signed a valid key bundle that does not conform to the specifications. When groups are moved from "experimental" to "stable" such an action will result in a warning being communicated to the profile.'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b0404c31.04c08dcd.js b/build-staging/it/assets/js/b0404c31.04c08dcd.js new file mode 100644 index 00000000..61bfdb08 --- /dev/null +++ b/build-staging/it/assets/js/b0404c31.04c08dcd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7860],{3905:(e,t,a)=>{a.d(t,{Zo:()=>h,kt:()=>m});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function r(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){o(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,o=function(e,t){if(null==e)return{};var a,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):r(r({},t),e)),a},h=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(a),u=o,m=p["".concat(s,".").concat(u)]||p[u]||d[u]||i;return a?n.createElement(m,r(r({ref:t},h),{},{components:a})):n.createElement(m,r({ref:t},h))}));function m(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=a.length,r=new Array(i);r[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:o,r[1]=l;for(var c=2;c<i;c++)r[c]=a[c];return n.createElement.apply(null,r)}return n.createElement.apply(null,a)}u.displayName="MDXCreateElement"},3478:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),o=(a(7294),a(3905));const i={title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/it/blog/path-to-cwtch-stable",source:"@site/blog/2023-01-06-path-to-cwtch-stable.md",title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",date:"2023-01-06T00:00:00.000Z",formattedDate:"6 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"}],readingTime:9.995,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Path to Cwtch Stable",description:"The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.",slug:"path-to-cwtch-stable",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable API Design",permalink:"/it/blog/cwtch-stable-api-design"}},s={authorsImageUrls:[void 0]},c=[{value:"Tenets of Cwtch Stable",id:"tenets-of-cwtch-stable",level:3},{value:"Known Problems",id:"known-problems",level:3},{value:"Plan of Action",id:"plan-of-action",level:3},{value:"Goals and Timelines",id:"goals-and-timelines",level:3},{value:"Help us get there!",id:"help-us-get-there",level:3}],h={toc:c},p="wrapper";function d(e){let{components:t,...i}=e;return(0,o.kt)(p,(0,n.Z)({},h,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"As of December 2022 we have released 10 versions of Cwtch Beta since the ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/10-cwtch-beta-and-beyond/"},"initial launch, 18 months ago, in June 2021"),"."),(0,o.kt)("p",null,"There is a consensus among the team that the next large step for the Cwtch project to take is a move from public ",(0,o.kt)("strong",{parentName:"p"},"Beta")," to ",(0,o.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable."),(0,o.kt)("p",null,"This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them."),(0,o.kt)("p",null,(0,o.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})),(0,o.kt)("h3",{id:"tenets-of-cwtch-stable"},"Tenets of Cwtch Stable"),(0,o.kt)("p",null,"It is important to state that Cwtch Stable ",(0,o.kt)("strong",{parentName:"p"},"does not mean an end to Cwtch development"),". Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Consistent Interface")," \u2013 each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Universal Availability and Cohesive Support")," \u2013 people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Reproducible Builds")," \u2013 Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Proven Security")," \u2013 we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.")),(0,o.kt)("h3",{id:"known-problems"},"Known Problems"),(0,o.kt)("p",null,"To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable."),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of a Stable API for future feature development")," \u2013 while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Special functionality in libCwtch-go")," \u2013 our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"libCwtch-rs partial support")," - we currently do not officially consider ",(0,o.kt)("a",{parentName:"li",href:"https://lib.rs/crates/libcwtch"},"libCwtch-rs")," when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Reproducible Pipelines")," - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of up to date, and translated, Security Documentation")," \u2013 the ",(0,o.kt)("a",{parentName:"li",href:"https://docs.openprivacy.ca/cwtch-security-handbook/"},"Cwtch security handbook")," is currently isolated from the rest of our documentation and doesn\u2019t benefit from cross-linking, or translations. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"No Automated UI Tests")," \u2013 we put a lot of work into ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/23-cucumber-testing/"},"building out a testing framework for the UI"),", but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Code Signing Provider")," \u2013 our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Second-class Android Support")," - while we have put ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/27-android-improvements/"},"a lot of effort behind Android support")," across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Fuzzing")," \u2013 while ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"Fuzzbot")," sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Lack of Formal Release Acceptance Process")," \u2013 currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to \u201cunrelated\u201d changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Inconsistent Cwtch Information Discovery")," \u2013 our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Incomplete Documentation")," \u2013 docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)")),(0,o.kt)("h3",{id:"plan-of-action"},"Plan of Action"),(0,o.kt)("p",null,"Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Interface Specification Documentation")," \u2013 this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Release Process")," \u2013 this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Support Document")," - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Cwtch Packaging Document")," - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define, Publish, and Implement a Reproducible Builds Document")," \u2013 this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand the Cwtch Documentation Site")," \u2013 to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Expand our Automated Testing to include UI and Fuzzing")," - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)"),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Re-evaluate all Issues across all Cwtch related repositories")," \u2013 issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don\u2019t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans."),(0,o.kt)("li",{parentName:"ol"},(0,o.kt)("strong",{parentName:"li"},"Define a Stable Feature Set")," \u2013 there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)")),(0,o.kt)("h3",{id:"goals-and-timelines"},"Goals and Timelines"),(0,o.kt)("p",null,"With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"1st February 2023"),", the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023"),", the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable)."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team."),(0,o.kt)("li",{parentName:"ol"},"By ",(0,o.kt)("strong",{parentName:"li"},"31st March 2023")," the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.")),(0,o.kt)("p",null,"As these documents are written, and these goals met we will be posting them here! Subscribe to our ",(0,o.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,o.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,o.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, Cwtch development."),(0,o.kt)("h3",{id:"help-us-get-there"},"Help us get there!"),(0,o.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,o.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,o.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position, please ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,o.kt)("p",null,"Donations of ",(0,o.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,o.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b11de5d5.978db84c.js b/build-staging/it/assets/js/b11de5d5.978db84c.js new file mode 100644 index 00000000..6d46686c --- /dev/null +++ b/build-staging/it/assets/js/b11de5d5.978db84c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3417],{1368:t=>{t.exports=JSON.parse('{"title":"Profili","slug":"/category/profiles","permalink":"/it/docs/category/profiles","navigation":{"previous":{"title":"Supported Platforms","permalink":"/it/docs/getting-started/supported_platforms"},"next":{"title":"Un\'introduzione ai profili di Cwtch","permalink":"/it/docs/profiles/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b125d866.05751358.js b/build-staging/it/assets/js/b125d866.05751358.js new file mode 100644 index 00000000..a5729d4b --- /dev/null +++ b/build-staging/it/assets/js/b125d866.05751358.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8799],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>m});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function c(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),p=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},s=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(a),d=n,m=h["".concat(l,".").concat(d)]||h[d]||u[d]||o;return a?r.createElement(m,i(i({ref:t},s),{},{components:a})):r.createElement(m,i({ref:t},s))}));function m(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=a[p];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}d.displayName="MDXCreateElement"},1595:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/it/blog/cwtch-stable-roadmap-update-june",source:"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",date:"2023-06-30T00:00:00.000Z",formattedDate:"30 giugno 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"}],readingTime:5.26,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals",slug:"cwtch-stable-roadmap-update-june",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},nextItem:{title:"Cwtch Beta 1.12",permalink:"/it/blog/cwtch-nightly-1-12"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/cwtch-stable-roadmap-update"},"revisits the Cwtch Stable roadmap update")," we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b29d9412.0ca2217e.js b/build-staging/it/assets/js/b29d9412.0ca2217e.js new file mode 100644 index 00000000..5ddad079 --- /dev/null +++ b/build-staging/it/assets/js/b29d9412.0ca2217e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8848],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var a=t(7294);function n(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);r&&(a=a.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){n(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function c(e,r){if(null==e)return{};var t,a,n=function(e,r){if(null==e)return{};var t,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)t=o[a],r.indexOf(t)>=0||(n[t]=e[t]);return n}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)t=o[a],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var s=a.createContext({}),l=function(e){var r=a.useContext(s),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=l(e.components);return a.createElement(s.Provider,{value:r},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var r=e.children;return a.createElement(a.Fragment,{},r)}},d=a.forwardRef((function(e,r){var t=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(t),d=n,m=u["".concat(s,".").concat(d)]||u[d]||f[d]||o;return t?a.createElement(m,i(i({ref:r},p),{},{components:t})):a.createElement(m,i({ref:r},p))}));function m(e,r){var t=arguments,n=r&&r.mdxType;if("string"==typeof e||n){var o=t.length,i=new Array(o);i[0]=d;var c={};for(var s in r)hasOwnProperty.call(r,s)&&(c[s]=r[s]);c.originalType=e,c[u]="string"==typeof e?e:n,i[1]=c;for(var l=2;l<o;l++)i[l]=t[l];return a.createElement.apply(null,i)}return a.createElement.apply(null,t)}d.displayName="MDXCreateElement"},509:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>s,contentTitle:()=>i,default:()=>f,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var a=t(7462),n=(t(7294),t(3905));const o={sidebar_position:3},i="Modificare la tua password",c={unversionedId:"profiles/change-password",id:"profiles/change-password",title:"Modificare la tua password",description:"1. Clicca sulla matita accanto al profilo che vuoi modificare",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/change-password.md",sourceDirName:"profiles",slug:"/profiles/change-password",permalink:"/it/docs/profiles/change-password",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-password.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Cambiare il tuo nome visualizzato",permalink:"/it/docs/profiles/change-name"},next:{title:"Modificare la tua immagine del profilo",permalink:"/it/docs/profiles/change-profile-image"}},s={},l=[],p={toc:l},u="wrapper";function f(e){let{components:r,...t}=e;return(0,n.kt)(u,(0,a.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"modificare-la-tua-password"},"Modificare la tua password"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Clicca sulla matita accanto al profilo che vuoi modificare"),(0,n.kt)("li",{parentName:"ol"},'Vai a "password corrente" e inseriscila'),(0,n.kt)("li",{parentName:"ol"},'Vai a "nuova password" e inserisci la tua nuova password'),(0,n.kt)("li",{parentName:"ol"},"Inserisci la nuova password una seconda volta"),(0,n.kt)("li",{parentName:"ol"},"Clicca su salva il profilo")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b2a64359.46032bc4.js b/build-staging/it/assets/js/b2a64359.46032bc4.js new file mode 100644 index 00000000..ab48989c --- /dev/null +++ b/build-staging/it/assets/js/b2a64359.46032bc4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1006],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),h=o,m=u["".concat(c,".").concat(h)]||u[h]||d[h]||i;return n?r.createElement(m,a(a({ref:t},l),{},{components:n})):r.createElement(m,a({ref:t},l))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,a[1]=s;for(var p=2;p<i;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},7470:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:3},a="Connectivity",s={unversionedId:"components/connectivity/intro",id:"components/connectivity/intro",title:"Connectivity",description:"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/connectivity/intro.md",sourceDirName:"components/connectivity",slug:"/components/connectivity/intro",permalink:"/it/security/components/connectivity/intro",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Connectivity & Tor",permalink:"/it/security/category/connectivity--tor"},next:{title:"Tapir",permalink:"/it/security/category/tapir"}},c={},p=[{value:"Known Risks",id:"known-risks",level:2},{value:"Private Key Exposure to the Tor Process",id:"private-key-exposure-to-the-tor-process",level:3},{value:"Mitigations",id:"mitigations",level:3},{value:"Tor Process Management",id:"tor-process-management",level:3},{value:"Testing Status",id:"testing-status",level:2}],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"connectivity"},"Connectivity"),(0,o.kt)("p",null,"Cwtch makes use of Tor Onion Services (v3) for all inter-node communication."),(0,o.kt)("p",null,"We provide the ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity")," package for managing the Tor daemon and setting up and tearing down onion services through Tor."),(0,o.kt)("h2",{id:"known-risks"},"Known Risks"),(0,o.kt)("h3",{id:"private-key-exposure-to-the-tor-process"},"Private Key Exposure to the Tor Process"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (Requires Physical Access or Privilege Escalation to exploit)"),(0,o.kt)("p",null,"We must pass the private key of any onion service we wish to set up to the connectivity library, through the ",(0,o.kt)("inlineCode",{parentName:"p"},"Listen")," interface (and thus to the Tor process). This is one of the most critical areas that is outside of our control. Any binding to a rouge tor process or binary will result in compromise of the Onion private key."),(0,o.kt)("h3",{id:"mitigations"},"Mitigations"),(0,o.kt)("p",null,"Connectivity attempt to bind to the system-provided Tor process as the default, ",(0,o.kt)("em",{parentName:"p"},"only")," when it has been provided with an authentication token."),(0,o.kt)("p",null,"Otherwise connectivity always attempts to deploy its own Tor process using a known good binary packaged with the system (outside of the scope of the connectivity package)"),(0,o.kt)("p",null,"In the long term we hope an integrated library will become available and allow direct management through an in-process interface to prevent the private key from leaving the process boundary (or other alternative paths that allow us to maintain full control over the private key in-memory.)"),(0,o.kt)("h3",{id:"tor-process-management"},"Tor Process Management"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (Requires Physical Access or Privilege Escalation to exploit)"),(0,o.kt)("p",null,"Many issues can arise from the management of a separate process, including the need to restart, exit and otherwise ensure appropriate management."),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/connectivity/src/branch/master/acn.go"},"ACN")," interface provides ",(0,o.kt)("inlineCode",{parentName:"p"},"Restart"),", ",(0,o.kt)("inlineCode",{parentName:"p"},"Close")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"GetBootstrapStatus")," interfaces to allow applications to manage the underlying Tor process. In addition the ",(0,o.kt)("inlineCode",{parentName:"p"},"SetStatusCallback")," method can be used to allow an application to be notified when the status of the Tor process changes."),(0,o.kt)("p",null,"However, if sufficiently-privileged users wish they can interfere with this mechanism, and as such the Tor process is a more brittle component interaction than others."),(0,o.kt)("h2",{id:"testing-status"},"Testing Status"),(0,o.kt)("p",null,"Current connectivity has limited unit testing capabilities and none of these are run during pull requests or merges. There is no integration testing."),(0,o.kt)("p",null,"It is worth noting that connectivity is used by both Tapir and Cwtch in their integration tests (and so despite the lack of package level testing, it is exposed to system-wide test conditions)"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b331d16d.6d1e6fa1.js b/build-staging/it/assets/js/b331d16d.6d1e6fa1.js new file mode 100644 index 00000000..6815a7e6 --- /dev/null +++ b/build-staging/it/assets/js/b331d16d.6d1e6fa1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8237],{1244:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/cwtch-stable/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":17,"previousPage":"/it/blog/tags/cwtch-stable","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b51a5363.a6ebdb13.js b/build-staging/it/assets/js/b51a5363.a6ebdb13.js new file mode 100644 index 00000000..3ae140a5 --- /dev/null +++ b/build-staging/it/assets/js/b51a5363.a6ebdb13.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1814],{6704:a=>{a.exports=JSON.parse('{"label":"cwtch","permalink":"/it/blog/tags/cwtch","allTagsPath":"/it/blog/tags","count":17}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b58c7628.8d84bd8d.js b/build-staging/it/assets/js/b58c7628.8d84bd8d.js new file mode 100644 index 00000000..602bcef0 --- /dev/null +++ b/build-staging/it/assets/js/b58c7628.8d84bd8d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8590],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>m});var n=t(7294);function a(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function i(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){a(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function c(e,r){if(null==e)return{};var t,n,a=function(e,r){if(null==e)return{};var t,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(a[t]=e[t]);return a}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=n.createContext({}),s=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):i(i({},r),e)),t},p=function(e){var r=s(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},v=n.forwardRef((function(e,r){var t=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(t),v=a,m=u["".concat(l,".").concat(v)]||u[v]||d[v]||o;return t?n.createElement(m,i(i({ref:r},p),{},{components:t})):n.createElement(m,i({ref:r},p))}));function m(e,r){var t=arguments,a=r&&r.mdxType;if("string"==typeof e||a){var o=t.length,i=new Array(o);i[0]=v;var c={};for(var l in r)hasOwnProperty.call(r,l)&&(c[l]=r[l]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var s=2;s<o;s++)i[s]=t[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,t)}v.displayName="MDXCreateElement"},74:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var n=t(7462),a=(t(7294),t(3905));const o={sidebar_position:4},i="Salvare la cronologia delle conversazioni",c={unversionedId:"chat/save-conversation-history",id:"chat/save-conversation-history",title:"Salvare la cronologia delle conversazioni",description:"Come impostazione predefinita, per la privacy, Cwtch non conserva la cronologia delle conversazioni tra diverse sessioni.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/save-conversation-history.md",sourceDirName:"chat",slug:"/chat/save-conversation-history",permalink:"/it/docs/chat/save-conversation-history",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/save-conversation-history.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Sharing Cwtch Addresses",permalink:"/it/docs/chat/share-address-with-friends"},next:{title:"Formattazione messaggio",permalink:"/it/docs/chat/message-formatting"}},l={},s=[],p={toc:s},u="wrapper";function d(e){let{components:r,...t}=e;return(0,a.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"salvare-la-cronologia-delle-conversazioni"},"Salvare la cronologia delle conversazioni"),(0,a.kt)("p",null,"Come impostazione predefinita, per la privacy, Cwtch non conserva la cronologia delle conversazioni tra diverse sessioni."),(0,a.kt)("p",null,"Per abilitare la cronologia per una specifica conversazione:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},'Nella finestra della conversazione vai su "Impostazioni"'),(0,a.kt)("li",{parentName:"ol"},'Vai a "Salva cronologia"'),(0,a.kt)("li",{parentName:"ol"},"Clicca sul menu a tendina"),(0,a.kt)("li",{parentName:"ol"},'Scegli "Salva cronologia"'),(0,a.kt)("li",{parentName:"ol"},"Ora la tua cronologia verr\xe0 salvata")),(0,a.kt)("p",null,'La cronologia della conversazione pu\xf2 essere disattivata in qualsiasi momento selezionando "Elimina cronologia" dal menu a discesa.'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b74cf248.76183dc6.js b/build-staging/it/assets/js/b74cf248.76183dc6.js new file mode 100644 index 00000000..c2133038 --- /dev/null +++ b/build-staging/it/assets/js/b74cf248.76183dc6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3319],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},s=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(n),m=o,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return n?r.createElement(f,a(a({ref:t},s),{},{components:n})):r.createElement(f,a({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,a=new Array(i);a[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},9798:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const i={sidebar_position:1},a="Un'introduzione alla chat p2p di Cwtch",c={unversionedId:"chat/introduction",id:"chat/introduction",title:"Un'introduzione alla chat p2p di Cwtch",description:"Cwtch utilizza i servizi onion di Tor v3 per stabilire connessioni anonime, peer-to-peer tra profili.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/introduction.md",sourceDirName:"chat",slug:"/chat/introduction",permalink:"/it/docs/chat/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Conversations",permalink:"/it/docs/category/conversations"},next:{title:"Starting a New Conversation",permalink:"/it/docs/chat/add-contact"}},l={},p=[{value:"Come funziona la chat p2p internamente",id:"come-funziona-la-chat-p2p-internamente",level:2}],s={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"unintroduzione-alla-chat-p2p-di-cwtch"},"Un'introduzione alla chat p2p di Cwtch"),(0,o.kt)("p",null,"Cwtch utilizza i servizi onion di Tor v3 per stabilire connessioni anonime, peer-to-peer tra profili."),(0,o.kt)("h2",{id:"come-funziona-la-chat-p2p-internamente"},"Come funziona la chat p2p internamente"),(0,o.kt)("p",null,"Per interagire con una persona tra i tuoi contatti in una conversazione peer-to-peer entrambi dovete essere online."),(0,o.kt)("p",null,"Dopo che la connessione ha successo, entrambe le parti sono coinvolte in un ",(0,o.kt)("strong",{parentName:"p"},"protocollo di autenticazione")," che:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Si assicura che ogni parte abbia accesso alla chiave privata associata alla propria identit\xe0 pubblica."),(0,o.kt)("li",{parentName:"ul"},"Genera una chiave di sessione effimera utilizzata per cifrare tutte le comunicazioni successive durante la sessione.")),(0,o.kt)("p",null,"Questo scambio (documentato in dettaglio nel ",(0,o.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/authentication_protocol.html"},"protocollo di autenticazione"),") \xe8 ",(0,o.kt)("em",{parentName:"p"},"negabile offline"),", ovvero \xe8 possibile per qualsiasi parte forgiare trascrizioni di questo protocollo di scambio a posteriori, e di conseguenza - a fatto avvenuto - \xe8 impossibile dimostrare definitivamente che lo scambio \xe8 avvenuto davvero."),(0,o.kt)("p",null,"Una volta che il processo di autenticazione \xe8 riuscito, potete comunicare con l'altra persona indisturbatamente, con la sicurezza che nessun altro pu\xf2 apprendere nulla sui contenuti o i metadati della conversazione."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b8ae7715.9962717d.js b/build-staging/it/assets/js/b8ae7715.9962717d.js new file mode 100644 index 00000000..c0a4f5ed --- /dev/null +++ b/build-staging/it/assets/js/b8ae7715.9962717d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8239],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=l(e.components);return n.createElement(c.Provider,{value:r},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},m=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=i,v=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=m;var s={};for(var c in r)hasOwnProperty.call(r,c)&&(s[c]=r[c]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var l=2;l<o;l++)a[l]=t[l];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}m.displayName="MDXCreateElement"},9889:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:2},a="Come creare un server",s={unversionedId:"servers/create-server",id:"servers/create-server",title:"Come creare un server",description:"Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/create-server.md",sourceDirName:"servers",slug:"/servers/create-server",permalink:"/it/docs/servers/create-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/create-server.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Introduzione ai server",permalink:"/it/docs/servers/introduction"},next:{title:"Come modificare un server",permalink:"/it/docs/servers/edit-server"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"come-creare-un-server"},"Come creare un server"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l' ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Esperimento di server hosting")," attivato."),(0,i.kt)("p",null,":::"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Vai all'icona del server"),(0,i.kt)("li",{parentName:"ol"},'Premi il pulsante di azione "',(0,i.kt)("inlineCode",{parentName:"li"},"+"),'" per creare un nuovo server'),(0,i.kt)("li",{parentName:"ol"},"Scegli un nome per il tuo server"),(0,i.kt)("li",{parentName:"ol"},"Seleziona una password per il tuo server"),(0,i.kt)("li",{parentName:"ol"},"Clicca su \u201cAggiungi server\u201d")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Server_New.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/b979d7e4.b414f5c1.js b/build-staging/it/assets/js/b979d7e4.b414f5c1.js new file mode 100644 index 00000000..24eccf4b --- /dev/null +++ b/build-staging/it/assets/js/b979d7e4.b414f5c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[360],{9266:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/support","page":1,"postsPerPage":10,"totalPages":1,"totalCount":3,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ba6ec3d2.25fb6655.js b/build-staging/it/assets/js/ba6ec3d2.25fb6655.js new file mode 100644 index 00000000..620a5254 --- /dev/null +++ b/build-staging/it/assets/js/ba6ec3d2.25fb6655.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9737],{9254:e=>{e.exports=JSON.parse('{"label":"reproducible-builds","permalink":"/it/blog/tags/reproducible-builds","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/bc51653d.e2e0d594.js b/build-staging/it/assets/js/bc51653d.e2e0d594.js new file mode 100644 index 00000000..49c8860b --- /dev/null +++ b/build-staging/it/assets/js/bc51653d.e2e0d594.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[818],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),d=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=d(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),p=d(r),h=a,f=p["".concat(c,".").concat(h)]||p[h]||u[h]||o;return r?n.createElement(f,i(i({ref:t},l),{},{components:r})):n.createElement(f,i({ref:t},l))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:a,i[1]=s;for(var d=2;d<o;d++)i[d]=r[d];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}h.displayName="MDXCreateElement"},592:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var n=r(7462),a=(r(7294),r(3905));const o={sidebar_position:3},i="Sharing Cwtch Addresses",s={unversionedId:"chat/share-address-with-friends",id:"chat/share-address-with-friends",title:"Sharing Cwtch Addresses",description:"There are many ways to share a Cwtch address.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/share-address-with-friends.md",sourceDirName:"chat",slug:"/chat/share-address-with-friends",permalink:"/it/docs/chat/share-address-with-friends",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/share-address-with-friends.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Accettare/Declinare nuove conversazioni",permalink:"/it/docs/chat/accept-deny-new-conversation"},next:{title:"Salvare la cronologia delle conversazioni",permalink:"/it/docs/chat/save-conversation-history"}},c={},d=[{value:"Sharing Your Cwtch Address",id:"sharing-your-cwtch-address",level:2}],l={toc:d},p="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"sharing-cwtch-addresses"},"Sharing Cwtch Addresses"),(0,a.kt)("p",null,"There are many ways to share a Cwtch address."),(0,a.kt)("h2",{id:"sharing-your-cwtch-address"},"Sharing Your Cwtch Address"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Vai al tuo profilo"),(0,a.kt)("li",{parentName:"ol"},"Fare clic sull'icona della copia indirizzo")),(0,a.kt)("p",null,"Ora \xe8 possibile condividere questo indirizzo. Le persone con questo indirizzo saranno in grado di aggiungerti come un contatto Cwtch."),(0,a.kt)("p",null,"Per informazioni su come bloccare connessioni da persone che non conosci vedi ",(0,a.kt)("a",{parentName:"p",href:"/docs/settings/behaviour/block-unknown-connections"},"Impostazioni: Blocca connessioni sconosciute")),(0,a.kt)("h1",{id:"sharing-a-friends-cwtch-address"},"Sharing A Friends Cwtch Address"),(0,a.kt)("p",null,"Inside of Cwtch there is another mechanism for exchanging Cwtch addresses."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,a.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/bf059cf9.2818d042.js b/build-staging/it/assets/js/bf059cf9.2818d042.js new file mode 100644 index 00000000..725d4b34 --- /dev/null +++ b/build-staging/it/assets/js/bf059cf9.2818d042.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5273],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>b});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,i,n=function(e,t){if(null==e)return{};var r,i,n={},a=Object.keys(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)r=a[i],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=i.createContext({}),s=function(e){var t=i.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=s(e.components);return i.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},g=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=s(r),g=n,b=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return r?i.createElement(b,o(o({ref:t},p),{},{components:r})):i.createElement(b,o({ref:t},p))}));function b(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,o=new Array(a);o[0]=g;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[d]="string"==typeof e?e:n,o[1]=c;for(var s=2;s<a;s++)o[s]=r[s];return i.createElement.apply(null,o)}return i.createElement.apply(null,r)}g.displayName="MDXCreateElement"},2626:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var i=r(7462),n=(r(7294),r(3905));const a={title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/it/blog/cwtch-android-reproducibility",source:"@site/blog/2023-02-10-android-reproducibility.md",title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",date:"2023-02-10T00:00:00.000Z",formattedDate:"10 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"reproducible-builds",permalink:"/it/blog/tags/reproducible-builds"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"repliqate",permalink:"/it/blog/tags/repliqate"}],readingTime:2.92,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Making Cwtch Android Bindings Reproducible",description:"In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible",slug:"cwtch-android-reproducibility",tags:["cwtch","cwtch-stable","reproducible-builds","bindings","repliqate"],image:"/img/devlog6_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing (II)",permalink:"/it/blog/cwtch-testing-ii"},nextItem:{title:"Notes on Cwtch UI Testing",permalink:"/it/blog/cwtch-testing-i"}},l={authorsImageUrls:[void 0]},s=[],p={toc:s},d="wrapper";function u(e){let{components:t,...a}=e;return(0,n.kt)(d,(0,i.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"In this development log, we continue our previous work on ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings"),", uncovering the final few sources of variation between our ",(0,n.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/openprivacy/repliqate"},"Repliqate")," scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!"),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(4756).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},4756:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/devlog6-047cb55e43376529b3899ac2a0792f9c.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c14f15fd.05646011.js b/build-staging/it/assets/js/c14f15fd.05646011.js new file mode 100644 index 00000000..abb2b93f --- /dev/null +++ b/build-staging/it/assets/js/c14f15fd.05646011.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7649],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),h=a,f=u["".concat(s,".").concat(h)]||u[h]||d[h]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},3071:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(7462),a=(n(7294),n(3905));const o={sidebar_position:2},i="Core Concepts",c={unversionedId:"building-a-cwtch-app/core-concepts",id:"building-a-cwtch-app/core-concepts",title:"Core Concepts",description:"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.",source:"@site/developing/building-a-cwtch-app/core-concepts.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/core-concepts",permalink:"/it/developing/building-a-cwtch-app/core-concepts",draft:!1,tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Getting Started",permalink:"/it/developing/building-a-cwtch-app/intro"},next:{title:"Building a Cwtch Echobot",permalink:"/it/developing/building-a-cwtch-app/building-an-echobot"}},s={},l=[{value:"Cwtch Home Directory",id:"cwtch-home-directory",level:2},{value:"Profiles",id:"profiles",level:2},{value:"The Event Bus",id:"the-event-bus",level:2},{value:"Settings",id:"settings",level:2},{value:"Experiments",id:"experiments",level:3}],p={toc:l},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"core-concepts"},"Core Concepts"),(0,a.kt)("p",null,"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently."),(0,a.kt)("h2",{id:"cwtch-home-directory"},"Cwtch Home Directory"),(0,a.kt)("p",null,"Often referred to as ",(0,a.kt)("inlineCode",{parentName:"p"},"$CWTCH_HOME"),", the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application."),(0,a.kt)("h2",{id:"profiles"},"Profiles"),(0,a.kt)("p",null,"Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations."),(0,a.kt)("h2",{id:"the-event-bus"},"The Event Bus"),(0,a.kt)("p",null,"Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. ",(0,a.kt)("inlineCode",{parentName:"p"},"NewMessageFromPeer")," and setup an event handler to run code in response to such a message."),(0,a.kt)("p",null,"For an example see the Echo Bot tutorial."),(0,a.kt)("h2",{id:"settings"},"Settings"),(0,a.kt)("p",null,"Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration."),(0,a.kt)("h3",{id:"experiments"},"Experiments"),(0,a.kt)("p",null,"Certain Cwtch features are ",(0,a.kt)("a",{parentName:"p",href:"/docs/category/experiments"},"gated behind experiments"),". These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c3b86ae0.8788091c.js b/build-staging/it/assets/js/c3b86ae0.8788091c.js new file mode 100644 index 00000000..f4f88adc --- /dev/null +++ b/build-staging/it/assets/js/c3b86ae0.8788091c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3007],{6464:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/autobindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c4f5d8e4.ea3b76f3.js b/build-staging/it/assets/js/c4f5d8e4.ea3b76f3.js new file mode 100644 index 00000000..a46a88c5 --- /dev/null +++ b/build-staging/it/assets/js/c4f5d8e4.ea3b76f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4195],{3261:(e,t,n)=>{n.r(t),n.d(t,{default:()=>m});var a=n(7294),l=n(6010),r=n(7961),o=n(9960),s=n(2263);const c={heroBanner:"heroBanner_qdFl",buttons:"buttons_AeoN",button:"button_JGCe"};var i=n(5999);const u=[{id:1,title:a.createElement(i.Z,null,"The Cwtch Handbook")},{id:2,title:a.createElement(i.Z,null,"Your Guide to setting up, and using, Surveillance Resistant Infrastructure")},{id:3,title:a.createElement(i.Z,null,"Get Started With Cwtch")}];function h(){const{siteConfig:e}=(0,s.Z)();return a.createElement("header",{className:(0,l.Z)("hero hero--primary",c.heroBanner)},a.createElement("div",{className:"container"},a.createElement("h1",{className:"hero__title"},u[0].title),a.createElement("p",{className:"hero__subtitle"},u[1].title),a.createElement("div",{className:c.buttons},a.createElement(o.Z,{className:"button button--secondary button--lg",to:"/docs/intro"},u[2].title))))}function m(){const{siteConfig:e}=(0,s.Z)();return a.createElement(r.Z,{title:`${e.title}`,description:"The Cwtch Handbook"},a.createElement(h,null),a.createElement("main",null))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c50453d6.bf72966c.js b/build-staging/it/assets/js/c50453d6.bf72966c.js new file mode 100644 index 00000000..80bd0f71 --- /dev/null +++ b/build-staging/it/assets/js/c50453d6.bf72966c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9284],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),u=s(r),f=o,m=u["".concat(p,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(m,i(i({ref:t},l),{},{components:r})):n.createElement(m,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c[u]="string"==typeof e?e:o,i[1]=c;for(var s=2;s<a;s++)i[s]=r[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},4991:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:1},i="Packet Format",c={unversionedId:"components/tapir/packet_format",id:"components/tapir/packet_format",title:"Packet Format",description:"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, len bytes of data, and the rest zero padded:",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/tapir/packet_format.md",sourceDirName:"components/tapir",slug:"/components/tapir/packet_format",permalink:"/it/security/components/tapir/packet_format",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Tapir",permalink:"/it/security/category/tapir"},next:{title:"Authentication Protocol",permalink:"/it/security/components/tapir/authentication_protocol"}},p={},s=[],l={toc:s},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"packet-format"},"Packet Format"),(0,o.kt)("p",null,"All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, ",(0,o.kt)("inlineCode",{parentName:"p"},"len")," bytes of data, and the rest zero padded:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|\n")),(0,o.kt)("p",null,"Once encrypted, the entire 8192 byte data packet is encrypted using ",(0,o.kt)("a",{parentName:"p",href:"https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox"},"libsodium secretbox")," using the standard structure ( note in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)"),(0,o.kt)("p",null,"For information on how the secret key is derived see the ",(0,o.kt)("a",{parentName:"p",href:"/it/security/components/tapir/authentication_protocol"},"authentication protocol")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c5a58ca1.a0b86038.js b/build-staging/it/assets/js/c5a58ca1.a0b86038.js new file mode 100644 index 00000000..912a30cd --- /dev/null +++ b/build-staging/it/assets/js/c5a58ca1.a0b86038.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5194],{9825:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/bindings","page":1,"postsPerPage":10,"totalPages":1,"totalCount":4,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c747432f.a76bb1c0.js b/build-staging/it/assets/js/c747432f.a76bb1c0.js new file mode 100644 index 00000000..d3542217 --- /dev/null +++ b/build-staging/it/assets/js/c747432f.a76bb1c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8835],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>d});var i=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function r(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,i,a=function(e,t){if(null==e)return{};var n,i,a={},o=Object.keys(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)n=o[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=i.createContext({}),p=function(e){var t=i.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},s=function(e){var t=p(e.components);return i.createElement(c.Provider,{value:t},e.children)},m="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},u=i.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=p(n),u=a,d=m["".concat(c,".").concat(u)]||m[u]||g[u]||o;return n?i.createElement(d,r(r({ref:t},s),{},{components:n})):i.createElement(d,r({ref:t},s))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=u;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[m]="string"==typeof e?e:a,r[1]=l;for(var p=2;p<o;p++)r[p]=n[p];return i.createElement.apply(null,r)}return i.createElement.apply(null,n)}u.displayName="MDXCreateElement"},2090:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>g,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var i=n(7462),a=(n(7294),n(3905));const o={title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},r=void 0,l={permalink:"/it/blog/autobindings-ii",source:"@site/blog/2023-03-03-autobindings-optional-experiments.md",title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",date:"2023-03-03T00:00:00.000Z",formattedDate:"3 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"bindings",permalink:"/it/blog/tags/bindings"},{label:"autobindings",permalink:"/it/blog/tags/autobindings"},{label:"libcwtch",permalink:"/it/blog/tags/libcwtch"}],readingTime:4.655,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Compile-time Optional Application Experiments (Autobindings)",description:"In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.",slug:"autobindings-ii",tags:["cwtch","cwtch-stable","bindings","autobindings","libcwtch"],image:"/img/devlog8_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Updates to Cwtch Documentation",permalink:"/it/blog/cwtch-documentation"},nextItem:{title:"Autogenerating Cwtch Bindings",permalink:"/it/blog/autobindings"}},c={authorsImageUrls:[void 0]},p=[],s={toc:p},m="wrapper";function g(e){let{components:t,...o}=e;return(0,a.kt)(m,(0,i.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"Last time we looked at autobindings")," we mentioned that one of the next steps was introducing support for ",(0,a.kt)("strong",{parentName:"p"},(0,a.kt)("a",{parentName:"strong",href:"https://docs.cwtch.im/blog/cwtch-stable-api-design#application-experiments"},"Application-level experiments")),". In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them."),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(7200).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},7200:(e,t,n)=>{n.d(t,{Z:()=>i});const i=n.p+"assets/images/devlog8-97ac031095f463e4b5172ac973677415.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c94c4dfb.5e3bcaf2.js b/build-staging/it/assets/js/c94c4dfb.5e3bcaf2.js new file mode 100644 index 00000000..2d748b75 --- /dev/null +++ b/build-staging/it/assets/js/c94c4dfb.5e3bcaf2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9146],{4469:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c96c5262.48df994f.js b/build-staging/it/assets/js/c96c5262.48df994f.js new file mode 100644 index 00000000..fa61941d --- /dev/null +++ b/build-staging/it/assets/js/c96c5262.48df994f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3761],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>u});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?i(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},i=Object.keys(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)a=i[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var s=n.createContext({}),c=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=c(a),h=r,u=m["".concat(s,".").concat(h)]||m[h]||d[h]||i;return a?n.createElement(u,o(o({ref:t},p),{},{components:a})):n.createElement(u,o({ref:t},p))}));function u(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,o=new Array(i);o[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:r,o[1]=l;for(var c=2;c<i;c++)o[c]=a[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}h.displayName="MDXCreateElement"},5426:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const i={title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,l={permalink:"/it/blog/cwtch-nightly-1-11",source:"@site/blog/2023-03-29-cwtch-1.11.md",title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",date:"2023-03-29T00:00:00.000Z",formattedDate:"29 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"release",permalink:"/it/blog/tags/release"}],readingTime:2.365,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Beta 1.11",description:"Cwtch Beta 1.11 is now available for download",slug:"cwtch-nightly-1-11",tags:["cwtch","cwtch-stable","release"],image:"/img/devlog12_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Stable Roadmap Update",permalink:"/it/blog/cwtch-stable-roadmap-update"},nextItem:{title:"Updates to Cwtch Documentation",permalink:"/it/blog/cwtch-documentation"}},s={authorsImageUrls:[void 0]},c=[{value:"In This Release",id:"in-this-release",level:2},{value:"Reproducible Bindings",id:"reproducible-bindings",level:2},{value:"Download the New Version",id:"download-the-new-version",level:2},{value:"Help us go further!",id:"help-us-go-further",level:2}],p={toc:c},m="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(m,(0,n.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"Cwtch 1.11 is now available for download"),"!"),(0,r.kt)("p",null,"Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for ",(0,r.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"Cwtch Stable")," including new ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")," bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes."),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(6094).Z,width:"1005",height:"481"})),(0,r.kt)("h2",{id:"in-this-release"},"In This Release"),(0,r.kt)("figure",null,(0,r.kt)("p",null,(0,r.kt)("a",{target:"_blank",href:a(5595).Z},(0,r.kt)("img",{src:a(9573).Z,width:"1341",height:"866"}))),(0,r.kt)("figcaption",null,"A screenshot of Cwtch 1.11")),(0,r.kt)("p",null,"A special thanks to the ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/translate"},"amazing volunteer translators")," and ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing"},"testers")," who made this release possible."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"New Features:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Based on new Reproducible Cwtch Stable Autobuilds")," - this is the first release of cwtch based on ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible"},"reproducible Cwtch bindings")," in addition to our new ",(0,r.kt)("a",{parentName:"li",href:"https://docs.cwtch.im/blog/autobindings"},"automatically generated")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Two New Supported Localizations"),": ",(0,r.kt)("strong",{parentName:"li"},"Slovak")," and ",(0,r.kt)("strong",{parentName:"li"},"Korean")))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Bug Fixes / Improvements:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"When preserving a message draft, quoted messages are now also saved"),(0,r.kt)("li",{parentName:"ul"},"Layout issues caused by pathological unicode are now prevented"),(0,r.kt)("li",{parentName:"ul"},"Improved performance of message row rendering"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Links in replies are now selectable"),(0,r.kt)("li",{parentName:"ul"},"Clickable Links: Fixed error when highlighting certain URIs "),(0,r.kt)("li",{parentName:"ul"},"File Downloading: Fixes for file downloading and exporting on 32bit Android devices"),(0,r.kt)("li",{parentName:"ul"},"Server Hosting: Fixes for several layout issues"),(0,r.kt)("li",{parentName:"ul"},"Build pipeline now runs automated UI tests"),(0,r.kt)("li",{parentName:"ul"},"Fix issues caused by scrollbar controller overriding"),(0,r.kt)("li",{parentName:"ul"},"Initial support for the Blodeuwedd Assistant (currently compile-time disabled)"),(0,r.kt)("li",{parentName:"ul"},"Cwtch Library:",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"/blog/cwtch-stable-api-design"},"New Stable Cwtch Peer API")),(0,r.kt)("li",{parentName:"ul"},"Ported File Downloading and Image Previews experiments into Cwtch"))))),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Accessibility / UX:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Full translations for ",(0,r.kt)("strong",{parentName:"li"},"Brazilian Portuguese"),", ",(0,r.kt)("strong",{parentName:"li"},"Dutch"),", ",(0,r.kt)("strong",{parentName:"li"},"French"),", ",(0,r.kt)("strong",{parentName:"li"},"German"),", ",(0,r.kt)("strong",{parentName:"li"},"Italian"),", ",(0,r.kt)("strong",{parentName:"li"},"Russian"),", ",(0,r.kt)("strong",{parentName:"li"},"Polish"),", ",(0,r.kt)("strong",{parentName:"li"},"Spanish"),", ",(0,r.kt)("strong",{parentName:"li"},"Turkish"),", and ",(0,r.kt)("strong",{parentName:"li"},"Welsh")),(0,r.kt)("li",{parentName:"ul"},"Core translations for ",(0,r.kt)("strong",{parentName:"li"},"Danish")," (75%), ",(0,r.kt)("strong",{parentName:"li"},"Norwegian")," (76%), and ",(0,r.kt)("strong",{parentName:"li"},"Romanian")," (75%)"),(0,r.kt)("li",{parentName:"ul"},"Partial translations for ",(0,r.kt)("strong",{parentName:"li"},"Luxembourgish")," (22%), ",(0,r.kt)("strong",{parentName:"li"},"Greek")," (16%), and ",(0,r.kt)("strong",{parentName:"li"},"Portuguese")," (6%)")))),(0,r.kt)("h2",{id:"reproducible-bindings"},"Reproducible Bindings"),(0,r.kt)("p",null,"Cwtch 1.11 is based on libCwtch version ",(0,r.kt)("inlineCode",{parentName:"p"},"2023-03-16-15-07-v0.0.3-1-g50c853a"),". The ",(0,r.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/cwtch-bindings-reproducible#introducing-repliqate"},"repliqate scripts")," to reproduce these bindings from source can be found at ",(0,r.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a"},"https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a")),(0,r.kt)("h2",{id:"download-the-new-version"},"Download the New Version"),(0,r.kt)("p",null,"You can download Cwtch from ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/download"},"https://cwtch.im/download"),"."),(0,r.kt)("p",null,"Subscribe to our ",(0,r.kt)("a",{parentName:"p",href:"/blog/rss.xml"},"RSS feed"),", ",(0,r.kt)("a",{parentName:"p",href:"/blog/atom.xml"},"Atom feed"),", or ",(0,r.kt)("a",{parentName:"p",href:"/blog/feed.json"},"JSON feed")," to stay up to date, and get the latest on, all aspects of Cwtch development."),(0,r.kt)("p",null,"Alternatively we also provide a ",(0,r.kt)("a",{parentName:"p",href:"https://cwtch.im/releases/index.xml"},"releases-only RSS feed"),"."),(0,r.kt)("h2",{id:"help-us-go-further"},"Help us go further!"),(0,r.kt)("p",null,"We couldn't do what we do without all the wonderful community support we get, from ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," to ",(0,r.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,r.kt)("p",null,"If you want to see us move faster on some of these goals and are in a position to, please ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"donate"),". If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer."),(0,r.kt)("p",null,"Donations of ",(0,r.kt)("strong",{parentName:"p"},"$5 or more")," can opt to receive stickers as a thank-you gift!"),(0,r.kt)("p",null,"For more information about donating to Open Privacy and claiming a thank you gift ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate/"},"please visit the Open Privacy Donate page"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"A Photo of Cwtch Stickers",src:a(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},5595:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/files/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},6094:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/devlog12-313b28c3f6bcc28a7df69b0f09ffa4f6.png"},9573:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/picnic-96d07251e7d3691f4f5bd88eecb87e77.png"},4515:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/c9f9ad20.c11c18c5.js b/build-staging/it/assets/js/c9f9ad20.c11c18c5.js new file mode 100644 index 00000000..39f727f3 --- /dev/null +++ b/build-staging/it/assets/js/c9f9ad20.c11c18c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5540],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=l(r),m=o,f=u["".concat(c,".").concat(m)]||u[m]||d[m]||a;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var l=2;l<a;l++)i[l]=r[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8522:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a={sidebar_position:5},i="Rispondere a un messaggio",s={unversionedId:"chat/reply-to-message",id:"chat/reply-to-message",title:"Rispondere a un messaggio",description:"1. Seleziona un messaggio a cui desideri rispondere",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/reply-to-message.md",sourceDirName:"chat",slug:"/chat/reply-to-message",permalink:"/it/docs/chat/reply-to-message",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/reply-to-message.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Accessing Conversation Settings",permalink:"/it/docs/chat/conversation-settings"},next:{title:"Condividere un file",permalink:"/it/docs/chat/share-file"}},c={},l=[],p={toc:l},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"rispondere-a-un-messaggio"},"Rispondere a un messaggio"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Seleziona un messaggio a cui desideri rispondere"),(0,o.kt)("li",{parentName:"ol"},"Trascinalo a destra"),(0,o.kt)("li",{parentName:"ol"},"Scrivi una risposta al messaggio ora citato"),(0,o.kt)("li",{parentName:"ol"},'Clicca su "Invio"')))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/cbb0e45e.4f1fe907.js b/build-staging/it/assets/js/cbb0e45e.4f1fe907.js new file mode 100644 index 00000000..833c0c99 --- /dev/null +++ b/build-staging/it/assets/js/cbb0e45e.4f1fe907.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8789],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),f=l(n),m=i,d=f["".concat(c,".").concat(m)]||f[m]||u[m]||o;return n?r.createElement(d,a(a({ref:t},p),{},{components:n})):r.createElement(d,a({ref:t},p))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,a=new Array(o);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[f]="string"==typeof e?e:i,a[1]=s;for(var l=2;l<o;l++)a[l]=n[l];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3017:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:3},a="Condivisione file",s={unversionedId:"settings/experiments/file-sharing",id:"settings/experiments/file-sharing",title:"Condivisione file",description:'These setting enables Cwtch filesharing functionality. This reveals the "Share File" option in the conversation pane, and allows you to download files from conversations.',source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/file-sharing.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/file-sharing",permalink:"/it/docs/settings/experiments/file-sharing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/file-sharing.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Hosting di un server",permalink:"/it/docs/settings/experiments/server-hosting"},next:{title:"Anteprime immagine e immagini del profilo",permalink:"/it/docs/settings/experiments/image-previews-and-profile-pictures"}},c={},l=[],p={toc:l},f="wrapper";function u(e){let{components:t,...n}=e;return(0,i.kt)(f,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"condivisione-file"},"Condivisione file"),(0,i.kt)("p",null,"These setting enables Cwtch ",(0,i.kt)("a",{parentName:"p",href:"/docs/chat/share-file"},"filesharing functionality"),'. This reveals the "Share File" option in the conversation pane, and allows you to download files from conversations.'),(0,i.kt)("p",null,"Optionally, you can enable ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Image Previews and Profile Pictures")," to download image files automatically, view image previews in the conversation window, and enable the ",(0,i.kt)("a",{parentName:"p",href:"/docs/profiles/change-profile-image"},"Profile Pictures")," feature;"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ccc49370.a9ca1f91.js b/build-staging/it/assets/js/ccc49370.a9ca1f91.js new file mode 100644 index 00000000..455c51ff --- /dev/null +++ b/build-staging/it/assets/js/ccc49370.a9ca1f91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6103],{5203:(e,t,n)=>{n.r(t),n.d(t,{default:()=>h});var a=n(7294),l=n(6010),o=n(1944),r=n(5281),i=n(9460),c=n(9058),s=n(390),m=n(7462),d=n(5999),u=n(2244);function g(e){const{nextItem:t,prevItem:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,d.I)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"})},n&&a.createElement(u.Z,(0,m.Z)({},n,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post"},"Newer Post")})),t&&a.createElement(u.Z,(0,m.Z)({},t,{subLabel:a.createElement(d.Z,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post"},"Older Post"),isNext:!0})))}function f(){const{assets:e,metadata:t}=(0,i.C)(),{title:n,description:l,date:r,tags:c,authors:s,frontMatter:m}=t,{keywords:d}=m,u=e.image??m.image;return a.createElement(o.d,{title:n,description:l,keywords:d,image:u},a.createElement("meta",{property:"og:type",content:"article"}),a.createElement("meta",{property:"article:published_time",content:r}),s.some((e=>e.url))&&a.createElement("meta",{property:"article:author",content:s.map((e=>e.url)).filter(Boolean).join(",")}),c.length>0&&a.createElement("meta",{property:"article:tag",content:c.map((e=>e.label)).join(",")}))}var v=n(9407);function p(e){let{sidebar:t,children:n}=e;const{metadata:l,toc:o}=(0,i.C)(),{nextItem:r,prevItem:m,frontMatter:d}=l,{hide_table_of_contents:u,toc_min_heading_level:f,toc_max_heading_level:p}=d;return a.createElement(c.Z,{sidebar:t,toc:!u&&o.length>0?a.createElement(v.Z,{toc:o,minHeadingLevel:f,maxHeadingLevel:p}):void 0},a.createElement(s.Z,null,n),(r||m)&&a.createElement(g,{nextItem:r,prevItem:m}))}function h(e){const t=e.content;return a.createElement(i.n,{content:e.content,isBlogPostPage:!0},a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.blogPages,r.k.page.blogPostPage)},a.createElement(f,null),a.createElement(p,{sidebar:e.sidebar},a.createElement(t,null))))}},9407:(e,t,n)=>{n.d(t,{Z:()=>m});var a=n(7462),l=n(7294),o=n(6010),r=n(3743);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},c="table-of-contents__link toc-highlight",s="table-of-contents__link--active";function m(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,o.Z)(i.tableOfContents,"thin-scrollbar",t)},l.createElement(r.Z,(0,a.Z)({},n,{linkClassName:c,linkActiveClassName:s})))}},3743:(e,t,n)=>{n.d(t,{Z:()=>f});var a=n(7462),l=n(7294),o=n(6668);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function s(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(c(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function m(){const e=(0,l.useRef)(0),{navbar:{hideOnScroll:t}}=(0,o.L)();return(0,l.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,l.useRef)(void 0),n=m();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:o,maxHeadingLevel:r}=e;function i(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),i=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:r}),c=s(i,{anchorTopOffset:n.current}),m=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===m)}))}return document.addEventListener("scroll",i),document.addEventListener("resize",i),i(),()=>{document.removeEventListener("scroll",i),document.removeEventListener("resize",i)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?l.createElement("ul",{className:o?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const g=l.memo(u);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:s,minHeadingLevel:m,maxHeadingLevel:u,...f}=e;const v=(0,o.L)(),p=m??v.tableOfContents.minHeadingLevel,h=u??v.tableOfContents.maxHeadingLevel,b=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:p,maxHeadingLevel:h});return d((0,l.useMemo)((()=>{if(c&&s)return{linkClassName:c,linkActiveClassName:s,minHeadingLevel:p,maxHeadingLevel:h}}),[c,s,p,h])),l.createElement(g,(0,a.Z)({toc:b,className:n,linkClassName:c},f))}}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/d1fa313c.f05028e7.js b/build-staging/it/assets/js/d1fa313c.f05028e7.js new file mode 100644 index 00000000..bd561aea --- /dev/null +++ b/build-staging/it/assets/js/d1fa313c.f05028e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9427],{3905:(e,t,i)=>{i.d(t,{Zo:()=>u,kt:()=>b});var n=i(7294);function r(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function a(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function o(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?a(Object(i),!0).forEach((function(t){r(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):a(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function l(e,t){if(null==e)return{};var i,n,r=function(e,t){if(null==e)return{};var i,n,r={},a=Object.keys(e);for(n=0;n<a.length;n++)i=a[n],t.indexOf(i)>=0||(r[i]=e[i]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)i=a[n],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(r[i]=e[i])}return r}var c=n.createContext({}),s=function(e){var t=n.useContext(c),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},u=function(e){var t=s(e.components);return n.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var i=e.components,r=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=s(i),m=r,b=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return i?n.createElement(b,o(o({ref:t},u),{},{components:i})):n.createElement(b,o({ref:t},u))}));function b(e,t){var i=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=i.length,o=new Array(a);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:r,o[1]=l;for(var s=2;s<a;s++)o[s]=i[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,i)}m.displayName="MDXCreateElement"},8676:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>s});var n=i(7462),r=(i(7294),i(3905));const a={sidebar_position:1},o="Testare Cwtch",l={unversionedId:"contribute/testing",id:"contribute/testing",title:"Testare Cwtch",description:"Questa sezione documenta alcuni modi per iniziare a testare Cwtch.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/testing.md",sourceDirName:"contribute",slug:"/contribute/testing",permalink:"/it/docs/contribute/testing",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/testing.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Developing Cwtch",permalink:"/it/docs/contribute/developing"},next:{title:"Translating Cwtch",permalink:"/it/docs/contribute/translate"}},c={},s=[{value:"Far girare Fuzzbot",id:"far-girare-fuzzbot",level:3},{value:"Unisciti al gruppo dei tester delle versioni di Cwtch candidate alla pubblicazione ufficiale",id:"unisciti-al-gruppo-dei-tester-delle-versioni-di-cwtch-candidate-alla-pubblicazione-ufficiale",level:3},{value:"Cwtch Nightlies",id:"cwtch-nightlies",level:3},{value:"Submitting Feedback",id:"submitting-feedback",level:3}],u={toc:s},p="wrapper";function d(e){let{components:t,...i}=e;return(0,r.kt)(p,(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"testare-cwtch"},"Testare Cwtch"),(0,r.kt)("p",null,"Questa sezione documenta alcuni modi per iniziare a testare Cwtch."),(0,r.kt)("h3",{id:"far-girare-fuzzbot"},"Far girare Fuzzbot"),(0,r.kt)("p",null,"FuzzBot \xe8 il nostro bot di test di sviluppo. Puoi aggiungere FuzzBot come contatto: ",(0,r.kt)("inlineCode",{parentName:"p"},"cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad"),"."),(0,r.kt)("p",null,":::Info Aiuto FuzzBot"),(0,r.kt)("p",null,"L'invio a FuzzBot del messaggio ",(0,r.kt)("inlineCode",{parentName:"p"},"aiuto")," lo attiver\xe0 ad inviare una risposta con tutti i comandi di test attualmente disponibili."),(0,r.kt)("p",null,":::"),(0,r.kt)("p",null,"Per maggiori informazioni su FuzzBot consulta il nostro ",(0,r.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/07-fuzzbot/"},"blog sullo sviluppo Discreet Log"),"."),(0,r.kt)("h3",{id:"unisciti-al-gruppo-dei-tester-delle-versioni-di-cwtch-candidate-alla-pubblicazione-ufficiale"},"Unisciti al gruppo dei tester delle versioni di Cwtch candidate alla pubblicazione ufficiale"),(0,r.kt)("p",null,"L'invio a Fuzzbot del comando ",(0,r.kt)("inlineCode",{parentName:"p"},"testgroup-invite")," far\xe0 s\xec che FuzzBot ti inviti al ",(0,r.kt)("strong",{parentName:"p"},"gruppo di tester di Cwtch"),"! L\xec puoi fare domande, inviare segnalazioni di bug e offrire feedback."),(0,r.kt)("h3",{id:"cwtch-nightlies"},"Cwtch Nightlies"),(0,r.kt)("p",null,"Cwtch Nightly build sono build di sviluppo che contengono nuove funzionalit\xe0 che sono pronte per essere testate."),(0,r.kt)("p",null,"Le versioni di sviluppo pi\xf9 recenti di Cwtch sono disponibili dal nostro ",(0,r.kt)("a",{parentName:"p",href:"https://build.openprivacy.ca/files/"},"build server"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Non")," raccomandiamo che i tester si tengano sempre aggiornati con l'ultimo nightly build. Invece, pubblicheremo un messaggio sul gruppo Tester di versioni di Cwtch candidate al rilascio quando sar\xe0 disponibile un nightly build significativa. Un nightly build \xe8 considerato significativo se contiene una nuova funzione o un fix a un bug serio."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"All contributions are ",(0,r.kt)("a",{parentName:"p",href:"/docs/contribute/stickers"},"eligible for stickers"))),(0,r.kt)("h3",{id:"submitting-feedback"},"Submitting Feedback"),(0,r.kt)("p",null,"There are three main ways of submitting testing feedback to the team:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Via Cwtch: Either via the Release Candidate Testers Group or directly to a Cwtch team member."),(0,r.kt)("li",{parentName:"ul"},"Via Gitea: Please open an issue in ",(0,r.kt)("a",{parentName:"li",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues"},"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues")," - please do not worry about duplicate issues, we will de-duplicate as part of our triage process."),(0,r.kt)("li",{parentName:"ul"},"Via Email: Email ",(0,r.kt)("inlineCode",{parentName:"li"},"team@cwtch.im")," with the bug report and one of our team will look into it.")),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/d228e678.59d2d9e1.js b/build-staging/it/assets/js/d228e678.59d2d9e1.js new file mode 100644 index 00000000..c6d341ee --- /dev/null +++ b/build-staging/it/assets/js/d228e678.59d2d9e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9798],{5353:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/developer-documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/d5f314f9.1dc05f26.js b/build-staging/it/assets/js/d5f314f9.1dc05f26.js new file mode 100644 index 00000000..02f13a12 --- /dev/null +++ b/build-staging/it/assets/js/d5f314f9.1dc05f26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5869],{9317:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"docs-developer"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/d634637f.1a735df4.js b/build-staging/it/assets/js/d634637f.1a735df4.js new file mode 100644 index 00000000..b826e847 --- /dev/null +++ b/build-staging/it/assets/js/d634637f.1a735df4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7241],{1248:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/documentation","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/d78ab406.8962f566.js b/build-staging/it/assets/js/d78ab406.8962f566.js new file mode 100644 index 00000000..495b7dcd --- /dev/null +++ b/build-staging/it/assets/js/d78ab406.8962f566.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9506],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),l=p(r),m=i,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||o;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[l]="string"==typeof e?e:i,a[1]=s;for(var p=2;p<o;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8978:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:1},a="Introduzione ai server",s={unversionedId:"servers/introduction",id:"servers/introduction",title:"Introduzione ai server",description:"Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/introduction.md",sourceDirName:"servers",slug:"/servers/introduction",permalink:"/it/docs/servers/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Servers",permalink:"/it/docs/category/servers"},next:{title:"Come creare un server",permalink:"/it/docs/servers/create-server"}},c={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...r}=e;return(0,i.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"introduzione-ai-server"},"Introduzione ai server"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l' ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Esperimento di server hosting")," attivato."),(0,i.kt)("p",null,":::"),(0,i.kt)("p",null,"La chat Cwtch da contatto a contatto \xe8 completamente peer to peer, il che significa se un peer \xe8 offline, non si pu\xf2 chattare, e non c'\xe8 alcun meccanismo per chat tra pi\xf9 persone."),(0,i.kt)("p",null,'Per supportare la chat di gruppo (e il recapito offline) abbiamo creato server Cwtch non affidabili che possono ospitare messaggi per un gruppo. I messaggi sono cifrati con la chiave di gruppo e recuperati tramite servizi "onion" effimeri, in modo che il server non ha modo di sapere di quali messaggi per quali gruppi potrebbe essere in possesso, o chi sta accedendo.'),(0,i.kt)("p",null,"Attualmente fare girare dei server nell'app di Cwtch \xe8 supportato solo nella versione Desktop in quanto i dispositivi di telefonia mobile hanno connessione internet e configurazione troppo instabili o inadatte ad ospitare un server."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/dabb1858.b567202d.js b/build-staging/it/assets/js/dabb1858.b567202d.js new file mode 100644 index 00000000..f54853bd --- /dev/null +++ b/build-staging/it/assets/js/dabb1858.b567202d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[877],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=l(n),h=o,f=p["".concat(c,".").concat(h)]||p[h]||u[h]||a;return n?r.createElement(f,i(i({ref:t},d),{},{components:n})):r.createElement(f,i({ref:t},d))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l<a;l++)i[l]=n[l];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}h.displayName="MDXCreateElement"},3639:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={},i="Android Service",s={unversionedId:"components/ui/android",id:"components/ui/android",title:"Android Service",description:"Adapted from Integrating FFI processes with Android services",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/android.md",sourceDirName:"components/ui",slug:"/components/ui/android",permalink:"/it/security/components/ui/android",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Cwtch UI",permalink:"/it/security/category/cwtch-ui"},next:{title:"Image Previews",permalink:"/it/security/components/ui/image_previews"}},c={},l=[],d={toc:l},p="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"android-service"},"Android Service"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/11-android-ffi-service-integration/"},"Adapted from: Discreet Log #11: Integrating FFI processes with Android services")),(0,o.kt)("p",null,"In addition to needing to make plain ol\u2019 method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isn\u2019t really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service."),(0,o.kt)("p",null,"The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, it\u2019s not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service."),(0,o.kt)("p",null,"If you\u2019d like to follow along, our WorkManager specifications are created in the handleCwtch() method of ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/MainActivity.kt"},"MainActivity.kt"),", and the workers themselves are defined in ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/android/app/src/main/kotlin/im/cwtch/flwtch/FlwtchWorker.kt"},"FlwtchWorker.kt"),"."),(0,o.kt)("p",null,"Our plain ol\u2019 method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback."),(0,o.kt)("p",null,"One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, it\u2019s easy for it to yield and resume as necessary while waiting for events to be generated. Cwtch\u2019s goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately."),(0,o.kt)("p",null,"FlwtchWorker\u2019s eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isn\u2019t running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontend\u2019s Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary."),(0,o.kt)("p",null,"Messages and other permanent state are stored on disk by the service, so the frontend doesn\u2019t need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state."),(0,o.kt)("p",null,"Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isn\u2019t the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},'private fun getNativeLibDir(): String {\n val ainfo = this.applicationContext.packageManager.getApplicationInfo(\n "im.cwtch.flwtch", // Must be app name\n PackageManager.GET_SHARED_LIBRARY_FILES)\n return ainfo.nativeLibraryDir\n}\n')),(0,o.kt)("p",null,"\u2026then, whenever the app is launched, we cancel any jobs that aren\u2019t tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ddf22f37.5e3032eb.js b/build-staging/it/assets/js/ddf22f37.5e3032eb.js new file mode 100644 index 00000000..f3b9e92c --- /dev/null +++ b/build-staging/it/assets/js/ddf22f37.5e3032eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1155],{3905:(t,e,n)=>{n.d(e,{Zo:()=>s,kt:()=>p});var r=n(7294);function i(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function o(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function a(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?o(Object(n),!0).forEach((function(e){i(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function c(t,e){if(null==t)return{};var n,r,i=function(t,e){if(null==t)return{};var n,r,i={},o=Object.keys(t);for(r=0;r<o.length;r++)n=o[r],e.indexOf(n)>=0||(i[n]=t[n]);return i}(t,e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(t);for(r=0;r<o.length;r++)n=o[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(i[n]=t[n])}return i}var M=r.createContext({}),u=function(t){var e=r.useContext(M),n=e;return t&&(n="function"==typeof t?t(e):a(a({},e),t)),n},s=function(t){var e=u(t.components);return r.createElement(M.Provider,{value:e},t.children)},L="mdxType",w={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},l=r.forwardRef((function(t,e){var n=t.components,i=t.mdxType,o=t.originalType,M=t.parentName,s=c(t,["components","mdxType","originalType","parentName"]),L=u(n),l=i,p=L["".concat(M,".").concat(l)]||L[l]||w[l]||o;return n?r.createElement(p,a(a({ref:e},s),{},{components:n})):r.createElement(p,a({ref:e},s))}));function p(t,e){var n=arguments,i=e&&e.mdxType;if("string"==typeof t||i){var o=n.length,a=new Array(o);a[0]=l;var c={};for(var M in e)hasOwnProperty.call(e,M)&&(c[M]=e[M]);c.originalType=t,c[L]="string"==typeof t?t:i,a[1]=c;for(var u=2;u<o;u++)a[u]=n[u];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}l.displayName="MDXCreateElement"},2732:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>M,contentTitle:()=>a,default:()=>w,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var r=n(7462),i=(n(7294),n(3905));const o={sidebar_position:10},a="Removing a Conversation",c={unversionedId:"chat/delete-contact",id:"chat/delete-contact",title:"Removing a Conversation",description:"This feature will result in irreversible deletion. This cannot be undone.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/delete-contact.md",sourceDirName:"chat",slug:"/chat/delete-contact",permalink:"/it/docs/chat/delete-contact",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/delete-contact.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Sbloccare un contatto",permalink:"/it/docs/chat/unblock-contact"},next:{title:"Groups",permalink:"/it/docs/category/groups"}},M={},u=[],s={toc:u},L="wrapper";function w(t){let{components:e,...o}=t;return(0,i.kt)(L,(0,r.Z)({},s,o,{components:e,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"removing-a-conversation"},"Removing a Conversation"),(0,i.kt)("admonition",{type:"warning"},(0,i.kt)("p",{parentName:"admonition"},"This feature will result in ",(0,i.kt)("strong",{parentName:"p"},"irreversible")," deletion. This ",(0,i.kt)("strong",{parentName:"p"},"cannot be undone"),".")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"In a chat with a contact, go to the conversation settings on the top right ",(0,i.kt)("span",{class:"icon"},(0,i.kt)("img",{src:n(5905).Z,width:"24",height:"24"}))),(0,i.kt)("li",{parentName:"ul"},"Scroll to the ",(0,i.kt)("strong",{parentName:"li"},"leave this conversation")," button, and press it."),(0,i.kt)("li",{parentName:"ul"},"You will be prompted to confirm if you want to leave the conversation. This action cannot be undone.")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,i.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}w.isMDXComponent=!0},5905:(t,e,n)=>{n.d(e,{Z:()=>r});const r="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyNS4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjQgMjQ7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJLnN0MHtmaWxsOm5vbmU7fQ0KPC9zdHlsZT4NCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0wLDBoMjR2MjRIMFYweiIvPg0KPGc+DQoJPHBhdGggZD0iTTEzLjYsMTMuOGMtMS0wLjItMi0wLjMtMi44LTAuM2MtMi43LDAtOCwxLjMtOCw0djJoOS44Yy0wLjMtMC42LTAuNC0xLjMtMC40LTIuMUMxMi4yLDE1LjksMTIuNywxNC43LDEzLjYsMTMuOHoiLz4NCgk8Y2lyY2xlIGN4PSIxMC44IiBjeT0iNy40IiByPSI0Ii8+DQo8L2c+DQo8cGF0aCBkPSJNMjEuMSwxNy45YzAtMC4xLDAtMC4zLDAtMC40YzAtMC4yLDAtMC4zLDAtMC40bDEtMC43YzAuMS0wLjEsMC4xLTAuMiwwLjEtMC4zbC0wLjktMS42Yy0wLjEtMC4xLTAuMi0wLjEtMC4zLTAuMWwtMS4xLDAuNQ0KCWMtMC4yLTAuMi0wLjUtMC4zLTAuOC0wLjRsLTAuMi0xLjJjMC0wLjEtMC4xLTAuMi0wLjItMC4yaC0xLjhjLTAuMSwwLTAuMiwwLjEtMC4yLDAuMmwtMC4yLDEuMmMtMC4zLDAuMS0wLjUsMC4zLTAuOCwwLjRsLTEuMS0wLjUNCgljLTAuMSwwLTAuMiwwLTAuMywwLjFMMTMuNCwxNmMtMC4xLDAuMSwwLDAuMiwwLjEsMC4zbDEsMC43YzAsMC4xLDAsMC4zLDAsMC40YzAsMC4xLDAsMC4zLDAsMC40bC0xLDAuN2MtMC4xLDAuMS0wLjEsMC4yLTAuMSwwLjMNCglsMC45LDEuNmMwLjEsMC4xLDAuMiwwLjEsMC4zLDAuMWwxLjEtMC41YzAuMiwwLjIsMC41LDAuMywwLjgsMC40bDAuMiwxLjJjMCwwLjEsMC4xLDAuMiwwLjIsMC4yaDEuOGMwLjEsMCwwLjItMC4xLDAuMi0wLjINCglsMC4yLTEuMmMwLjMtMC4xLDAuNS0wLjMsMC44LTAuNGwxLjEsMC41YzAuMSwwLDAuMiwwLDAuMy0wLjFsMC45LTEuNmMwLjEtMC4xLDAtMC4yLTAuMS0wLjNMMjEuMSwxNy45eiBNMTcuNywxOS4yDQoJYy0wLjksMC0xLjctMC44LTEuNy0xLjdjMC0wLjksMC44LTEuNywxLjctMS43YzAuOSwwLDEuNywwLjgsMS43LDEuN0MxOS40LDE4LjQsMTguNywxOS4yLDE3LjcsMTkuMnoiLz4NCjwvc3ZnPg0K"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/dfb11b4d.cca8a468.js b/build-staging/it/assets/js/dfb11b4d.cca8a468.js new file mode 100644 index 00000000..e5a07af2 --- /dev/null +++ b/build-staging/it/assets/js/dfb11b4d.cca8a468.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7430],{8729:a=>{a.exports=JSON.parse('{"label":"nightly","permalink":"/it/blog/tags/nightly","allTagsPath":"/it/blog/tags","count":1}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/e2032214.c3c30dff.js b/build-staging/it/assets/js/e2032214.c3c30dff.js new file mode 100644 index 00000000..2f659943 --- /dev/null +++ b/build-staging/it/assets/js/e2032214.c3c30dff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2411],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=s(n),f=o,m=u["".concat(l,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(m,c(c({ref:t},p),{},{components:n})):r.createElement(m,c({ref:t},p))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,c=new Array(a);c[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,c[1]=i;for(var s=2;s<a;s++)c[s]=n[s];return r.createElement.apply(null,c)}return r.createElement.apply(null,n)}f.displayName="MDXCreateElement"},7332:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={sidebar_position:2},c="Accettare/Declinare nuove conversazioni",i={unversionedId:"chat/accept-deny-new-conversation",id:"chat/accept-deny-new-conversation",title:"Accettare/Declinare nuove conversazioni",description:"1. Vai al tuo profilo",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/accept-deny-new-conversation.md",sourceDirName:"chat",slug:"/chat/accept-deny-new-conversation",permalink:"/it/docs/chat/accept-deny-new-conversation",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/accept-deny-new-conversation.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Starting a New Conversation",permalink:"/it/docs/chat/add-contact"},next:{title:"Sharing Cwtch Addresses",permalink:"/it/docs/chat/share-address-with-friends"}},l={},s=[],p={toc:s},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"accettaredeclinare-nuove-conversazioni"},"Accettare/Declinare nuove conversazioni"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Vai al tuo profilo"),(0,o.kt)("li",{parentName:"ol"},"Se qualcuno ti ha aggiunto, un nuovo nome apparir\xe0 assieme a due opzioni",(0,o.kt)("ol",{parentName:"li"},(0,o.kt)("li",{parentName:"ol"},"Clicca sull'icona del cuore per accettare questo nuovo contatto"),(0,o.kt)("li",{parentName:"ol"},"Clicca sull'icona del cestino per bloccare il contatto")))),(0,o.kt)("p",null,"Vedi anche: ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/behaviour/block-unknown-connections"},"Impostazione: Blocca contatti sconosciuti")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/e31178cb.4e22fdc9.js b/build-staging/it/assets/js/e31178cb.4e22fdc9.js new file mode 100644 index 00000000..035ab422 --- /dev/null +++ b/build-staging/it/assets/js/e31178cb.4e22fdc9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9661],{3905:(e,t,i)=>{i.d(t,{Zo:()=>s,kt:()=>d});var r=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function a(e){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?o(Object(i),!0).forEach((function(t){n(e,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(i)):o(Object(i)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(i,t))}))}return e}function l(e,t){if(null==e)return{};var i,r,n=function(e,t){if(null==e)return{};var i,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)i=o[r],t.indexOf(i)>=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)i=o[r],t.indexOf(i)>=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var c=r.createContext({}),p=function(e){var t=r.useContext(c),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},s=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),f=p(i),m=n,d=f["".concat(c,".").concat(m)]||f[m]||u[m]||o;return i?r.createElement(d,a(a({ref:t},s),{},{components:i})):r.createElement(d,a({ref:t},s))}));function d(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=i.length,a=new Array(o);a[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[f]="string"==typeof e?e:n,a[1]=l;for(var p=2;p<o;p++)a[p]=i[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,i)}m.displayName="MDXCreateElement"},4933:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var r=i(7462),n=(i(7294),i(3905));const o={sidebar_position:4},a="Modificare la tua immagine del profilo",l={unversionedId:"profiles/change-profile-image",id:"profiles/change-profile-image",title:"Modificare la tua immagine del profilo",description:"Questa funzione richiede Esperimenti abilitati e sia Condivisione file sia Anteprime immagine e immagini dei profili attivate.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/change-profile-image.md",sourceDirName:"profiles",slug:"/profiles/change-profile-image",permalink:"/it/docs/profiles/change-profile-image",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-profile-image.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Modificare la tua password",permalink:"/it/docs/profiles/change-password"},next:{title:"Sbloccare profili crittografati",permalink:"/it/docs/profiles/unlock-profile"}},c={},p=[],s={toc:p},f="wrapper";function u(e){let{components:t,...i}=e;return(0,n.kt)(f,(0,r.Z)({},s,i,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"modificare-la-tua-immagine-del-profilo"},"Modificare la tua immagine del profilo"),(0,n.kt)("p",null,":::attenzione"),(0,n.kt)("p",null,"Questa funzione richiede ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e sia ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/file-sharing"},"Condivisione file")," sia ",(0,n.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-pictures"},"Anteprime immagine e immagini dei profili")," attivate."),(0,n.kt)("p",null,":::"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Clicca sulla matita accanto al profilo che vuoi modificare"),(0,n.kt)("li",{parentName:"ol"},"Clicca sulla matita rosa sopra la foto del tuo profilo"),(0,n.kt)("li",{parentName:"ol"},"Seleziona un'immagine dal tuo dispositivo"),(0,n.kt)("li",{parentName:"ol"},"Scorri verso il basso e clicca sul salva profilo")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/e759f958.17eb6149.js b/build-staging/it/assets/js/e759f958.17eb6149.js new file mode 100644 index 00000000..181111ac --- /dev/null +++ b/build-staging/it/assets/js/e759f958.17eb6149.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1384],{3905:(e,r,t)=>{t.d(r,{Zo:()=>p,kt:()=>v});var n=t(7294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=n.createContext({}),c=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},p=function(e){var r=c(e.components);return n.createElement(l.Provider,{value:r},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},d=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(t),d=i,v=u["".concat(l,".").concat(d)]||u[d]||m[d]||o;return t?n.createElement(v,a(a({ref:r},p),{},{components:t})):n.createElement(v,a({ref:r},p))}));function v(e,r){var t=arguments,i=r&&r.mdxType;if("string"==typeof e||i){var o=t.length,a=new Array(o);a[0]=d;var s={};for(var l in r)hasOwnProperty.call(r,l)&&(s[l]=r[l]);s.originalType=e,s[u]="string"==typeof e?e:i,a[1]=s;for(var c=2;c<o;c++)a[c]=t[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,t)}d.displayName="MDXCreateElement"},3962:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=t(7462),i=(t(7294),t(3905));const o={sidebar_position:4},a="Come eliminare un server",s={unversionedId:"servers/delete-server",id:"servers/delete-server",title:"Come eliminare un server",description:"Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/delete-server.md",sourceDirName:"servers",slug:"/servers/delete-server",permalink:"/it/docs/servers/delete-server",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/servers/delete-server.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Come modificare un server",permalink:"/it/docs/servers/edit-server"},next:{title:"Come condividere il tuo pacchetto di chiavi del server",permalink:"/it/docs/servers/share-key"}},l={},c=[],p={toc:c},u="wrapper";function m(e){let{components:r,...t}=e;return(0,i.kt)(u,(0,n.Z)({},p,t,{components:r,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"come-eliminare-un-server"},"Come eliminare un server"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l' ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/server-hosting"},"Esperimento di server hosting")," attivato."),(0,i.kt)("p",null,":::"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Vai all'icona del server"),(0,i.kt)("li",{parentName:"ol"},"Seleziona il server che vuoi eliminare"),(0,i.kt)("li",{parentName:"ol"},"Clicca sull'icona della matita"),(0,i.kt)("li",{parentName:"ol"},"Scorri verso il basso e inserisci la tua password"),(0,i.kt)("li",{parentName:"ol"},"Clicca su elimina"),(0,i.kt)("li",{parentName:"ol"},"Clicca su elimina definitivamente"),(0,i.kt)("li",{parentName:"ol"},"Il tuo server \xe8 stato eliminato")),(0,i.kt)("div",{width:"400"},(0,i.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,i.kt)("source",{src:"/video/Server_Delete.mp4"}))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/e83cebc7.0d3d23db.js b/build-staging/it/assets/js/e83cebc7.0d3d23db.js new file mode 100644 index 00000000..d1d5be32 --- /dev/null +++ b/build-staging/it/assets/js/e83cebc7.0d3d23db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[7541],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),s=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=s(e.components);return o.createElement(l.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),p=s(n),m=r,d=p["".concat(l,".").concat(m)]||p[m]||f[m]||i;return n?o.createElement(d,a(a({ref:t},u),{},{components:n})):o.createElement(d,a({ref:t},u))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,a=new Array(i);a[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[p]="string"==typeof e?e:r,a[1]=c;for(var s=2;s<i;s++)a[s]=n[s];return o.createElement.apply(null,a)}return o.createElement.apply(null,n)}m.displayName="MDXCreateElement"},1407:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:3},a="Contenuto notifica",c={unversionedId:"settings/behaviour/notification-content",id:"settings/behaviour/notification-content",title:"Contenuto notifica",description:"1. Vai alle impostazioni",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/behaviour/notification-content.md",sourceDirName:"settings/behaviour",slug:"/settings/behaviour/notification-content",permalink:"/it/docs/settings/behaviour/notification-content",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/behaviour/notification-content.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Policy di notifica",permalink:"/it/docs/settings/behaviour/notification-policy"},next:{title:"Experiments",permalink:"/it/docs/category/experiments"}},l={},s=[],u={toc:s},p="wrapper";function f(e){let{components:t,...n}=e;return(0,r.kt)(p,(0,o.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"contenuto-notifica"},"Contenuto notifica"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Vai alle impostazioni"),(0,r.kt)("li",{parentName:"ol"},'Scorri fino a "comportamento"'),(0,r.kt)("li",{parentName:"ol"},"Il contenuto notifica controlla il contenuto delle notifiche",(0,r.kt)("ol",{parentName:"li"},(0,r.kt)("li",{parentName:"ol"},'Evento semplice: solo "Nuovo messaggio"'),(0,r.kt)("li",{parentName:"ol"},'Informazioni sulla conversazione: "Nuovo messaggio da XXXXX"')))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/e88d32a9.ff20b8ba.js b/build-staging/it/assets/js/e88d32a9.ff20b8ba.js new file mode 100644 index 00000000..e319e33e --- /dev/null +++ b/build-staging/it/assets/js/e88d32a9.ff20b8ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[6585],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ecbb35df.f50bac3d.js b/build-staging/it/assets/js/ecbb35df.f50bac3d.js new file mode 100644 index 00000000..78dcb767 --- /dev/null +++ b/build-staging/it/assets/js/ecbb35df.f50bac3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2469],{9012:s=>{s.exports=JSON.parse('{"label":"support","permalink":"/it/blog/tags/support","allTagsPath":"/it/blog/tags","count":3}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ef02fbbd.0acf98a3.js b/build-staging/it/assets/js/ef02fbbd.0acf98a3.js new file mode 100644 index 00000000..cbf1d508 --- /dev/null +++ b/build-staging/it/assets/js/ef02fbbd.0acf98a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9565],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,u=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),l=c(r),m=o,f=l["".concat(u,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},s),{},{components:r})):n.createElement(f,a({ref:t},s))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var p={};for(var u in t)hasOwnProperty.call(t,u)&&(p[u]=t[u]);p.originalType=e,p[l]="string"==typeof e?e:o,a[1]=p;for(var c=2;c<i;c++)a[c]=r[c];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1772:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>p,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:3},a="Creare un nuovo gruppo",p={unversionedId:"groups/create-group",id:"groups/create-group",title:"Creare un nuovo gruppo",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/create-group.md",sourceDirName:"groups",slug:"/groups/create-group",permalink:"/it/docs/groups/create-group",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/create-group.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Un'introduzione ai gruppi di Cwtch",permalink:"/it/docs/groups/introduction"},next:{title:"Inviare inviti a un gruppo",permalink:"/it/docs/groups/send-invite"}},u={},c=[],s={toc:c},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"creare-un-nuovo-gruppo"},"Creare un nuovo gruppo"),(0,o.kt)("p",null,":::attenzione Esperimenti necessari"),(0,o.kt)("p",null,"Questa funzione richiede ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,o.kt)("p",null,":::"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Nel pannello dei tuoi contatti"),(0,o.kt)("li",{parentName:"ol"},'Clicca sul pulsante di azione "',(0,o.kt)("inlineCode",{parentName:"li"},"+"),'"'),(0,o.kt)("li",{parentName:"ol"},'Clicca su "Crea gruppo"'),(0,o.kt)("li",{parentName:"ol"},"Dai un nome al tuo gruppo"),(0,o.kt)("li",{parentName:"ol"},'Clicca su "Crea"')),(0,o.kt)("div",{width:"400"},(0,o.kt)("video",{playsInline:!0,autoPlay:!0,muted:!0,loop:!0,width:"400"},(0,o.kt)("source",{src:"/video/Group_Create.mp4"}))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ef6f692b.fa621589.js b/build-staging/it/assets/js/ef6f692b.fa621589.js new file mode 100644 index 00000000..479841a5 --- /dev/null +++ b/build-staging/it/assets/js/ef6f692b.fa621589.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1950],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>y});var i=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,i,o=function(e,t){if(null==e)return{};var n,i,o={},r=Object.keys(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i<r.length;i++)n=r[i],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=i.createContext({}),l=function(e){var t=i.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p=function(e){var t=l(e.components);return i.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},h=i.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=l(n),h=o,y=u["".concat(s,".").concat(h)]||u[h]||m[h]||r;return n?i.createElement(y,a(a({ref:t},p),{},{components:n})):i.createElement(y,a({ref:t},p))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,a=new Array(r);a[0]=h;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var l=2;l<r;l++)a[l]=n[l];return i.createElement.apply(null,a)}return i.createElement.apply(null,n)}h.displayName="MDXCreateElement"},618:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var i=n(7462),o=(n(7294),n(3905));const r={sidebar_position:1.5},a="Component Ecosystem Overview",c={unversionedId:"components/ecosystem-overview",id:"components/ecosystem-overview",title:"Component Ecosystem Overview",description:"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ecosystem-overview.md",sourceDirName:"components",slug:"/components/ecosystem-overview",permalink:"/it/security/components/ecosystem-overview",draft:!1,tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Cwtch Technical Basics",permalink:"/it/security/components/intro"},next:{title:"Connectivity & Tor",permalink:"/it/security/category/connectivity--tor"}},s={},l=[{value:"openprivacy/connectivity",id:"openprivacyconnectivity",level:2},{value:"cwtch.im/tapir",id:"cwtchimtapir",level:2},{value:"cwtch.im/cwtch",id:"cwtchimcwtch",level:2},{value:"cwtch.im/libcwtch-go",id:"cwtchimlibcwtch-go",level:2},{value:"cwtch-ui",id:"cwtch-ui",level:2},{value:"Auxiliary Components",id:"auxiliary-components",level:2},{value:"openprivacy/log",id:"openprivacylog",level:3}],p={toc:l},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,i.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"component-ecosystem-overview"},"Component Ecosystem Overview"),(0,o.kt)("p",null,"Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem."),(0,o.kt)("h2",{id:"openprivacyconnectivity"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/openprivacy/connectivity"},"openprivacy/connectivity")),(0,o.kt)("p",null,"Summary: A library providing an ACN (Anonymous Communication Network ) networking abstraction."),(0,o.kt)("p",null,"The goal of connectivity is to abstract away the underlying libraries/software needed to communicate with a specific ACN. Right now we only support Tor and so the job of connectivity is to:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Start and Stop the Tor Process"),(0,o.kt)("li",{parentName:"ul"},"Provide configuration to the Tor process"),(0,o.kt)("li",{parentName:"ul"},"Allow raw connections to endpoints via the Tor process (e.g. connect to onion services)"),(0,o.kt)("li",{parentName:"ul"},"Host endpoints via the Tor process (e.g. host onion services)"),(0,o.kt)("li",{parentName:"ul"},"Provide status updates about the underlying Tor process")),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/connectivity/intro"},"connectivity")),(0,o.kt)("h2",{id:"cwtchimtapir"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/tapir"},"cwtch.im/tapir")),(0,o.kt)("p",null,"Summary: Tapir is a small library for building p2p applications over anonymous communication systems."),(0,o.kt)("p",null,"The goal of tapir is to abstract away ",(0,o.kt)("strong",{parentName:"p"},"applications")," over a particular ACN. Tapir supports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Creating a cryptographic identity (including ephemeral identities)"),(0,o.kt)("li",{parentName:"ul"},"Maintaining a connection pool of inbound and outbound connections to services"),(0,o.kt)("li",{parentName:"ul"},"Handling various application-layers including cryptographic transcripts, ",(0,o.kt)("a",{parentName:"li",href:"/security/components/tapir/authentication_protocol"},"authentication and authorization protocols"),", and ",(0,o.kt)("a",{parentName:"li",href:"https://openprivacy.ca/research/OPTR2019-01/"},"token-based services via PrivacyPass"),",")),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/components/tapir/authentication_protocol"},"tapir")),(0,o.kt)("h2",{id:"cwtchimcwtch"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch"},"cwtch.im/cwtch")),(0,o.kt)("p",null,"Summary: Cwtch is the main library for implementing the Cwtch protocol / system."),(0,o.kt)("p",null,"The goal of Cwtch is to provide implementations for cwtch-specific applications e.g. message sending, groups, and file sharing(implemented as Tapir applications), provide interfaces for managing and storing Cwtch profiles, provide an event bus for subsystem splutting and building plugins with new functionality, in addition to managing other core functionality."),(0,o.kt)("p",null,"The Cwtch library is also responsible for maintaining canonical model representations for wire formats and overlays."),(0,o.kt)("h2",{id:"cwtchimlibcwtch-go"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/libcwtch-go"},"cwtch.im/libcwtch-go")),(0,o.kt)("p",null,"Summary: libcwtch-go provides C (including Android) bindings for Cwtch for use in UI implementations."),(0,o.kt)("p",null,"The goal of libcwtch-go is to bridge the gap between the backend Cwtch library and any front end systems which may be written in a different language."),(0,o.kt)("p",null,"The API provided by libcwtch is much more restricted than the one provided by Cwtch directly, each libcwtch API typically packages up several calls to Cwtch."),(0,o.kt)("p",null,"libcwtch-go is also responsible for managing UI settings and experimental gating. It is also often used as a staging ground for experimental features and code that may eventually end up in Cwtch."),(0,o.kt)("h2",{id:"cwtch-ui"},(0,o.kt)("a",{parentName:"h2",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui"},"cwtch-ui")),(0,o.kt)("p",null,"Summary: A flutter based UI for Cwtch."),(0,o.kt)("p",null,"Cwtch UI uses libcwtch-go to provide a complete UI for Cwtch, allowing people to create and manage profiles, add contacts and groups, message people, share files (coming soon) and more."),(0,o.kt)("p",null,"The UI is also responsible for managing localization and translations."),(0,o.kt)("p",null,"For more information see ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"Cwtch UI")),(0,o.kt)("h2",{id:"auxiliary-components"},"Auxiliary Components"),(0,o.kt)("p",null,"Occasionally, Open Privacy will factor out parts of Cwtch into standalone libraries that are not Cwtch specific. These are briefly summarized here:"),(0,o.kt)("h3",{id:"openprivacylog"},(0,o.kt)("a",{parentName:"h3",href:"https://git.openprivacy.ca/openprivacy/log"},"openprivacy/log")),(0,o.kt)("p",null,"An Open Privacy specific logging framework that is used throughout Cwtch packages."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ef71f686.ec798b10.js b/build-staging/it/assets/js/ef71f686.ec798b10.js new file mode 100644 index 00000000..0b265c9c --- /dev/null +++ b/build-staging/it/assets/js/ef71f686.ec798b10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2481],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(r),m=o,h=u["".concat(l,".").concat(m)]||u[m]||d[m]||i;return r?n.createElement(h,s(s({ref:t},p),{},{components:r})):n.createElement(h,s({ref:t},p))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,s=new Array(i);s[0]=m;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:o,s[1]=a;for(var c=2;c<i;c++)s[c]=r[c];return n.createElement.apply(null,s)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},299:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var n=r(7462),o=(r(7294),r(3905));const i={},s="Development",a={unversionedId:"development",id:"development",title:"Development",description:"The main process to counter malicious actors in development of Cwtch is the openness of the process.",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/development.md",sourceDirName:".",slug:"/development",permalink:"/it/security/development",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Deployment",permalink:"/it/security/deployment"},next:{title:"References",permalink:"/it/security/references"}},l={},c=[{value:"Risk: Developer Directly Pushes Malicious Code",id:"risk-developer-directly-pushes-malicious-code",level:3},{value:"Risk: Code Regressions",id:"risk-code-regressions",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"development"},"Development"),(0,o.kt)("p",null,"The main process to counter malicious actors in development of Cwtch is the openness of the process."),(0,o.kt)("p",null,"To enhance this openness, automated builds, testing and packaging are defined as part of the repositories - improving te robustness of the code base at every stage."),(0,o.kt)("p",null,(0,o.kt)("img",{parentName:"p",src:"https://docs.openprivacy.ca/cwtch-security-handbook/1.png",alt:null})),(0,o.kt)("p",null,"While individual tests aren't perfect, and all processes have gaps, we should be committed to make it as easy as possible to contribute to Cwtch while also building pipelines and processes that catch errors (unintential or malicious) as soon as possible."),(0,o.kt)("h3",{id:"risk-developer-directly-pushes-malicious-code"},"Risk: Developer Directly Pushes Malicious Code"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Mitigated")),(0,o.kt)("p",null,(0,o.kt)("inlineCode",{parentName:"p"},"trunk")," is currently locked and only 3 Open Privacy staff members have permission to override it, in addition the responsibility of monitoring changes."),(0,o.kt)("p",null,"Further every new pull request and merge triggered automated builds & tests which trigger emails and audit logs."),(0,o.kt)("p",null,"The code is also open source and inspectable by anyone."),(0,o.kt)("h3",{id:"risk-code-regressions"},"Risk: Code Regressions"),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")," (See individual project entries in this handbook for more information)"),(0,o.kt)("p",null,"Our automated pipelines have the ability to catch regressions when that behaviour is detectable."),(0,o.kt)("p",null,"The greatest challenge is in defining how such regressions are detected for the ",(0,o.kt)("a",{parentName:"p",href:"/security/category/cwtch-ui"},"ui")," - where behaviour isn't as strictly defined as it is for the individual libraries."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/ef78badf.25d419d6.js b/build-staging/it/assets/js/ef78badf.25d419d6.js new file mode 100644 index 00000000..1e7a51fb --- /dev/null +++ b/build-staging/it/assets/js/ef78badf.25d419d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5532],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var a=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,a,o=function(e,t){if(null==e)return{};var r,a,o={},n=Object.keys(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(a=0;a<n.length;a++)r=n[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=a.createContext({}),s=function(e){var t=a.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return a.createElement(p.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var r=e.components,o=e.mdxType,n=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=s(r),h=o,f=u["".concat(p,".").concat(h)]||u[h]||m[h]||n;return r?a.createElement(f,l(l({ref:t},c),{},{components:r})):a.createElement(f,l({ref:t},c))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var n=r.length,l=new Array(n);l[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[u]="string"==typeof e?e:o,l[1]=i;for(var s=2;s<n;s++)l[s]=r[s];return a.createElement.apply(null,l)}return a.createElement.apply(null,r)}h.displayName="MDXCreateElement"},5481:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>m,frontMatter:()=>n,metadata:()=>i,toc:()=>s});var a=r(7462),o=(r(7294),r(3905));const n={title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},l=void 0,i={permalink:"/it/blog/cwtch-platform-support",source:"@site/blog/2023-01-27-platform-support.md",title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",date:"2023-01-27T00:00:00.000Z",formattedDate:"27 gennaio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"support",permalink:"/it/blog/tags/support"}],readingTime:10.535,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch UI Platform Support",description:"This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.",slug:"cwtch-platform-support",tags:["cwtch","cwtch-stable","support"],image:"/img/devlog4_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Notes on Cwtch UI Testing",permalink:"/it/blog/cwtch-testing-i"},nextItem:{title:"Making Cwtch Bindings Reproducible",permalink:"/it/blog/cwtch-bindings-reproducible"}},p={authorsImageUrls:[void 0]},s=[],c={toc:s},u="wrapper";function m(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"One of the ",(0,o.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/blog/path-to-cwtch-stable#tenets-of-cwtch-stable"},"tenets for Cwtch Stable is ",(0,o.kt)("strong",{parentName:"a"},"Universal Availability and Cohesive Support")),":"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},'"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."')),(0,o.kt)("p",null,"This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable."),(0,o.kt)("p",null,"The questions we aim to answer in this post are: "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"What systems do we currently support?"),(0,o.kt)("li",{parentName:"ul"},"How do we decide what systems are supported?"),(0,o.kt)("li",{parentName:"ul"},"How do we handle new OS versions?"),(0,o.kt)("li",{parentName:"ul"},"How does application support differ from library support?"),(0,o.kt)("li",{parentName:"ul"},"What blockers exist for systems we wish to support, but currently cannot e.g ios?")),(0,o.kt)("p",null,(0,o.kt)("img",{src:r(6149).Z,width:"1005",height:"481"})))}m.isMDXComponent=!0},6149:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog4-3f3e04bb10946b0f668423f66177ab7d.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f041e880.8b186783.js b/build-staging/it/assets/js/f041e880.8b186783.js new file mode 100644 index 00000000..4cbc3004 --- /dev/null +++ b/build-staging/it/assets/js/f041e880.8b186783.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5226],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function l(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),s=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=s(e.components);return r.createElement(c.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=s(a),m=n,d=h["".concat(c,".").concat(m)]||h[m]||u[m]||o;return a?r.createElement(d,i(i({ref:t},p),{},{components:a})):r.createElement(d,i({ref:t},p))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[h]="string"==typeof e?e:n,i[1]=l;for(var s=2;s<o;s++)i[s]=a[s];return r.createElement.apply(null,i)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},3291:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=a(7462),n=(a(7294),a(3905));const o={title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,l={permalink:"/it/blog/cwtch-stable-roadmap-update",source:"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",date:"2023-03-31T00:00:00.000Z",formattedDate:"31 marzo 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"planning",permalink:"/it/blog/tags/planning"}],readingTime:5.61,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Cwtch Stable Roadmap Update",description:"Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more",slug:"cwtch-stable-roadmap-update",tags:["cwtch","cwtch-stable","planning"],image:"/img/devlog1_small.jpg",hide_table_of_contents:!1,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Availability Status and Profile Attributes",permalink:"/it/blog/availability-status-profile-attributes"},nextItem:{title:"Cwtch Beta 1.11",permalink:"/it/blog/cwtch-nightly-1-11"}},c={authorsImageUrls:[void 0]},s=[],p={toc:s},h="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"The next large step for the Cwtch project to take is a move from public ",(0,n.kt)("strong",{parentName:"p"},"Beta")," to ",(0,n.kt)("strong",{parentName:"p"},"Stable")," \u2013 marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months."),(0,n.kt)("p",null,"This post ",(0,n.kt)("a",{parentName:"p",href:"/blog/path-to-cwtch-stable"},"revisits the Cwtch Stable roadmap")," we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable."),(0,n.kt)("p",null,(0,n.kt)("img",{src:a(9469).Z,width:"1005",height:"480"})))}u.isMDXComponent=!0},9469:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/devlog1-53937adbfa7a7edf40d34660f71ed0fd.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f04f0ec9.67327fd7.js b/build-staging/it/assets/js/f04f0ec9.67327fd7.js new file mode 100644 index 00000000..71a329e9 --- /dev/null +++ b/build-staging/it/assets/js/f04f0ec9.67327fd7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4508],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>g});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),m=l(r),d=i,g=m["".concat(c,".").concat(d)]||m[d]||u[d]||a;return r?n.createElement(g,o(o({ref:t},p),{},{components:r})):n.createElement(g,o({ref:t},p))}));function g(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,o=new Array(a);o[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[m]="string"==typeof e?e:i,o[1]=s;for(var l=2;l<a;l++)o[l]=r[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},9431:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=r(7462),i=(r(7294),r(3905));const a={sidebar_position:4.5},o="Formattazione messaggio",s={unversionedId:"chat/message-formatting",id:"chat/message-formatting",title:"Formattazione messaggio",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento di formattazione messaggio attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/message-formatting.md",sourceDirName:"chat",slug:"/chat/message-formatting",permalink:"/it/docs/chat/message-formatting",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/chat/message-formatting.md",tags:[],version:"current",sidebarPosition:4.5,frontMatter:{sidebar_position:4.5},sidebar:"tutorialSidebar",previous:{title:"Salvare la cronologia delle conversazioni",permalink:"/it/docs/chat/save-conversation-history"},next:{title:"Accessing Conversation Settings",permalink:"/it/docs/chat/conversation-settings"}},c={},l=[],p={toc:l},m="wrapper";function u(e){let{components:t,...r}=e;return(0,i.kt)(m,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"formattazione-messaggio"},"Formattazione messaggio"),(0,i.kt)("p",null,":::attenzione Esperimenti necessari"),(0,i.kt)("p",null,"Questa funzione richiede ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/message-formatting"},"Esperimento di formattazione messaggio")," attivato."),(0,i.kt)("p",null,"Come opzione ulteriore, puoi abilitare ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/settings/experiments/clickable-links"},"Link cliccabili")," per rendere gli URL nei messaggi cliccabili in Cwtch."),(0,i.kt)("p",null,":::"),(0,i.kt)("p",null,"Cwtch attualmente supporta la seguente formattazione markdown per i messaggi:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"**grassetto**")," che risulter\xe0 in ",(0,i.kt)("strong",{parentName:"li"},"grassetto")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"*corsivo*")," che risulter\xe0 in ",(0,i.kt)("em",{parentName:"li"},"corsivo")),(0,i.kt)("li",{parentName:"ul"},"< code > codice < /code > (senza spazi) che risulter\xe0 in ",(0,i.kt)("inlineCode",{parentName:"li"},"codice")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"^apice^")," che risulter\xe0 in ",(0,i.kt)("sup",null,"apice")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"^pedice^")," che risulter\xe0 in ",(0,i.kt)("sub",null,"pedice")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"~~barrato~~")," che risulter\xe0 in ",(0,i.kt)("del",null,"barrato"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f21fe67f.4708943f.js b/build-staging/it/assets/js/f21fe67f.4708943f.js new file mode 100644 index 00000000..816a9c4f --- /dev/null +++ b/build-staging/it/assets/js/f21fe67f.4708943f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[48],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,o,n=function(e,t){if(null==e)return{};var r,o,n={},i=Object.keys(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=o.createContext({}),c=function(e){var t=o.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,l=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=c(r),h=n,d=u["".concat(l,".").concat(h)]||u[h]||m[h]||i;return r?o.createElement(d,s(s({ref:t},p),{},{components:r})):o.createElement(d,s({ref:t},p))}));function d(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,s=new Array(i);s[0]=h;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[u]="string"==typeof e?e:n,s[1]=a;for(var c=2;c<i;c++)s[c]=r[c];return o.createElement.apply(null,s)}return o.createElement.apply(null,r)}h.displayName="MDXCreateElement"},5493:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>m,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var o=r(7462),n=(r(7294),r(3905));const i={sidebar_position:4},s="Groups",a={unversionedId:"components/cwtch/groups",id:"components/cwtch/groups",title:"Groups",description:"For the most part the Cwtch risk model for groups is split into two distinct profiles:",source:"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/groups.md",sourceDirName:"components/cwtch",slug:"/components/cwtch/groups",permalink:"/it/security/components/cwtch/groups",draft:!1,tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4},sidebar:"tutorialSidebar",previous:{title:"Key Bundles",permalink:"/it/security/components/cwtch/key_bundles"},next:{title:"Cwtch Server",permalink:"/it/security/components/cwtch/server"}},l={},c=[{value:"Risk Overview: Key Derivation",id:"risk-overview-key-derivation",level:2},{value:"Risk: Malicious Peer Leaks Group Key and/or Conversation",id:"risk-malicious-peer-leaks-group-key-andor-conversation",level:2},{value:"Risk: Active Attacks by Group Members",id:"risk-active-attacks-by-group-members",level:2},{value:"Mitigations:",id:"mitigations",level:3}],p={toc:c},u="wrapper";function m(e){let{components:t,...r}=e;return(0,n.kt)(u,(0,o.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"groups"},"Groups"),(0,n.kt)("p",null,"For the most part the Cwtch risk model for groups is split into two distinct profiles:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Groups made up of mutually trusted participants where peers are assumed honest."),(0,n.kt)("li",{parentName:"ul"},"Groups consisting of strangers where peers are assumed to be potentially malicious.")),(0,n.kt)("p",null,"Most of the mitigations described in this section relate to the latter case, but naturally also impact the former. Even if assumed honest peers later turn malicious there are mechanisms that can detect such malice and prevent it from happening in the future."),(0,n.kt)("h2",{id:"risk-overview-key-derivation"},"Risk Overview: Key Derivation"),(0,n.kt)("p",null,"In the ideal case we would use a protocol like OTR, the limitations preventing us from doing so right now are:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Offline messages are not guaranteed to reach all peers, and as such any metadata relating to key material might get lost. We need a key derivation process which is robust to missing messages or incomplete broadcast.")),(0,n.kt)("h2",{id:"risk-malicious-peer-leaks-group-key-andor-conversation"},"Risk: Malicious Peer Leaks Group Key and/or Conversation"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Status: Partially Mitigated (but impossible to mitigate fully)")),(0,n.kt)("p",null,"Whether dealing with trusted smaller groups or partially-public larger groups there is ",(0,n.kt)("em",{parentName:"p"},"always")," the possibility that a malicious actor will leak group messages."),(0,n.kt)("p",null,"We plan to make it easy for peers to ",(0,n.kt)("a",{parentName:"p",href:"#fork"},"fork")," groups to mitigate the same key being used to encrypt lots of sensitive information and provide some level of forward secrecy for past group conversations."),(0,n.kt)("h2",{id:"risk-active-attacks-by-group-members"},"Risk: Active Attacks by Group Members"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Status: Partially Mitigated")),(0,n.kt)("p",null,"Group members, who have access to the key material of the group, can conspire with a server or other group members to break transcript consistency."),(0,n.kt)("p",null,"While we cannot directly prevent censorship given this kind of active collusion, we have a number of mechanisms in place that should reveal the presence of censorship to honest members of the group."),(0,n.kt)("h3",{id:"mitigations"},"Mitigations:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Because each message is signed by the peers public key, it should not be possible (within the cryptographic assumptions of the underlying cryptography) for one group member to imitate another."),(0,n.kt)("li",{parentName:"ul"},"Each message contains a unique identifier derived from the contents and the previous message hash - making it impossible for collaborators to include messages from non-colluding members without revealing an implicit message chain (which if they were attempting to censor other messages would reveal such censorship)")),(0,n.kt)("p",null,"Finally: We are actively working on adding non-repudiation to Cwtch servers such that they themselves are restricted in what they can censor efficiently."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f2d017e0.bf63989d.js b/build-staging/it/assets/js/f2d017e0.bf63989d.js new file mode 100644 index 00000000..9fc85281 --- /dev/null +++ b/build-staging/it/assets/js/f2d017e0.bf63989d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[981],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>b});var i=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function A(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?A(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):A(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,i,n=function(e,t){if(null==e)return{};var r,i,n={},A=Object.keys(e);for(i=0;i<A.length;i++)r=A[i],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var A=Object.getOwnPropertySymbols(e);for(i=0;i<A.length;i++)r=A[i],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var o=i.createContext({}),p=function(e){var t=i.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=p(e.components);return i.createElement(o.Provider,{value:t},e.children)},s="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},m=i.forwardRef((function(e,t){var r=e.components,n=e.mdxType,A=e.originalType,o=e.parentName,c=a(e,["components","mdxType","originalType","parentName"]),s=p(r),m=n,b=s["".concat(o,".").concat(m)]||s[m]||u[m]||A;return r?i.createElement(b,l(l({ref:t},c),{},{components:r})):i.createElement(b,l({ref:t},c))}));function b(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var A=r.length,l=new Array(A);l[0]=m;var a={};for(var o in t)hasOwnProperty.call(t,o)&&(a[o]=t[o]);a.originalType=e,a[s]="string"==typeof e?e:n,l[1]=a;for(var p=2;p<A;p++)l[p]=r[p];return i.createElement.apply(null,l)}return i.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8382:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>A,metadata:()=>a,toc:()=>p});var i=r(7462),n=(r(7294),r(3905));const A={sidebar_position:5},l="Esperimento Link cliccabili",a={unversionedId:"settings/experiments/clickable-links",id:"settings/experiments/clickable-links",title:"Esperimento Link cliccabili",description:"Questa funzione, se abilitata, presenta un rischio di deanonimizzazione.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/clickable-links.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/clickable-links",permalink:"/it/docs/settings/experiments/clickable-links",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/clickable-links.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"tutorialSidebar",previous:{title:"Anteprime immagine e immagini del profilo",permalink:"/it/docs/settings/experiments/image-previews-and-profile-pictures"},next:{title:"Formattazione messaggio",permalink:"/it/docs/settings/experiments/message-formatting"}},o={},p=[{value:"Rischi",id:"rischi",level:2}],c={toc:p},s="wrapper";function u(e){let{components:t,...A}=e;return(0,n.kt)(s,(0,i.Z)({},c,A,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"esperimento-link-cliccabili"},"Esperimento Link cliccabili"),(0,n.kt)("p",null,":::pericolo"),(0,n.kt)("p",null,"Questa funzione, se abilitata, presenta un rischio di ",(0,n.kt)("strong",{parentName:"p"},"deanonimizzazione"),"."),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Non")," aprire URL provenienti da persone di cui non ti fidi. I link inviati tramite Cwtch vengono aperti tramite il browser ",(0,n.kt)("strong",{parentName:"p"},"predefinito")," del sistema. La maggior parte dei browser non pu\xf2 fornire anonimato."),(0,n.kt)("p",null,":::"),(0,n.kt)("h1",{id:"abilita-lesperimento-link-cliccabili"},"Abilita l'Esperimento Link cliccabili"),(0,n.kt)("p",null,"I link cliccabili ",(0,n.kt)("strong",{parentName:"p"},"non sono")," abilitati come impostazione predefinita. Per consentire a Cwtch di aprire i link nei messaggi:"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},'Vai su "Impostazioni"'),(0,n.kt)("li",{parentName:"ol"},'Abilita "Esperimenti"'),(0,n.kt)("li",{parentName:"ol"},"Abilita l'Esperimento ",(0,n.kt)("inlineCode",{parentName:"li"},"Link cliccabili"))),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(1302).Z,width:"1243",height:"58"})),(0,n.kt)("h2",{id:"rischi"},"Rischi"),(0,n.kt)("p",null,"Avere link cliccabili nei messaggi \xe9 molto utile, tuttavia ci sono rischi di cui devi essere consapevole se scegli di abilitare questa funzione."),(0,n.kt)("p",null,"Per evitare l'attivazione accidentale, dopo aver cliccato su un link in un messaggio, Cwtch aprir\xe0 prima un prompt aggiuntivo con due opzioni:"),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(6004).Z,width:"1274",height:"192"})),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Copia l'URL negli appunti"),(0,n.kt)("li",{parentName:"ol"},"Apri l'URL nel ",(0,n.kt)("strong",{parentName:"li"},"web browser predefinito"))),(0,n.kt)("p",null,"\xc8 possibile utilizzare il pulsante indietro sul dispositivo, o cliccare fuori da questo prompt per evitare di selezionare una delle due opzioni."),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Cwtch non pu\xf2 proteggerti se apri link maligni"),"."),(0,n.kt)("p",null,"L'URL viene aperto nel ",(0,n.kt)("strong",{parentName:"p"},"web browser predefinito")," che probabilmente, come minimo, esporr\xe1 il tuo indirizzo IP al server che ospita l'URL. Le pagine web possono anche utilizzare altre vulnerabilit\xe0 del browser per raccogliere altre informazioni, o attaccare il tuo computer con ulteriori exploit."))}u.isMDXComponent=!0},6004:(e,t,r)=>{r.d(t,{Z:()=>i});const i=r.p+"assets/images/clickable_links-bb81ced13bf30ba78591fa7f0b5550dd.png"},1302:(e,t,r)=>{r.d(t,{Z:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABNsAAAA6CAIAAAAGIMiyAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4nO3de1yM6f8/8GumdFCrViRZpbZVSbRbNklYpSSklmgplXNC+aLNSiJMRC1bDkmxkkOlROkcHWw1HTQdhlqsY6VaNoNQ8/vj/n3uzzw6TBmSz3o9/5q57muu08w1j3nPdd/XzRg2bBgRSlpaWngGAAAAAAAAABEw+7oBAAAAAAAA8JlCRAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfQMRKQAAAAAAAPQNRKQAAAAAAADQNxCRAgAAAAAAQN/47CJSFotV3UFCQoLIBXI4HBaL1emhzMzMqKiody1w+PDhoaGhmZmZHA6noqIiLy8vNDSUOnTz5k0fHx/q8YkTJ86ePSukHBcXl+rqaktLy55XLaQvglX3BIvFunnzZsd0BQWF5OTkgICA92kMAAAAAAD8O4j3dQP6AJ/P9/PzE0xpamrqq8a0Y2tru2HDBgkJifz8/Dt37rS1tamoqMjJyXXMOXjw4P79+3/8Fr4nJSWlQYMGDR48uK8bAgAAAAAAPcLn89ulMBiMD1X4R4pIlZSU6Me1tbWdpnw0fD7/5MmTH7PGnnN1dX3x4sXKlSvLysqE55wxY8bHadKHVVFRoa+v39etAAAAAACAblCB6I8//jh16lRdXd0hQ4YQQurq6jgcTkZGRkxMDPkQoWnvRqSenp7Tpk0bMmSIlJQUnWhiYkIIyc7OplNevXpVV1eXkpKyZ8+eXm3PJ27z5s1fffXVli1bug1HAQAAAAAAeg+fz//xxx/XrVunrKwsmK6srKysrGxhYbFu3bpff/01JibmPYPSXryONCIiYunSpaqqqhISEi8FUEcFUyQkJFRVVZctWxYeHt577emWi4tLSUnJgQMH8vPzq6qqrl+/7unpSR0yMzM7d+4cm83mcrklJSW///674BrvqFGj/vjjD+ol7c4HFrRp06bs7OzKyko2m33o0KGOGbS1tRsaGqKjo3vS2ri4uCtXrtBPvb29c3JyqqqqSktLO64Am5ubs9ls6m+M5cuXJyYmlpaWcrncgoICf39/wZwfqi9CsNns4OBg6jGHwwkMDMzKyqqsrCwuLqbTBSkoKFy5ciUvL8/AwIAQsmPHjry8vKqqqpKSkpSUFC0trXeqHQAAAAAAhOPz+T4+Pv7+/u3CUUHKysr+/v4+Pj4dz+l9J721Rvp///d/xsbGr1+/TkxMDAsL43K57TKMGTOGfqylpbVkyRIrKytjY+P169fv37+/l1pFYTKZ1dXVgimBgYEhISGEEFlZWXV19XPnzjU3N8+ZM2fx4sVU2PPy5cs3b94kJyffv39fQ0NjxowZPj4+q1atol4+ZMiQhISExsbGyZMnz58//+3bt9u2bWtXqYeHh4uLS3x8fElJiba2to2NzYEDB9auXSuYR1FR8e+//xahR35+fjY2Nunp6WVlZSNGjGj3L4WRkZGvr299ff3y5csJIZKSknV1ddevX29sbDQ0NLSxsbl79y4dVX6ovvScoaFhSkrKvXv3JkyYYG5uvmXLlnaRcFhYmIKCgqenJ5vNXrZsmZ2dXVpaWmFhoby8/NChQzt+tAAAAAAAoB1lMmBRm95kvpo6f6B4ZwuTfMLnE8In/FZ+G/E1kXAY25NiHRwc+Hz+9u3bRV4p7a2I1MLCghBy6dIleplRCC6Xu3Hjxra2NltbWwsLi96OSDvubFRUVEQ/Dg4OTkpKIoQ0NTXt3r174sSJKSkpubm5ubm5dB41NbWvv/6afpqZmUkVeOjQocuXL0+bNq1jFDdz5szq6mp6NIYNG6anp9cuT79+/UTr0fTp069du9ZpTCgrK+vl5fXy5cvVq1c3NjYSQg4ePEgfDQkJYbPZgi35UH3puWvXrlFVHD9+vKioSFdXV/BoVFSUqqqqr69vRkYGIURDQ4PP58fHx6ekpIhcIwAAAADAZ8WOr+vbatZpICqICkf5czUlF/coHKU4OjqWl5fHxsaKFpT2VkSqqKjY2tp6+PBhOoXL5XZsIp/Pp8+6PHz4sLW1taKiYi81SbDSnuxsFB0dvXXrVhkZGeqpvb399OnTVVRUpKSkBgwYUF9f3+mrOBzOnDlzZGRkeDyeYLqCgsKwYcOqqqqopwwGo+NyaENDg5qa2rt2Z8qUKXJyciUlJZ0edXNzk5eXd3R0vHPnDp24fv36CRMmDBo0SFpaWlZWVkJC4oP3RTR1dXXS0tL0UyMjI2Vl5X379sXFxVEpSUlJU6ZMCQwM/Ouvv0pKSg4fPnz//v0PUjUAAAAAwL+SHV93Z6u58Dz/f4GUT96SNqn1hu9ahbu7e2xsLJ/PFyEo/ezuRyoaBweHX375hRBy6tSpDRs2cDicrnK+fv26tbW1XQhHCGlpaSksLNT+Dy0tLSMjo3Z5/vrrL3l5+U2bNr1T24YOHUoIYTI7fytv3LghJSW1cuVKOoXFYjk7O9+/f//QoUOurq5C7nzzPn35IGpqal6+fGlra0v/L5CVlWVoaHjixImXL1/OmjUrPj7e2tq6N6oGAAAAAPgXUCYDfFvNepKTT/htpI0xV4upPOCda1FWtrW1fffWEdJ7EWl9fb2YmJhgIKSlpaXZgeC2NCtXrhQTE+tq7bFvGRkZvXnzZvHixWFhYbm5ue0u3hX8J0BbW/vJkycdS6itrdXW1tbQ0BBSy759+xobG+fOnTtr1qyety0nJ6e1tbWr82aTkpIyMjKmTp3q4+NDpXz77bd379718PA4e/as4OnKH7YvH8STJ0/CwsJUVFSOHTsmmL5nz54ff/zR2dm5X79+5ubd/N8DAAAAAPDZWtSm1+3JurRWwmeavfM5mxRTU1PRXthbZ+2mpKSsWLFi5syZDAbj+PHjwref0dLScnFxsbKy4vP5H+H6QAaDYW9vL5jy9OlT6trRrjQ2NsrKyh47diwvL09bW1tHR4e6JpMybdq0lpaW27dvT5gwQVdX9+jRo1T6s2fPhg4dam5unpKScurUqR07doSEhJw5c+bu3buGhoYNDQ2hoaGCtdTW1oaHh69cuXLXrl2zZ8+urq5+8eKFqqqqvLz8smXLCCHPnz/X0NAwNDTMz8+nX3X//v3S0lITExN/f//s7GwdHZ3+/fvT8SchZOXKlTExMQsWLHj8+PHRo0efPXumo6Ozc+fOO3fuGBsbDxw4ULANXfVFsOqe9IUaZxcXF/opn88XYS/lX3/9VUlJae7cuYGBgR4eHqtWrdLV1S0rK6uvrzcyMpKUlHzw4MG7lgkAAAAA8JmYzO8+wqRP2W3lt0noDhGtIl1dXWrd7l1P3O2tiDQgIEBXV3fChAk2NjbW1tYtLS30IWpRSzDylJSUpE46zc3N3bdvXy81icZgMLZv3y6YwuVyhUek3t7eX3/99ffffz9+/PjHjx8XFRWNGDGCPlpeXm5lZdW/f//Gxsbw8HB6Z6bExEQnJ6eAgABPT8/z589LS0s7ODi4u7v369fv77//vnTpUseKjhw5UlZWtm7dulGjRk2cOPHNmzdPnz69ceMGdTQtLc3c3Nzf33/KlCmCr9qyZcvWrVtNTU2tra2fP3/e8ZrS1atXR0ZGurq6PnjwIDg4ePPmzTY2Nm/evKmpqampqRHM2VVfBKvuYV8YDIaXlxf9tLW1VbS7+3h5eSkqKs6YMePx48ctLS2ampoTJ06UkJB4/vx5amrq7t27RSgTAAAAAOBzoM4f2H0mQgghbaStlbSJKX0hWkVDhogYyjKGDRsmPIfgTjPvytPT09zcXFFRUUpKik40MTEhhGRnZ9Mpr169qq+vT0lJaXdvTAAAAAAAABBZ1VuPnmyxyyfkLb/1Bf+1/G0PIibKlrmtra0jR45kMBjvukbauxEpTUlJiX5cW1vbaQoAAAAAAAB8QJdbF4/kDxKeRzAilc1bIj5MToSKHj16ZGJiIkJE2ltn7bbTMeZEFAoAAAAAANCrrjLudBuR0hiE8arskaxIEWlZWZkIryK4+wsAAAAAAMC/1Slm6VvS1pOcTMJkEsar1D9Fqyg9PV20FyIiBQAAAAAA+Hd6RP7xEUsTnodBGAxCGAwixmC+ja58/fDpu9by8OHDmJgYEU7ZJYhIAQAAAAAA/sXOMTi/iKX0ZKVUnDAlGGKNAVfftYrAwECRmkYIIlJaTExMZGTkBykqISGhh7c5YbPZW7Zs6UnOrprX87oCAwMzMzN7kpMQYmlpWV1draWl1cP8nyfBIe35G/HvYG9vf/PmzZ7kZLFYubm5vd2ej6/nk1c0Z8+ePXv2bO+VDwAAAJ+VcwyOqXhYKLPwFqOhq9CUQRhMwpRkiPNjuPXh13teeEREBLVAKlrbPtLORp+IK1eufP311+0SW1tbey/0KigoKCgocHNz66XyRRMTEyMlJWVlZdXXDRHFpzmknzN/f/9p06ZZW1vfv3//o1W6du3aFStW6OjoCCZyudxdu3adPHlSX1//zJkzVOLbt28bGhri4+MDAgIIIdShDRs2xMfHf7TWfij48AMAAIDIHpF/9jCv7SHXhGfj8/l8Pr/V99A2xjYnJ6dui42IiNi2bZuYmJhop+ySzy0iXbhwYb9+/Qghvr6+mpqaCxYs6O0aS0pKKisre7uWd1VeXi54h9j/Lb06pAcPHtTQ0LC0tOyl8j8Rly9fvnv37urVqz9IaVwuV1FR8WOGoz3k5eWVk5MzduzYRYsWLVmypKamJi4urq8b9V4+ze8TAAAA+Dehokomk7lt2zYOh7N+/fqubhf68OHD/fv3x8TEMJlMkcNR8rlFpI2NjdSDtrY2Pp//Ee5As2LFit6uQgQ+Pj593QTR9eqQMplMMTGx3iv/EyEmJsZkfrAz9sPDwz/NM5bfvHlTW1tbW1ubnJxcXFxsZGT0vx6RfprfJwAAAPAvw2AwqCAzNjb2/Pnzc+fONTMzGzt2rJKSEiGktrb2xo0baWlp0dHRYmJi77M6SsF1pP81dOjQa9euVVVV5efnb9iwgUpUUFAIDw8vLi7mcDgXLlzQ09Nr96p58+alpqaWl5cXFhaGhIS0O5qXl7dz507qsaenZ25ubmVlZU5Ojqenp2A2Dw+PsrIyV1dXfX39CxculJSUcLncvLw8d3d3Os9XX32Vn59fVVV17dq1Tn+YmpiYJCQklJWVlZSUHDlyREhPo6KioqOjCSGWlpZsNjsqKqq0tLS8vDw2Nnb48OHtMh85cqSgoGDy5MkKCgqRkZGlpaUVFRW5ubmOjo6C2ToOlIyMTGZmZlRUFJXh6NGjOTk5w4cPj4mJiYqKysrKqqysvH79+vr164UMNYvFSkxMPH/+PIfDOXnypOCQslis1NTUK1eulJeXs9lsf3//gIAAaogyMjJmzpxJFevs7JyVlVVRUZGfn+/l5UUlxsTEnDt3rt3bvXPnTlNT0xEjRlRVVZ06dUqwd6GhoYWFhVwut6ioqNvrto2MjGJjY2/cuFFWVhYXF2dsbEwISUhIoE8TXbNmDZfL9fPzo54eO3YsISGBELJ3797CwsKqqqqCgoJdu3bRBTo6Ot66dcvCwoJ66u7uXlJSIiMjIyMjc+TIETabXVlZmZGRQb8j6enpBw4coB57eHgUFxcLNu/cuXPq6uo//PBDVVWVt7c3IaSrcgQFBwez2ezy8vL09HR6bCk+Pj4FBQXUYz09vejo6NLS0hs3brQ7LVZJSSk5OTkhIUFGRkYwfcuWLXl5eVVVVX/88cfWrVupROrNTUpKKi8vLy0t/e2334SPebfa2tpev34tJENXg08IMTc3T0pK4nA4HA4nPT1dQUGBSh83bhz1koyMjDlz5hBCupq/MTExx48fT01Nrays/OWXXwgh27dvz8/Pr6ioyMjIoE/WcHJyouZFQUFBx5lIOnz4hYzP+8wONze3a9euVVZWlpSUUJevdzr3u5oUO3bsyM/Pr6yszMrKyszM3L59O5XescvCv1IAAACgD1FBJpPJFBcXv3DhwqpVq4yMjNTU1NTU1IyMjFatWnXhwgVxcfH3XB2lICL9L0lJyfDw8DVr1vz111+Ojo7U72YWi6Wuru7h4bFy5Up5efl2kaSOjo6Xl9etW7cWL14cGBhYWFjYVeFLlixZtGhRQkLCggULIiMjORwOfWjp0qXOzs6nTp0KCQnhcrl37tw5ePDg5s2bHz58KHjqdr9+/YKCgpYvX/7gwYPVq1cbGRm1q8LHx4fH49na2u7Zs2f8+PFUsNEtOTm5R48eLV26NCwsTENDo10HAwICDAwMtm/ffvXq1c2bN2tqavr5+c2cOTMiIoIOQigdB4rH4wUFBY0ePdrd3d3JyWn8+PFBQUHUuZ0jRoyIjIx0dHTkcDhLly41MzMTMtQaGhrPnj3bvXv38ePH2zV+yJAhqampS5Ysyc/Pt7W1VVNT8/X19fPzExcXp4J2Q0NDDw+P7OzsSZMmXbp0ycHBgY7rhg4deuzYMcG3+5dffklPT7979662tvaiRYsEK3r48GFkZOTatWuzsrKsrKwWLlwoZEh9fX2ZTObatWt37do1cOBAKgIpKChQU1Ojgplx48bxeLyxY8dS+TU1Ndls9vz582fNmnXmzJkffvhh//792dnZdIEnT55sbGycPn069dTQ0JDL5fJ4vH379unq6gYEBLi6ujY1Nbm7u7e7rrJTdnZ2t2/fzszM1NbW3rFjByGk23IOHDjw3XffHThwwMnJKTk5mc1md1X4rl27JCUlN23atGnTpnY7aR0+fJjJZLq6uvJ4PDrR1dXVzs4uNjbW3t4+Ly/vp59+WrJkCXVoyJAhGRkZTk5OqampFhYWLi4u3XatUwYGBocPH2YwGOfPn+8qj5DBJ4S4ubm1tbWtWbPG2dn5zJkz9KkWfD5/69atfn5+TCaT+rwJmb9U+Orj4xMXF7dmzZo5c+YEBwfPnDnz4cOHa9euJYTo6+uvX7++vLzcwcEhPDxcQkJCeL+6HR+RZ4eLi0tlZeW8efN+/vnny5cvE0I6nfudTgqqa7GxsT/99FN2djb1Tyqd3q7Lwr9SAAAAoG/RQSkVl7ZDpb9/OEo+t7N2hbt79y598uGhQ4csLCxiY2MNDAwuXrx49epVQkhOTo65ubngSxwdHV+8eEFdj1dUVCSkcCsrqxs3brBYLEJIWVkZna6kpDR37ty4uLg9e/YQQng8Hr1mWFdXFxERYW5unpKSQgi5c+cOtd5YXFx89erVOXPmXL/+3y2w5s2bN3z4cBaLVVNTU1NTY2NjM2bMmB52PDQ0lMvlstlsY2NjwZUZBwcHMzMzf3//S5cuEUL69evHZDJVVVUzMzNDQ0PbFdLpQMXHx0+YMGHRokWvX7++ePEitTBLCLl9+zZVApvNzsvLmzFjRlpaWldD/eTJk6VLl3ba8ubm5n379hFCysvLJ06cWFZWlpiYSAgZO3bsDz/8QAiZP38+j8ejgvMdO3ZYWVmZmJgkJycTQu7du0ctuhKBt7urIdq2bRv1ICUlxdjYWEjgZ2trq6KiYmdnR73LYmJi27Zt09fXj4iIsLOzc3BwCAoK0tDQiImJsbe3V1BQ0NfXl5eXj4yMnDBhAoPBUFRUVFJSonfloZWXl48ePZp6PHLkyKNHjxJCvv/++9OnT1OZuVxuUlKSra1tRUVFV23rSrflTJgwITY2lhouIeHorFmz1NXVFy5cSM0Fapwpp0+fHjhwoJubW7vLTS0sLEpKSqg9h0pLS0eOHGlmZhYWFkYIaW5u3rt3L1Xj5MmTR40a9a792rt37549exgMRkNDw/r16wXnXTuSkpJCBl9MTExKSkpFReXkyZOC3Wez2UlJSYSQUaNGUdceC5m/HA5n8+bN1CEWi1VVVUWN54kTJ0JCQqZMmTJjxoynT59SuxYVFRVNmTJFeO+6HR+RZ4e4uPiAAQO++uor+h3sdO53OinMzMxKSkr8/f0JIaWlpdOmTaPymJubd+yy8K8UAAAA6HNUtMlgMPh8frvI8/0DURoi0k6kpaW1tbVJSkoqKSnJysrOmjWL3pa2ublZMKeSktLTpz26gayCgsK9e/c6po8dO5bBYFy79t89r7y9vSdNmiQlJUW9zdLS0u1ewuPxnjx5MnDgQMFEdXV1BoNBRbyUqqqqnjRMUHNz86BBg+inkyZNamxspH5PE0L27t0rLS1tb2/v5ORUVla2f/9+OggXMlCenp7Z2dl8Pr+rW2U0NTXJycl1O9TC8Xi8ly9f0peANjU1UaM3aNAgOTk5wSiitbW13Wvpt1tI+Y6OjvPmzRs4cGBbW9uAAQPExbucON988w2Px6ODn8jISG9vb01NzaKiops3b44bN446YXLXrl02NjaOjo7Dhw+/ffs29T/CyJEjJ02aZG1tXV1dffr0afqEZ0LI5cuXWSyWvr7+d999x+fzjxw5Qo3Y7du3qQy1tbVNTU30CaU91205SkpKAwYMuHv3brdFaWtrt7S0dPxrRlJSUldXt6CgoGNM+OWXX1ZXV9NPHz9+PHTo0I4l83i8dtf3trS0iImJycjI0CuuMjIyDAbj+fPndJ6NGzfGx8fv3bvXwsJC+Cm7J0+eFDL4v/32m7Oz88aNG9esWXP9+nVqfU9QQ0MDfV1uV/OXz+fT+eXk5FRVVemP5T///NO/f39FRcVnz54JaaQQHcen3dF3mh0hISHW1ta//vprbW1tUlKSv79/p3O/00khJyf3559/dmxDp10W8pUCAAAAn5QPGH92hLN2hamtrX3x4kViYqLBf1BrCzQej/fll1/2pKhXr14NHjy4Y3pqampdXZ2Pj4+GhgYhxNnZed68eUePHjUxMZk4cWJXpcnJydXV1QmmUEtPmzdvppvq4ODQk4YJERgY+OWXX9KXqN2/f3/ZsmUGBgb79u1TV1cXvMZVyEBt2LBBWlp6wIAB1MmrFMFtdeTl5evr67sdatE0NTU1NzcbCBBhVycZGZkNGzYUFBQYGxubmJjU19cLyfzo0SMZGRnq2lFCiKWlJYPBoE5HzMnJGTlypKmp6a1btwghXC7XwMBAR0cnPz+fyrxly5ZJkyZ5eHjw+XxXV1fBYuPi4urr621sbCZOnEitXtbW1r569UpwtVZOTu7x48eEECpCEN4p+mtFSDl0htevX6urqwsvkBDS1NQkJSVlYGDQLr2lpeX48ePGxsb0qhqtublZWVmZfjpw4MCmpqZuKyKE5OfnM5lMwQ/5/PnzW1tbBRdmKdu2bXv+/HnHMLIdIYOflJRkZ2c3bdq0mJgYU1NT+nrLjno4f//555+bN28KfiwTExOfPn0qwh8K76Or2XH48GFLS8sFCxZUVFQ4Ozvr6+t3nPtdTYrm5uZO/1PotMtCvlIAAADg84GItBvFxcXTp0+nrtGaOXMmtX8J7erVqwoKCkFBQUpKSpaWltTv41evXnWMB0pLS8eOHUv95Fq4cCF9f5G2tjYvLy9xcXFqaxBFRUUJCYnBgwfr6OjQO99QvvnmG2dnZx0dnZCQECkpKWoNh67r9OnTDx8+3Lhxo5mZmYyMjKOjo6GhoeDLeTyejIzMO/3kraysPHDgwJgxY6i2OTs7r1ixQklJ6ebNmy0tLT0ZqKlTpy5cuPDs2bPnz5+3s7ObOnUqlVlXV9fLy0tHRycwMFBWVvbs2bPdDrVo4uLipKWlT548qaGhoaam1u1Wpc3NzYqKitQ2TnTiiBEjJCUlFRQUtLS03Nzc5OXlqXTBIaXfiNjY2IaGhi1btpiZmU2dOtXd3b2srKympoYQEhQUJCYmZmRklJubSwjJycnR1NQcPHjw77//TgiZMmWKp6enjo5OdXV1p2tl1EdIS0srLS2NSuFwOLNnz3Z2dh4zZkxYWNjbt29PnDhBCHn8+PHo0aNdXFyMjIz09fU7FsXj8dTV1enrWrsqh1ZdXT1jxow5c+YMHz589erVw4cPf/LkCYPBaHebnOTk5H/++cfb21tPT09fX3/VqlX0ocDAwPj4eDs7u+XLlwu+5Pr163p6et7e3hoaGt7e3iNHjuzhdrilpaVlZWUuLi4eHh5GRkaurq5Lly7Nzc0VvEiV7mxsbOy33377008/0Yn9+/fX+g8lJSXhg79hw4a5c+fW1tbW1NRQ23R31Soh81dQVlaWrq6ur6+vjIyMoaEhtaNPUlKSvLz8sWPH9PT07O3tVVRUejIO76Or2eHj4zN58uTq6mpqN/LW1taOc7+rSZGXl6enp0f9xbZx48YvvvhCSJeFf6UAAADAZwIRaTe8vLxKSkpcXV3Lyso2bdo0btw4waNnz549derU+PHj09PTd+3aRe02lJaWpqqqmpqaKpjT09MzLy/PwcGhoqJi3bp19DWBhJCioiIWi6WiohIeHv7bb79xOJzVq1dHRUVpamoK/jiur693c3M7d+6cpqZmQEAAtVAmWJevr+/z588DAgJycnIcHBwEqyCEREdHv3jxIi0tbfLkyT3vfkRERGRkpKWl5aZNm9TV1Z2cnNLT048ePfrixYt223t2OlA///zzrVu39u7du3PnzpqaGnqzooaGhjlz5pw/f/7bb7/dv39/aWlpt0MtmqysrKCgoGHDhlFbV8+aNUv43j8RERF1dXXBwcGCtzOpqKhITEycMmVKTEzM7Nmz6eUgwSGl3wgej8disRgMRlBQ0L59+5qamgS3mKqsrJSQkKAumTty5AiDwbhz5w61vq2iomJpaXnmzJn4+HhVVdWO91OJi4tTV1dvbW2lIlhCyI4dO2pqatatWxcZGamsrOzn50eFEMHBwU+ePNm4cePBgwdbW1s7RlDR0dGysrIXL16kFi27KofGYrHq6uq2b9+emJhoZ2enq6ublpZWWlrKYrHoayMJIffv3w8KCvriiy9OnToVHh4+Y8YMwUI8PT0LCwtdXfZp1doAAAHqSURBVF0F0/38/JKSkqytrS9evGhubh4aGirkat52fv7556qqqoULF4aHhy9evJjNZne1yBYQEHDv3j3BfYa2b9+e8B9+fn7CB3/06NFeXl6VlZXe3t7FxcWC58a3I2T+tmvPmTNnpk2bdv369aCgIFNTU0JIcnLy0aNHR40aFRUV5ebm9uDBgx6Og8g6nR1qamrjx48/ePBgYWHh7Nmzz58/X1pa2nHudzUpdu/efeXKlVmzZsXHx5uamra0tFAfv067LPwrBQAAAD4TjK5ueErreB0jwPuIiYl59eqV8O1qoVPZ2dlcLnfZsmV93RCAHikuLg4LCwsODu7rhgAAAMCnC2ukAP8b9PT0Bg0aRG80BfCJmzx5cv/+/cvLy/u6IQAAAPBJw167AP8b7O3t//77byE31QT4FPj7+ycnJz979szd3f3mzZvU/ZwAAAAAuoKIFOB/g4GBgQh39AH4yEaPHm1lZdXW1vbnn38KXkQNAAAA0ClcRwoAAAAAAAB9A9eRAgAAAAAAQN9ARAoAAAAAAAB9AxEpAAAAAAAA9A1EpAAAAAAAANA3EJECAAAAAABA30BECgAAAAAAAH0DESkAAAAAAAD0DUSkAAAAAAAA0DcQkQIAAAAAAEDfQEQKAAAAAAAAfeP/AQclJUZgqx9hAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f4279852.ca90fc1f.js b/build-staging/it/assets/js/f4279852.ca90fc1f.js new file mode 100644 index 00000000..396e0710 --- /dev/null +++ b/build-staging/it/assets/js/f4279852.ca90fc1f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9902],{5391:e=>{e.exports=JSON.parse('{"permalink":"/it/blog","page":1,"postsPerPage":10,"totalPages":2,"totalCount":17,"nextPage":"/it/blog/page/2","blogDescription":"The latest updated on Cwtch development.","blogTitle":"Development Log"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f748f255.06c1bb18.js b/build-staging/it/assets/js/f748f255.06c1bb18.js new file mode 100644 index 00000000..27a2d2b0 --- /dev/null +++ b/build-staging/it/assets/js/f748f255.06c1bb18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8181],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var o=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function n(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,o,a=function(e,t){if(null==e)return{};var r,o,a={},i=Object.keys(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)r=i[o],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=o.createContext({}),p=function(e){var t=o.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):n(n({},t),e)),r},c=function(e){var t=p(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},f=o.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(r),f=a,m=u["".concat(s,".").concat(f)]||u[f]||d[f]||i;return r?o.createElement(m,n(n({ref:t},c),{},{components:r})):o.createElement(m,n({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,n=new Array(i);n[0]=f;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:a,n[1]=l;for(var p=2;p<i;p++)n[p]=r[p];return o.createElement.apply(null,n)}return o.createElement.apply(null,r)}f.displayName="MDXCreateElement"},5525:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>n,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var o=r(7462),a=(r(7294),r(3905));const i={sidebar_position:1.5},n="Creare un nuovo profilo",l={unversionedId:"profiles/create-a-profile",id:"profiles/create-a-profile",title:"Creare un nuovo profilo",description:'1. Clicca sul pulsante di azione "+" nell\'angolo in basso a destra e seleziona "Nuovo profilo"',source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/create-a-profile.md",sourceDirName:"profiles",slug:"/profiles/create-a-profile",permalink:"/it/docs/profiles/create-a-profile",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/create-a-profile.md",tags:[],version:"current",sidebarPosition:1.5,frontMatter:{sidebar_position:1.5},sidebar:"tutorialSidebar",previous:{title:"Un'introduzione ai profili di Cwtch",permalink:"/it/docs/profiles/introduction"},next:{title:"Cambiare il tuo nome visualizzato",permalink:"/it/docs/profiles/change-name"}},s={},p=[{value:"Una nota sui profili protetti da password (crittografati)",id:"una-nota-sui-profili-protetti-da-password-crittografati",level:2}],c={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,o.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"creare-un-nuovo-profilo"},"Creare un nuovo profilo"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},'Clicca sul pulsante di azione "',(0,a.kt)("inlineCode",{parentName:"li"},"+"),'" nell\'angolo in basso a destra e seleziona "Nuovo profilo"'),(0,a.kt)("li",{parentName:"ol"},"Seleziona un nome da visualizzare"),(0,a.kt)("li",{parentName:"ol"},"Seleziona se vuoi proteggere questo profilo localmente con crittografia avanzata:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Password: il tuo account \xe8 protetto da altre persone che potrebbero utilizzare questo dispositivo"),(0,a.kt)("li",{parentName:"ul"},"Nessuna password: chiunque abbia accesso a questo dispositivo ha la possibilit\xe0 di accedere a questo profilo"))),(0,a.kt)("li",{parentName:"ol"},"Inserisci nuovamente la tua password"),(0,a.kt)("li",{parentName:"ol"},"Clicca su aggiungi nuovo profilo")),(0,a.kt)("h2",{id:"una-nota-sui-profili-protetti-da-password-crittografati"},"Una nota sui profili protetti da password (crittografati)"),(0,a.kt)("p",null,"I profili sono memorizzati localmente sul disco e crittografati utilizzando una chiave derivata dalla password conosciuta dall'utente (tramite pbkdf2)."),(0,a.kt)("p",null,"Note that, once encrypted and stored on disk, the only way to recover a profile is by rederiving the key from the password - as such it isn't possible to provide a full list of profiles a user might have access to until they enter a password."),(0,a.kt)("p",null,"Vedi anche: ",(0,a.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html"},"Manuale sulla sicurezza di Cwtch: Crittografia del profilo & spazio di archiviazione")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f76a3b8e.d87fb81c.js b/build-staging/it/assets/js/f76a3b8e.d87fb81c.js new file mode 100644 index 00000000..df8f3bf6 --- /dev/null +++ b/build-staging/it/assets/js/f76a3b8e.d87fb81c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2184],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},g="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),g=l(n),m=i,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||a;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,o=new Array(a);o[0]=m;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[g]="string"==typeof e?e:i,o[1]=c;for(var l=2;l<a;l++)o[l]=n[l];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},3103:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=n(7462),i=(n(7294),n(3905));const a={title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},o=void 0,c={permalink:"/it/blog/cwtch-testing-ii",source:"@site/blog/2023-02-17-cwtch-testing-ii.md",title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",date:"2023-02-17T00:00:00.000Z",formattedDate:"17 febbraio 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"support",permalink:"/it/blog/tags/support"},{label:"testing",permalink:"/it/blog/tags/testing"}],readingTime:1.75,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"Notes on Cwtch UI Testing (II)",description:"In this development log we provide more updates on automated UI integration testing!",slug:"cwtch-testing-ii",tags:["cwtch","cwtch-stable","support","testing"],image:"/img/devlog7_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Autogenerating Cwtch Bindings",permalink:"/it/blog/autobindings"},nextItem:{title:"Making Cwtch Android Bindings Reproducible",permalink:"/it/blog/cwtch-android-reproducibility"}},s={authorsImageUrls:[void 0]},l=[],p={toc:l},g="wrapper";function u(e){let{components:t,...a}=e;return(0,i.kt)(g,(0,r.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"In this development log, we investigate some text-based UI bugs encountered by ",(0,i.kt)("a",{parentName:"p",href:"https://docs.cwtch.im/docs/contribute/testing#running-fuzzbot"},"Fuzzbot"),", add more ",(0,i.kt)("a",{parentName:"p",href:"/blog/cwtch-testing-i"},"automated UI tests")," to the pipeline, and announce a new release of the Cwtchbot library."),(0,i.kt)("p",null,(0,i.kt)("img",{src:n(6097).Z,width:"1005",height:"481"})))}u.isMDXComponent=!0},6097:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/devlog7-ddd3206f988a859af98340268befb0fa.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f7ca86a6.973d26c1.js b/build-staging/it/assets/js/f7ca86a6.973d26c1.js new file mode 100644 index 00000000..2e453771 --- /dev/null +++ b/build-staging/it/assets/js/f7ca86a6.973d26c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[4612],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>b});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),u=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l=function(e){var t=u(e.components);return n.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,o=e.originalType,s=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(r),f=i,b=p["".concat(s,".").concat(f)]||p[f]||d[f]||o;return r?n.createElement(b,a(a({ref:t},l),{},{components:r})):n.createElement(b,a({ref:t},l))}));function b(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=r.length,a=new Array(o);a[0]=f;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[p]="string"==typeof e?e:i,a[1]=c;for(var u=2;u<o;u++)a[u]=r[u];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},172:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var n=r(7462),i=(r(7294),r(3905));const o={sidebar_position:10},a="Stickers",c={unversionedId:"contribute/stickers",id:"contribute/stickers",title:"Stickers",description:"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email erinn@openprivacy.ca with details and an address for us to mail stickers to.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/stickers.md",sourceDirName:"contribute",slug:"/contribute/stickers",permalink:"/it/docs/contribute/stickers",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/contribute/stickers.md",tags:[],version:"current",sidebarPosition:10,frontMatter:{sidebar_position:10},sidebar:"tutorialSidebar",previous:{title:"Documentation Style Guide",permalink:"/it/docs/contribute/documentation"},next:{title:"Platforms",permalink:"/it/docs/category/platforms"}},s={},u=[],l={toc:u},p="wrapper";function d(e){let{components:t,...o}=e;return(0,i.kt)(p,(0,n.Z)({},l,o,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"stickers"},"Stickers"),(0,i.kt)("p",null,"All contributions are eligible for stickers. If you are contributing to bug, feature, testing, or language, or have contributed significantly in the past then please email ",(0,i.kt)("a",{parentName:"p",href:"mailto:erinn@openprivacy.ca"},"erinn@openprivacy.ca")," with details and an address for us to mail stickers to."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"A Photo of Cwtch Stickers",src:r(4515).Z,width:"1024",height:"768"})))}d.isMDXComponent=!0},4515:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/stickers-new-1e9b14bdd638b4907cce833e813a09ad.jpg"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f894db60.de13cf40.js b/build-staging/it/assets/js/f894db60.de13cf40.js new file mode 100644 index 00000000..efd53763 --- /dev/null +++ b/build-staging/it/assets/js/f894db60.de13cf40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[2436],{3905:(t,e,a)=>{a.d(e,{Zo:()=>u,kt:()=>g});var n=a(7294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?l(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function p(t,e){if(null==t)return{};var a,n,r=function(t,e){if(null==t)return{};var a,n,r={},l=Object.keys(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),d=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},u=function(t){var e=d(t.components);return n.createElement(o.Provider,{value:e},t.children)},m="mdxType",s={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,u=p(t,["components","mdxType","originalType","parentName"]),m=d(a),c=r,g=m["".concat(o,".").concat(c)]||m[c]||s[c]||l;return a?n.createElement(g,i(i({ref:e},u),{},{components:a})):n.createElement(g,i({ref:e},u))}));function g(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=c;var p={};for(var o in e)hasOwnProperty.call(e,o)&&(p[o]=e[o]);p.originalType=t,p[m]="string"==typeof t?t:r,i[1]=p;for(var d=2;d<l;d++)i[d]=a[d];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},8981:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>p,toc:()=>d});var n=a(7462),r=(a(7294),a(3905));const l={},i="Supported Platforms",p={unversionedId:"getting-started/supported_platforms",id:"getting-started/supported_platforms",title:"Supported Platforms",description:"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/getting-started/supported_platforms.md",sourceDirName:"getting-started",slug:"/getting-started/supported_platforms",permalink:"/it/docs/getting-started/supported_platforms",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/getting-started/supported_platforms.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Getting started",permalink:"/it/docs/category/getting-started"},next:{title:"Profiles",permalink:"/it/docs/category/profiles"}},o={},d=[],u={toc:d},m="wrapper";function s(t){let{components:e,...a}=t;return(0,r.kt)(m,(0,n.Z)({},u,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"supported-platforms"},"Supported Platforms"),(0,r.kt)("p",null,"The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023)."),(0,r.kt)("p",null,"In many cases we are looking for testers to confirm that various functionality works. If you are interested in testing Cwtch on a specific platform, or want to volunteer to help us official support a platform not listed here, then check out ",(0,r.kt)("a",{parentName:"p",href:"/docs/category/contribute"},"Contibuting to Cwtch"),"."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"Legend:")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\u2705: ",(0,r.kt)("strong",{parentName:"li"},"Officially Supported"),". Cwtch should work on these platforms without issue. Regressions are treated as high priority."),(0,r.kt)("li",{parentName:"ul"},"\ud83d\udfe1: ",(0,r.kt)("strong",{parentName:"li"},"Best Effort Support"),". Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated."),(0,r.kt)("li",{parentName:"ul"},"\u274c: ",(0,r.kt)("strong",{parentName:"li"},"Not Supported"),". Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"Platform"),(0,r.kt)("th",{parentName:"tr",align:null},"Official Cwtch Builds"),(0,r.kt)("th",{parentName:"tr",align:null},"Source Support"),(0,r.kt)("th",{parentName:"tr",align:null},"Notes"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 only. Not officially supported, but official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Windows 8 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Not supported. Dedicated builds from source may work. Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 10 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\u274c"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds have been reported to work on Catalina but not High Sierra")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OSX 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Official builds supports both arm64 and x86 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Debian 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Ubuntu 22.04"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit amd64 Only.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Ubuntu"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"CentOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Gentoo"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Arch"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Whonix"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues/550"},"Known Issues. Specific changes to Cwtch are required for support. "))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Raspian (arm64)"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Builds from source work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Linux Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 9 and below"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Official builds may work.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 10"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 11"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 12"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Android 13"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"LineageOS"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"\u2705"),(0,r.kt)("td",{parentName:"tr",align:null},"Official SDK supprts arm, arm64, and amd64 architectures.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Other Android Distributions"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud83d\udfe1"),(0,r.kt)("td",{parentName:"tr",align:null},"Testing Needed.")))))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f928e8d9.9677409e.js b/build-staging/it/assets/js/f928e8d9.9677409e.js new file mode 100644 index 00000000..ef31e981 --- /dev/null +++ b/build-staging/it/assets/js/f928e8d9.9677409e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[8786],{7160:e=>{e.exports=JSON.parse('{"pluginId":"docs-developer","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Introduction to Cwtch Development","href":"/it/developing/intro","docId":"intro"},{"type":"link","label":"Release and Packaging Process","href":"/it/developing/release","docId":"release"},{"type":"category","label":"Building a Cwtch App","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/it/developing/building-a-cwtch-app/intro","docId":"building-a-cwtch-app/intro"},{"type":"link","label":"Core Concepts","href":"/it/developing/building-a-cwtch-app/core-concepts","docId":"building-a-cwtch-app/core-concepts"},{"type":"link","label":"Building a Cwtch Echobot","href":"/it/developing/building-a-cwtch-app/building-an-echobot","docId":"building-a-cwtch-app/building-an-echobot"}],"href":"/it/developing/category/building-a-cwtch-app"}]},"docs":{"building-a-cwtch-app/building-an-echobot":{"id":"building-a-cwtch-app/building-an-echobot","title":"Building a Cwtch Echobot","description":"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/core-concepts":{"id":"building-a-cwtch-app/core-concepts","title":"Core Concepts","description":"This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.","sidebar":"tutorialSidebar"},"building-a-cwtch-app/intro":{"id":"building-a-cwtch-app/intro","title":"Getting Started","description":"Choosing A Cwtch Library","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Introduction to Cwtch Development","description":"- Core Concepts","sidebar":"tutorialSidebar"},"release":{"id":"release","title":"Release and Packaging Process","description":"Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f9b019e0.b5b4a856.js b/build-staging/it/assets/js/f9b019e0.b5b4a856.js new file mode 100644 index 00000000..f531aff9 --- /dev/null +++ b/build-staging/it/assets/js/f9b019e0.b5b4a856.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[225],{3905:(e,i,t)=>{t.d(i,{Zo:()=>u,kt:()=>g});var r=t(7294);function n(e,i,t){return i in e?Object.defineProperty(e,i,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[i]=t,e}function o(e,i){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);i&&(r=r.filter((function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var i=1;i<arguments.length;i++){var t=null!=arguments[i]?arguments[i]:{};i%2?o(Object(t),!0).forEach((function(i){n(e,i,t[i])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(i){Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(t,i))}))}return e}function p(e,i){if(null==e)return{};var t,r,n=function(e,i){if(null==e)return{};var t,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],i.indexOf(t)>=0||(n[t]=e[t]);return n}(e,i);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],i.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(n[t]=e[t])}return n}var s=r.createContext({}),c=function(e){var i=r.useContext(s),t=i;return e&&(t="function"==typeof e?e(i):a(a({},i),e)),t},u=function(e){var i=c(e.components);return r.createElement(s.Provider,{value:i},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var i=e.children;return r.createElement(r.Fragment,{},i)}},m=r.forwardRef((function(e,i){var t=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),l=c(t),m=n,g=l["".concat(s,".").concat(m)]||l[m]||d[m]||o;return t?r.createElement(g,a(a({ref:i},u),{},{components:t})):r.createElement(g,a({ref:i},u))}));function g(e,i){var t=arguments,n=i&&i.mdxType;if("string"==typeof e||n){var o=t.length,a=new Array(o);a[0]=m;var p={};for(var s in i)hasOwnProperty.call(i,s)&&(p[s]=i[s]);p.originalType=e,p[l]="string"==typeof e?e:n,a[1]=p;for(var c=2;c<o;c++)a[c]=t[c];return r.createElement.apply(null,a)}return r.createElement.apply(null,t)}m.displayName="MDXCreateElement"},9495:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>p,toc:()=>c});var r=t(7462),n=(t(7294),t(3905));const o={sidebar_position:1},a="Un'introduzione ai gruppi di Cwtch",p={unversionedId:"groups/introduction",id:"groups/introduction",title:"Un'introduzione ai gruppi di Cwtch",description:"Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/introduction.md",sourceDirName:"groups",slug:"/groups/introduction",permalink:"/it/docs/groups/introduction",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/groups/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Groups",permalink:"/it/docs/category/groups"},next:{title:"Creare un nuovo gruppo",permalink:"/it/docs/groups/create-group"}},s={},c=[{value:"Come funzionano i gruppi sotto il coperchio",id:"come-funzionano-i-gruppi-sotto-il-coperchio",level:2}],u={toc:c},l="wrapper";function d(e){let{components:i,...t}=e;return(0,n.kt)(l,(0,r.Z)({},u,t,{components:i,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"unintroduzione-ai-gruppi-di-cwtch"},"Un'introduzione ai gruppi di Cwtch"),(0,n.kt)("p",null,":::attenzione Esperimenti necessari"),(0,n.kt)("p",null,"Questa funzione richiede ",(0,n.kt)("a",{parentName:"p",href:"/docs/settings/introduction#experiments"},"Esperimenti abilitati")," e l'",(0,n.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"Esperimento Gruppi")," attivato."),(0,n.kt)("p",null,":::"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"Nota: la comunicazione di gruppo resistente ai metadati \xe8 ancora un'area di ricerca attiva e ci\xf2 che \xe8 documentato qui probabilmente cambier\xe0 in futuro.")),(0,n.kt)("p",null,"Per impostazione predefinita, Cwtch supporta solo chat peer-to-peer e online. Per supportare le conversazioni con pi\xf9 parti e il recapito offline, \xe8 necessaria una terza parte (non fidata). Chiamiamo queste entit\xe0 terze ",(0,n.kt)("a",{parentName:"p",href:"/docs/servers/introduction"},'"server"'),"."),(0,n.kt)("p",null,"Questi server possono essere creati da chiunque e sono pensati per essere sempre online. Il punto fondamentale \xe8 che tutte le comunicazioni con un server sono progettate in modo tale che il server abbia il meno possibile informazioni sui contenuti o metadati."),(0,n.kt)("p",null,"Per molti aspetti la comunicazione con un server \xe8 identica a quella con un normale peer Cwtch, comprende tutti gli stessi passi, tuttavia il server agisce sempre come peer in entrata, e il peer in uscita utilizza sempre una ",(0,n.kt)("strong",{parentName:"p"},"coppia di chiavi effimera")," appena generata - in modo che ogni sessione del server sia disconnessa."),(0,n.kt)("p",null,"Di conseguenza, le conversazioni peer-server differiscono solo nei ",(0,n.kt)("em",{parentName:"p"},"tipi")," di messaggi inviati tra le due parti, con il server che memorizza tutti i messaggi che riceve e quindi permette a qualsiasi client di ripescare i messaggi pi\xf9 vecchi."),(0,n.kt)("p",null,"The risk model associated with servers is more complicated that peer-to-peer communication, as such we currently require people who want to use servers within Cwtch to ",(0,n.kt)("a",{parentName:"p",href:"/docs/settings/experiments/group-experiment"},"opt-in to the Group Chat experiment")," in order to add, manage and create groups on untrusted servers."),(0,n.kt)("h2",{id:"come-funzionano-i-gruppi-sotto-il-coperchio"},"Come funzionano i gruppi sotto il coperchio"),(0,n.kt)("p",null,"Quando una persona vuole iniziare una conversazione di gruppo, in primo luogo genera casualmente una ",(0,n.kt)("inlineCode",{parentName:"p"},"Chiave di gruppo")," segreta. Tutte le comunicazioni del gruppo verranno cifrate utilizzando questa chiave."),(0,n.kt)("p",null,"Insieme alla ",(0,n.kt)("inlineCode",{parentName:"p"},"Chiave di gruppo"),", il creatore del gruppo decide anche il ",(0,n.kt)("strong",{parentName:"p"},"Server Cwtch")," da utilizzare come host del gruppo. Per ulteriori informazioni su come i Server autenticano se stessi si vedano i ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/key_bundles.html"},"pacchetti di chiavi"),"."),(0,n.kt)("p",null,"Un ",(0,n.kt)("inlineCode",{parentName:"p"},"Identificatore di gruppo")," \xe8 generato utilizzando la chiave di gruppo e il server di gruppo e questi tre elementi sono raggruppati in un invito che pu\xf2 essere inviato ai potenziali membri del gruppo (per esempio tramite connessioni peer-to-peer esistenti)."),(0,n.kt)("p",null,"Per inviare un messaggio al gruppo, un profilo si collega al server che ospita il gruppo (vedi sotto), e crittografa il proprio messaggio con la ",(0,n.kt)("inlineCode",{parentName:"p"},"Chiave di gruppo")," e genera una firma crittografica sotto l'",(0,n.kt)("inlineCode",{parentName:"p"},"Identificatore di gruppo"),", il ",(0,n.kt)("inlineCode",{parentName:"p"},"Server di gruppo")," e il messaggio decriptato (vedi ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/message_formats.html"},"formati di trasmissione")," per ulteriori informazioni)."),(0,n.kt)("p",null,"Per ricevere un messaggio dal gruppo, un profilo deve essere collegato al server che ospita il gruppo e scaricare ",(0,n.kt)("em",{parentName:"p"},"tutti")," i messaggi (dall'ultima connessione precedente). I profili tentano quindi di decifrare ogni messaggio utilizzando la ",(0,n.kt)("inlineCode",{parentName:"p"},"Chiave di gruppo")," e in caso di successo cercano di verificare la firma (vedi ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/server.html"},"Server di Cwtch"),", ",(0,n.kt)("a",{parentName:"p",href:"https://docs.openprivacy.ca/cwtch-security-handbook/groups.html"},"Gruppi di Cwtch")," per una panoramica degli attacchi e delle mitigazioni)."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/f9cff38b.63dfbda8.js b/build-staging/it/assets/js/f9cff38b.63dfbda8.js new file mode 100644 index 00000000..8bb53801 --- /dev/null +++ b/build-staging/it/assets/js/f9cff38b.63dfbda8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1932],{6601:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/nightly","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fa088e0f.7d5235c3.js b/build-staging/it/assets/js/fa088e0f.7d5235c3.js new file mode 100644 index 00000000..dbbb710a --- /dev/null +++ b/build-staging/it/assets/js/fa088e0f.7d5235c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[9399],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},l="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),l=p(r),m=o,f=l["".concat(c,".").concat(m)]||l[m]||d[m]||i;return r?n.createElement(f,a(a({ref:t},u),{},{components:r})):n.createElement(f,a({ref:t},u))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[l]="string"==typeof e?e:o,a[1]=s;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},7172:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:9},a="QR Codes",s={unversionedId:"settings/experiments/qrcodes",id:"settings/experiments/qrcodes",title:"QR Codes",description:"This documentation page is a stub. You can help by expanding it.",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/qrcodes.md",sourceDirName:"settings/experiments",slug:"/settings/experiments/qrcodes",permalink:"/it/docs/settings/experiments/qrcodes",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/settings/experiments/qrcodes.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{sidebar_position:9},sidebar:"tutorialSidebar",previous:{title:"Formattazione messaggio",permalink:"/it/docs/settings/experiments/message-formatting"},next:{title:"Tor",permalink:"/it/docs/tor"}},c={},p=[],u={toc:p},l="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"qr-codes"},"QR Codes"),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"This documentation page is a stub. You can help by ",(0,o.kt)("a",{parentName:"p",href:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im"},"expanding it"),".")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fad3d52b.713a3fa8.js b/build-staging/it/assets/js/fad3d52b.713a3fa8.js new file mode 100644 index 00000000..28a67dc5 --- /dev/null +++ b/build-staging/it/assets/js/fad3d52b.713a3fa8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[5003],{203:a=>{a.exports=JSON.parse('{"label":"autobindings","permalink":"/it/blog/tags/autobindings","allTagsPath":"/it/blog/tags","count":2}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fb3c1916.37c9304f.js b/build-staging/it/assets/js/fb3c1916.37c9304f.js new file mode 100644 index 00000000..0ec8228c --- /dev/null +++ b/build-staging/it/assets/js/fb3c1916.37c9304f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[276],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),s=p(r),f=o,b=s["".concat(l,".").concat(f)]||s[f]||d[f]||i;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},8886:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:1},a="Introduction to Cwtch Development",c={unversionedId:"intro",id:"intro",title:"Introduction to Cwtch Development",description:"- Core Concepts",source:"@site/developing/intro.md",sourceDirName:".",slug:"/intro",permalink:"/it/developing/intro",draft:!1,tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Release and Packaging Process",permalink:"/it/developing/release"}},l={},p=[{value:"Contributing to Cwtch Core",id:"contributing-to-cwtch-core",level:2},{value:"Building Cwtch Bots",id:"building-cwtch-bots",level:2}],u={toc:p},s="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introduction-to-cwtch-development"},"Introduction to Cwtch Development"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/core-concepts"},"Core Concepts")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/security/intro"},"Security Handbook"))),(0,o.kt)("h2",{id:"contributing-to-cwtch-core"},"Contributing to Cwtch Core"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/release"},"Release and Packaging Process"))),(0,o.kt)("h2",{id:"building-cwtch-bots"},"Building Cwtch Bots"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/intro#choosing-a-cwtch-library"},"Choosing a Library")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/developing/building-a-cwtch-app/building-an-echobot"},"Echobot Tutorial"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fc999220.ea2cb007.js b/build-staging/it/assets/js/fc999220.ea2cb007.js new file mode 100644 index 00000000..fa8191d6 --- /dev/null +++ b/build-staging/it/assets/js/fc999220.ea2cb007.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3224],{1298:e=>{e.exports=JSON.parse('{"title":"Servers","slug":"/category/servers","permalink":"/it/docs/category/servers","navigation":{"previous":{"title":"Gestire i server","permalink":"/it/docs/groups/manage-known-servers"},"next":{"title":"Introduzione ai server","permalink":"/it/docs/servers/introduction"}}}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fccc5d20.09b8e29a.js b/build-staging/it/assets/js/fccc5d20.09b8e29a.js new file mode 100644 index 00000000..8c3ae88a --- /dev/null +++ b/build-staging/it/assets/js/fccc5d20.09b8e29a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[3056],{4765:e=>{e.exports=JSON.parse('{"permalink":"/it/blog/tags/testing","page":1,"postsPerPage":10,"totalPages":1,"totalCount":2,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fd27e325.a240efeb.js b/build-staging/it/assets/js/fd27e325.a240efeb.js new file mode 100644 index 00000000..2b4b98a6 --- /dev/null +++ b/build-staging/it/assets/js/fd27e325.a240efeb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1199],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function a(e,t){if(null==e)return{};var n,o,r=function(e,t){if(null==e)return{};var n,o,r={},i=Object.keys(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o<i.length;o++)n=i[o],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=o.createContext({}),l=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p=function(e){var t=l(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),u=l(n),m=r,d=u["".concat(s,".").concat(m)]||u[m]||h[m]||i;return n?o.createElement(d,c(c({ref:t},p),{},{components:n})):o.createElement(d,c({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,c=new Array(i);c[0]=m;var a={};for(var s in t)hasOwnProperty.call(t,s)&&(a[s]=t[s]);a.originalType=e,a[u]="string"==typeof e?e:r,c[1]=a;for(var l=2;l<i;l++)c[l]=n[l];return o.createElement.apply(null,c)}return o.createElement.apply(null,n)}m.displayName="MDXCreateElement"},9327:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(7462),r=(n(7294),n(3905));const i={sidebar_position:3},c="Building a Cwtch Echobot",a={unversionedId:"building-a-cwtch-app/building-an-echobot",id:"building-a-cwtch-app/building-an-echobot",title:"Building a Cwtch Echobot",description:"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.",source:"@site/developing/building-a-cwtch-app/building-an-echobot.md",sourceDirName:"building-a-cwtch-app",slug:"/building-a-cwtch-app/building-an-echobot",permalink:"/it/developing/building-a-cwtch-app/building-an-echobot",draft:!1,tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Core Concepts",permalink:"/it/developing/building-a-cwtch-app/core-concepts"}},s={},l=[{value:"Using CwtchBot (Go)",id:"using-cwtchbot-go",level:2},{value:"Using Imp (Rust)",id:"using-imp-rust",level:2}],p={toc:l},u="wrapper";function h(e){let{components:t,...n}=e;return(0,r.kt)(u,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"building-a-cwtch-echobot"},"Building a Cwtch Echobot"),(0,r.kt)("p",null,"In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent."),(0,r.kt)("p",null,"For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or\nframework."),(0,r.kt)("h2",{id:"using-cwtchbot-go"},"Using CwtchBot (Go)"),(0,r.kt)("admonition",{title:"CwtchBot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the CwtchBot framework.")),(0,r.kt)("p",null,"Start by creating a new Go project, and a file ",(0,r.kt)("inlineCode",{parentName:"p"},"main.go"),". In the ",(0,r.kt)("inlineCode",{parentName:"p"},"main")," function:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'package main\n\nimport (\n "cwtch.im/cwtch/event"\n "cwtch.im/cwtch/model"\n "cwtch.im/cwtch/model/attr"\n "cwtch.im/cwtch/model/constants"\n "fmt"\n "git.openprivacy.ca/sarah/cwtchbot"\n _ "github.com/mutecomm/go-sqlcipher/v4"\n "os/user"\n "path"\n)\n\nfunc main() {\n user, _ := user.Current()\n cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")\n cwtchbot.Launch()\n\n // Set Some Profile Information\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")\n cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")\n\n fmt.Printf("echobot address: %v\\n", cwtchbot.Peer.GetOnion())\n\n for {\n message := cwtchbot.Queue.Next()\n cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])\n switch message.EventType {\n case event.NewMessageFromPeer:\n msg := cwtchbot.UnpackMessage(message.Data[event.Data])\n fmt.Printf("Message: %v\\n", msg)\n reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n case event.ContactCreated:\n fmt.Printf("Auto approving stranger %v %v\\n", cid, message.Data[event.RemotePeer])\n // accept the stranger as a new contact\n cwtchbot.Peer.AcceptConversation(cid.ID)\n // Send Hello...\n reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))\n cwtchbot.Peer.SendMessage(cid.ID, reply)\n }\n }\n}\n')),(0,r.kt)("h2",{id:"using-imp-rust"},"Using Imp (Rust)"),(0,r.kt)("admonition",{title:"Imp (Rust) Bot Framework",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-go"},'use std::borrow::BorrowMut;\nuse std::thread;\nuse chrono::{DateTime, FixedOffset};\nuse libcwtch;\nuse libcwtch::CwtchLib;\nuse libcwtch::structs::*;\nuse libcwtch::event::*;\nuse cwtch_imp::imp;\nuse cwtch_imp::behaviour::*;\nuse cwtch_imp::imp::Imp;\n\nconst BOT_HOME: &str = "~/.cwtch/bots/echobot";\nconst BOT_NAME: &str = "echobot";\n\nstruct Echobot {}\n\nfn main() {\n let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();\n let event_loop_handle = thread::spawn(move || {\n let mut echobot = Echobot {};\n let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());\n bot.event_loop::<Echobot>(echobot.borrow_mut());\n });\n event_loop_handle.join().expect("Error running event loop");\n}\n\nimpl imp::EventHandler for Echobot {\n fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {\n let response = Message {\n o: MessageType::TextMessage,\n d: message.d,\n };\n cwtch.send_message(&profile.profile_id, conversation_id, &response);\n }\n\n fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {\n match event {\n Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {\n println!(\n "\\n***** {} at {} *****\\n",\n name, profile_id.as_str()\n );\n }\n _ => (),\n };\n }\n}\n')))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fe1dd7ae.158f4574.js b/build-staging/it/assets/js/fe1dd7ae.158f4574.js new file mode 100644 index 00000000..0b392db7 --- /dev/null +++ b/build-staging/it/assets/js/fe1dd7ae.158f4574.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[1979],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>u});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,a,n=function(e,t){if(null==e)return{};var r,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),p=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},h="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),h=p(r),m=n,u=h["".concat(l,".").concat(m)]||h[m]||g[m]||o;return r?a.createElement(u,i(i({ref:t},s),{},{components:r})):a.createElement(u,i({ref:t},s))}));function u(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[h]="string"==typeof e?e:n,i[1]=c;for(var p=2;p<o;p++)i[p]=r[p];return a.createElement.apply(null,i)}return a.createElement.apply(null,r)}m.displayName="MDXCreateElement"},1501:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var a=r(7462),n=(r(7294),r(3905));const o={title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg"}]},i=void 0,c={permalink:"/it/blog/cwtch-nightly-v.11-74",source:"@site/blog/2023-06-07-new-nightly.md",title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",date:"2023-06-07T00:00:00.000Z",formattedDate:"7 giugno 2023",tags:[{label:"cwtch",permalink:"/it/blog/tags/cwtch"},{label:"cwtch-stable",permalink:"/it/blog/tags/cwtch-stable"},{label:"developer-documentation",permalink:"/it/blog/tags/developer-documentation"}],readingTime:1.845,hasTruncateMarker:!0,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}],frontMatter:{title:"New Cwtch Nightly (v1.11.0-74-g0406)",description:"In this development log we take a look at the new Cwtch Nightly",slug:"cwtch-nightly-v.11-74",tags:["cwtch","cwtch-stable","developer-documentation"],image:"/img/devlog10_small.png",hide_table_of_contents:!1,toc_max_heading_level:4,authors:[{name:"Sarah Jamie Lewis",title:"Executive Director, Open Privacy Research Society",image_url:"/img/sarah.jpg",imageURL:"/img/sarah.jpg"}]},prevItem:{title:"Cwtch Beta 1.12",permalink:"/it/blog/cwtch-nightly-1-12"},nextItem:{title:"Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.",permalink:"/it/blog/cwtch-developer-documentation"}},l={authorsImageUrls:[void 0]},p=[],s={toc:p},h="wrapper";function g(e){let{components:t,...o}=e;return(0,n.kt)(h,(0,a.Z)({},s,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing."),(0,n.kt)("p",null,"As a reminder, the Open Privacy Research Society have ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/discreet-log/38-march-2023/"},"also announced they are want to raise $60,000 in 2023")," to help move forward projects like Cwtch. Please help support projects like ours with a ",(0,n.kt)("a",{parentName:"p",href:"https://openprivacy.ca/donate"},"one-off donations")," or ",(0,n.kt)("a",{parentName:"p",href:"https://www.patreon.com/openprivacy"},"recurring support via Patreon"),"."),(0,n.kt)("p",null,(0,n.kt)("img",{src:r(9964).Z,width:"1005",height:"481"})))}g.isMDXComponent=!0},9964:(e,t,r)=>{r.d(t,{Z:()=>a});const a=r.p+"assets/images/devlog10-160dd00841ab18c4fc41da81e8c6c133.png"}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/fe910059.ad535d04.js b/build-staging/it/assets/js/fe910059.ad535d04.js new file mode 100644 index 00000000..886f32a2 --- /dev/null +++ b/build-staging/it/assets/js/fe910059.ad535d04.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[27],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,d=u["".concat(l,".").concat(m)]||u[m]||f[m]||i;return r?n.createElement(d,a(a({ref:t},s),{},{components:r})):n.createElement(d,a({ref:t},s))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},9457:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i={sidebar_position:2},a="Cambiare il tuo nome visualizzato",c={unversionedId:"profiles/change-name",id:"profiles/change-name",title:"Cambiare il tuo nome visualizzato",description:"1. Nel men\xfa Gestisci profili, premi la matita accanto al profilo che vuoi modificare",source:"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/change-name.md",sourceDirName:"profiles",slug:"/profiles/change-name",permalink:"/it/docs/profiles/change-name",draft:!1,editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/docs/profiles/change-name.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Creare un nuovo profilo",permalink:"/it/docs/profiles/create-a-profile"},next:{title:"Modificare la tua password",permalink:"/it/docs/profiles/change-password"}},l={},p=[],s={toc:p},u="wrapper";function f(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"cambiare-il-tuo-nome-visualizzato"},"Cambiare il tuo nome visualizzato"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Nel men\xfa Gestisci profili, premi la matita accanto al profilo che vuoi modificare"),(0,o.kt)("li",{parentName:"ol"},"Modifica il tuo nome"),(0,o.kt)("li",{parentName:"ol"},"Clicca su salva il profilo")))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/main.d3acbaba.js b/build-staging/it/assets/js/main.d3acbaba.js new file mode 100644 index 00000000..1f73cb86 --- /dev/null +++ b/build-staging/it/assets/js/main.d3acbaba.js @@ -0,0 +1,2 @@ +/*! For license information please see main.d3acbaba.js.LICENSE.txt */ +(self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),l=n(6887);const s={"010d07c1":[()=>n.e(8838).then(n.bind(n,9090)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/manage-known-servers.md",9090],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,1223)),"@theme/BlogTagsListPage",1223],"02cf6bb5":[()=>n.e(9051).then(n.bind(n,7215)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/introduction.md",7215],"043d4691":[()=>n.e(7275).then(n.t.bind(n,4402,19)),"~docs/docs-security/category-itsecurity-tutorialsidebar-category-cwtch-140.json",4402],"07eed749":[()=>n.e(9010).then(n.bind(n,2833)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/overlays.md",2833],"08c34551":[()=>n.e(9717).then(n.t.bind(n,7723,19)),"~docs/default/category-itdocs-tutorialsidebar-category-platforms-889.json",7723],"08c3bd78":[()=>n.e(4986).then(n.bind(n,9992)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/introduction.md",9992],"0999b6aa":[()=>n.e(3949).then(n.t.bind(n,4165,19)),"~blog/default/it-blog-tags-repliqate-144.json",4165],"0a2b8ac2":[()=>n.e(3674).then(n.t.bind(n,2549,19)),"~blog/default/it-blog-archive-d3a.json",2549],"0b5b83c5":[()=>n.e(9207).then(n.bind(n,8914)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/profile-info.md",8914],"0bb12077":[()=>n.e(8697).then(n.t.bind(n,6735,19)),"~blog/default/it-blog-tags-cwtch-stable-a69-list.json",6735],"0d59ece6":[()=>n.e(5490).then(n.t.bind(n,8731,19)),"~docs/docs-security/category-itsecurity-tutorialsidebar-category-connectivity-tor-662.json",8731],"0d64c1d9":[()=>n.e(8710).then(n.bind(n,9133)),"@site/blog/2023-01-20-reproducible-builds-bindings.md",9133],"0fb199c9":[()=>n.e(5221).then(n.bind(n,2061)),"@site/i18n/it/docusaurus-plugin-content-docs/current/platforms/tails.md",2061],"115541e2":[()=>n.e(2450).then(n.bind(n,4864)),"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/edit-server.md",4864],"11796dfe":[()=>n.e(2033).then(n.t.bind(n,5761,19)),"~blog/default/it-blog-tags-release-360.json",5761],"13965eb4":[()=>n.e(80).then(n.bind(n,1734)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/behaviour/notification-policy.md",1734],"141cdfa9":[()=>n.e(7293).then(n.bind(n,677)),"@site/blog/2023-04-06-availability-and-profile-attributes.md?truncated=true",677],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],"1578504c":[()=>n.e(3693).then(n.t.bind(n,7542,19)),"~docs/docs-security/category-itsecurity-tutorialsidebar-category-cwtch-ui-73a.json",7542],17896441:[()=>Promise.all([n.e(532),n.e(9785),n.e(7918)]).then(n.bind(n,5154)),"@theme/DocItem",5154],"18b4904d":[()=>n.e(1322).then(n.bind(n,4810)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/add-contact.md",4810],"19563afa":[()=>n.e(3185).then(n.bind(n,6647)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/references.md",6647],"19cde8ec":[()=>n.e(5552).then(n.bind(n,5054)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/leave-group.md",5054],"1a25c548":[()=>n.e(5732).then(n.bind(n,1202)),"@site/blog/2023-01-06-path-to-cwtch-stable.md?truncated=true",1202],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1cbfc7c5":[()=>n.e(3712).then(n.t.bind(n,1879,19)),"~blog/default/it-blog-tags-release-360-list.json",1879],"1d0a8d89":[()=>n.e(6711).then(n.bind(n,539)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/conversation-settings.md",539],"1ebd8798":[()=>n.e(4788).then(n.bind(n,5558)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md?truncated=true",5558],"209bdfc3":[()=>n.e(2537).then(n.t.bind(n,4520,19)),"~blog/default/it-blog-tags-documentation-529.json",4520],"21d06810":[()=>n.e(7621).then(n.bind(n,4241)),"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/developing.md",4241],"231a229c":[()=>n.e(2348).then(n.bind(n,1608)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/share-file.md",1608],"247a7af4":[()=>n.e(8070).then(n.t.bind(n,4196,19)),"~blog/default/it-blog-tags-reproducible-builds-6dd-list.json",4196],"2887095c":[()=>n.e(621).then(n.bind(n,5369)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/send-invite.md",5369],"29659bc8":[()=>n.e(6266).then(n.bind(n,3308)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/unblock-contact.md",3308],"298daba3":[()=>n.e(8573).then(n.bind(n,4937)),"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/translate.md",4937],"2c10bcf6":[()=>n.e(2397).then(n.t.bind(n,9355,19)),"~blog/default/it-blog-tags-security-handbook-8ab.json",9355],"2c901dd2":[()=>n.e(5314).then(n.t.bind(n,2255,19)),"~blog/default/it-blog-tags-api-744.json",2255],"2ffad701":[()=>n.e(785).then(n.bind(n,1180)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/group-experiment.md",1180],"34843fbe":[()=>n.e(6940).then(n.t.bind(n,1403,19)),"~docs/docs-security/category-itsecurity-tutorialsidebar-category-cwtch-components-d86.json",1403],"3a109bd3":[()=>n.e(7782).then(n.bind(n,877)),"@site/blog/2023-03-10-cwtch-documentation.md?truncated=true",877],"3b7b256a":[()=>n.e(4867).then(n.t.bind(n,2504,19)),"~blog/default/it-blog-tags-libcwtch-998.json",2504],"3b87f7a6":[()=>n.e(2135).then(n.t.bind(n,982,19)),"~docs/docs-security/category-itsecurity-tutorialsidebar-category-tapir-9cd.json",982],"3bc00383":[()=>n.e(9481).then(n.bind(n,4788)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/behaviour/block-unknown-connections.md",4788],"3bf835b2":[()=>n.e(4862).then(n.bind(n,2603)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/exporting-profile.md",2603],"3bf8c048":[()=>n.e(8371).then(n.bind(n,9427)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/delete-profile.md",9427],"3d43f565":[()=>n.e(4239).then(n.t.bind(n,9470,19)),"~docs/default/category-itdocs-tutorialsidebar-category-contribuisci-05f.json",9470],"3db42865":[()=>n.e(7139).then(n.t.bind(n,3769,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"3e80d710":[()=>n.e(2723).then(n.t.bind(n,7760,19)),"~blog/default/it-blog-tags-cwtch-stable-page-2-658.json",7760],"43b107c1":[()=>n.e(9200).then(n.bind(n,1168)),"@site/blog/2023-02-03-cwtch-testing-i.md",1168],"45a7c7c6":[()=>n.e(9251).then(n.bind(n,2073)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/server-hosting.md",2073],"46b0c109":[()=>n.e(5583).then(n.bind(n,8878)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/availability-status.md",8878],"47db09cd":[()=>n.e(6891).then(n.bind(n,1778)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/streamer-mode.md",1778],"49b07f50":[()=>n.e(6318).then(n.bind(n,0)),"@site/i18n/it/docusaurus-plugin-content-docs/current/intro.md",0],"4aa555c3":[()=>n.e(7797).then(n.bind(n,3449)),"@site/blog/2023-06-16-cwtch-1.12.md?truncated=true",3449],"4d27f429":[()=>n.e(788).then(n.bind(n,7362)),"@site/blog/2023-01-20-reproducible-builds-bindings.md?truncated=true",7362],"4f68bcc6":[()=>n.e(3516).then(n.t.bind(n,4289,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-security/plugin-route-context-module-100.json",4289],"508409b4":[()=>n.e(3171).then(n.bind(n,5863)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/importing-a-profile.md",5863],"53cc4802":[()=>n.e(7594).then(n.bind(n,3109)),"@site/blog/2023-02-03-cwtch-testing-i.md?truncated=true",3109],"553c6794":[()=>n.e(8185).then(n.bind(n,4466)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/message_formats.md",4466],"56ee2ea4":[()=>n.e(9195).then(n.bind(n,7959)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/block-contact.md",7959],"57d795a6":[()=>n.e(6735).then(n.bind(n,805)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/deployment.md",805],"59e122e4":[()=>n.e(6299).then(n.t.bind(n,86,19)),"~blog/default/it-blog-tags-testing-9c6.json",86],"5ae3487b":[()=>n.e(9507).then(n.t.bind(n,6271,19)),"~blog/default/it-blog-page-2-e9b.json",6271],"5beee875":[()=>n.e(9444).then(n.bind(n,2724)),"@site/blog/2023-06-07-new-nightly.md",2724],"5cb298ca":[()=>n.e(2909).then(n.bind(n,4673)),"@site/blog/2023-04-28-developer-docs.md?truncated=true",4673],"5dc151e9":[()=>n.e(923).then(n.bind(n,2320)),"@site/developing/release.md",2320],"5e5faacc":[()=>n.e(8192).then(n.bind(n,9655)),"@site/blog/2023-01-27-platform-support.md",9655],"5e9927d2":[()=>n.e(5398).then(n.bind(n,8526)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/unlock-profile.md",8526],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],61794344:[()=>n.e(6232).then(n.bind(n,4669)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md",4669],"6275ceb4":[()=>n.e(6555).then(n.bind(n,248)),"@site/blog/2023-03-10-cwtch-documentation.md",248],"644e0e81":[()=>n.e(4561).then(n.bind(n,4367)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/image_previews.md",4367],"6648656d":[()=>n.e(3026).then(n.t.bind(n,2490,19)),"~docs/default/category-itdocs-tutorialsidebar-category-conversations-1c9.json",2490],"66f0cf59":[()=>n.e(3588).then(n.t.bind(n,6331,19)),"~docs/default/category-itdocs-tutorialsidebar-category-getting-started-585.json",6331],"6875c492":[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"68c206b4":[()=>n.e(3936).then(n.bind(n,3549)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/light-dark-mode.md",3549],"6a78f460":[()=>n.e(439).then(n.bind(n,2982)),"@site/blog/2023-04-06-availability-and-profile-attributes.md",2982],"6b44a42a":[()=>n.e(4071).then(n.t.bind(n,4642,19)),"~blog/default/it-blog-tags-cwtch-stable-a69.json",4642],"6c4339db":[()=>n.e(8795).then(n.t.bind(n,6705,19)),"~blog/default/it-blog-tags-security-handbook-8ab-list.json",6705],"6e2435dc":[()=>n.e(5861).then(n.bind(n,9745)),"@site/i18n/it/docusaurus-plugin-content-docs/current/tor.md",9745],"7246b934":[()=>n.e(6730).then(n.t.bind(n,3364,19)),"~blog/default/it-blog-tags-cwtch-a37-list.json",3364],"73c8cde5":[()=>n.e(2605).then(n.bind(n,7127)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/image-previews-and-profile-pictures.md",7127],"794fc1e8":[()=>n.e(2111).then(n.t.bind(n,4205,19)),"~blog/default/it-blog-tags-tags-3c3.json",4205],"7a06dbff":[()=>n.e(3905).then(n.t.bind(n,4040,19)),"~docs/default/category-itdocs-tutorialsidebar-category-experiments-c32.json",4040],"7c6e9bc2":[()=>n.e(8254).then(n.bind(n,2419)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/intro.md",2419],"7f5e9c41":[()=>n.e(2234).then(n.t.bind(n,9369,19)),"~blog/default/it-blog-tags-api-744-list.json",9369],"8051e978":[()=>n.e(6325).then(n.t.bind(n,846,19)),"~blog/default/it-blog-tags-cwtch-page-2-4c8-list.json",846],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],"824a28c6":[()=>n.e(5905).then(n.bind(n,9347)),"@site/developing/building-a-cwtch-app/intro.md",9347],"8281c315":[()=>n.e(2861).then(n.bind(n,1205)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/change-language.md",1205],83643414:[()=>n.e(6098).then(n.t.bind(n,6946,19)),"~docs/default/category-itdocs-tutorialsidebar-category-groups-9ac.json",6946],"876f085b":[()=>n.e(9645).then(n.t.bind(n,239,19)),"~docs/default/category-itdocs-tutorialsidebar-category-aspetto-3eb.json",239],"8838b5d9":[()=>n.e(9239).then(n.t.bind(n,3177,19)),"~docs/default/category-itdocs-tutorialsidebar-category-impostazioni-96a.json",3177],"88d0c547":[()=>n.e(2081).then(n.bind(n,418)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/intro.md",418],"8918cacc":[()=>n.e(8907).then(n.bind(n,3190)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/message-formatting.md",3190],"89f86a37":[()=>n.e(9759).then(n.bind(n,9366)),"@site/blog/2023-03-29-cwtch-1.11.md?truncated=true",9366],"8a8a5858":[()=>n.e(1739).then(n.t.bind(n,5717,19)),"~blog/default/it-blog-tags-cwtch-page-2-4c8.json",5717],"8aa5d230":[()=>n.e(9516).then(n.bind(n,2330)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/server.md",2330],"8d811565":[()=>n.e(3587).then(n.t.bind(n,302,19)),"~docs/docs-developer/category-itdeveloping-tutorialsidebar-category-building-a-cwtch-app-7e4.json",302],"8e3a693e":[()=>n.e(7970).then(n.bind(n,8840)),"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/unlock-server.md",8840],"8e8114dc":[()=>n.e(9923).then(n.t.bind(n,1809,19)),"~blog/default/it-blog-tags-developer-documentation-c2a.json",1809],"8fe7a387":[()=>n.e(5233).then(n.bind(n,9667)),"@site/blog/2023-03-03-autobindings-optional-experiments.md",9667],"9009e554":[()=>n.e(1871).then(n.t.bind(n,7202,19)),"~blog/default/it-blog-tags-planning-f1e-list.json",7202],"9034063a":[()=>n.e(1602).then(n.t.bind(n,2430,19)),"~blog/default/it-blog-tags-libcwtch-998-list.json",2430],"9148c1ad":[()=>n.e(9477).then(n.bind(n,7248)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/appearance/ui-columns.md",7248],"917f768f":[()=>n.e(1210).then(n.bind(n,1328)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/tapir/authentication_protocol.md",1328],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"937969ee":[()=>n.e(854).then(n.t.bind(n,2959,19)),"~blog/default/it-blog-tags-planning-f1e.json",2959],"97ac6d59":[()=>n.e(6758).then(n.bind(n,4124)),"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/share-key.md",4124],"98bd2791":[()=>n.e(8909).then(n.t.bind(n,6058,19)),"~blog/default/it-blog-tags-repliqate-144-list.json",6058],"9944c673":[()=>n.e(6457).then(n.bind(n,3832)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/risk.md",3832],"9947de33":[()=>n.e(8098).then(n.bind(n,7771)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/input.md",7771],"9b12a270":[()=>n.e(9249).then(n.bind(n,9816)),"@site/blog/2023-02-10-android-reproducibility.md",9816],"9dd8190d":[()=>n.e(2688).then(n.bind(n,7561)),"@site/blog/2023-02-24-autogenerating-cwtch-bindings.md",7561],"9e2a7473":[()=>n.e(1258).then(n.bind(n,8725)),"@site/blog/2023-01-13-cwtch-stable-api-design.md",8725],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],"9f1c7621":[()=>n.e(1312).then(n.bind(n,4387)),"@site/blog/2023-02-17-cwtch-testing-ii.md",4387],a02b4022:[()=>n.e(3492).then(n.bind(n,4889)),"@site/blog/2023-06-16-cwtch-1.12.md",4889],a4396826:[()=>n.e(5089).then(n.bind(n,3760)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/accept-group-invite.md",3760],a65a3c47:[()=>n.e(7591).then(n.bind(n,5432)),"@site/blog/2023-04-28-developer-docs.md",5432],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(3089)]).then(n.bind(n,46)),"@theme/BlogListPage",46],a79c88c2:[()=>n.e(9976).then(n.bind(n,8553)),"@site/blog/2023-01-13-cwtch-stable-api-design.md?truncated=true",8553],a7e50e09:[()=>n.e(3763).then(n.t.bind(n,4698,19)),"~blog/default/it-blog-tags-bindings-b84.json",4698],a8875a35:[()=>n.e(8801).then(n.bind(n,5023)),"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/documentation.md",5023],a8c7fdc6:[()=>n.e(4108).then(n.t.bind(n,6454,19)),"~docs/docs-security/version-current-metadata-prop-751.json",6454],adfd2a96:[()=>n.e(4268).then(n.bind(n,2700)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/edit-group-name.md",2700],ae271b89:[()=>n.e(7977).then(n.t.bind(n,3296,19)),"~docs/default/category-itdocs-tutorialsidebar-category-comportamento-25d.json",3296],af23c5f9:[()=>n.e(3218).then(n.bind(n,4958)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md",4958],af2ce9b1:[()=>n.e(5391).then(n.bind(n,1574)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/key_bundles.md",1574],b0404c31:[()=>n.e(7860).then(n.bind(n,3478)),"@site/blog/2023-01-06-path-to-cwtch-stable.md",3478],b11de5d5:[()=>n.e(3417).then(n.t.bind(n,1368,19)),"~docs/default/category-itdocs-tutorialsidebar-category-profili-999.json",1368],b125d866:[()=>n.e(8799).then(n.bind(n,1595)),"@site/blog/2023-06-30-cwtch-stable-roadmap-update.md?truncated=true",1595],b29d9412:[()=>n.e(8848).then(n.bind(n,509)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/change-password.md",509],b2a64359:[()=>n.e(1006).then(n.bind(n,7470)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/connectivity/intro.md",7470],b331d16d:[()=>n.e(8237).then(n.t.bind(n,1244,19)),"~blog/default/it-blog-tags-cwtch-stable-page-2-658-list.json",1244],b51a5363:[()=>n.e(1814).then(n.t.bind(n,6704,19)),"~blog/default/it-blog-tags-cwtch-a37.json",6704],b58c7628:[()=>n.e(8590).then(n.bind(n,74)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/save-conversation-history.md",74],b74cf248:[()=>n.e(3319).then(n.bind(n,9798)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/introduction.md",9798],b8ae7715:[()=>n.e(8239).then(n.bind(n,9889)),"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/create-server.md",9889],b979d7e4:[()=>n.e(360).then(n.t.bind(n,9266,19)),"~blog/default/it-blog-tags-support-f4c-list.json",9266],ba6ec3d2:[()=>n.e(9737).then(n.t.bind(n,9254,19)),"~blog/default/it-blog-tags-reproducible-builds-6dd.json",9254],bc51653d:[()=>n.e(818).then(n.bind(n,592)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/share-address-with-friends.md",592],bf059cf9:[()=>n.e(5273).then(n.bind(n,2626)),"@site/blog/2023-02-10-android-reproducibility.md?truncated=true",2626],c14f15fd:[()=>n.e(7649).then(n.bind(n,3071)),"@site/developing/building-a-cwtch-app/core-concepts.md",3071],c3b86ae0:[()=>n.e(3007).then(n.t.bind(n,6464,19)),"~blog/default/it-blog-tags-autobindings-89e-list.json",6464],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,3261)),"@site/src/pages/index.js",3261],c50453d6:[()=>n.e(9284).then(n.bind(n,4991)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/tapir/packet_format.md",4991],c5a58ca1:[()=>n.e(5194).then(n.t.bind(n,9825,19)),"~blog/default/it-blog-tags-bindings-b84-list.json",9825],c747432f:[()=>n.e(8835).then(n.bind(n,2090)),"@site/blog/2023-03-03-autobindings-optional-experiments.md?truncated=true",2090],c94c4dfb:[()=>n.e(9146).then(n.t.bind(n,4469,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],c96c5262:[()=>n.e(3761).then(n.bind(n,5426)),"@site/blog/2023-03-29-cwtch-1.11.md",5426],c9f9ad20:[()=>n.e(5540).then(n.bind(n,8522)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/reply-to-message.md",8522],cbb0e45e:[()=>n.e(8789).then(n.bind(n,3017)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/file-sharing.md",3017],ccc49370:[()=>Promise.all([n.e(532),n.e(9785),n.e(6048),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],d1fa313c:[()=>n.e(9427).then(n.bind(n,8676)),"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/testing.md",8676],d228e678:[()=>n.e(9798).then(n.t.bind(n,5353,19)),"~blog/default/it-blog-tags-developer-documentation-c2a-list.json",5353],d5f314f9:[()=>n.e(5869).then(n.t.bind(n,9317,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-docs/docs-developer/plugin-route-context-module-100.json",9317],d634637f:[()=>n.e(7241).then(n.t.bind(n,1248,19)),"~blog/default/it-blog-tags-documentation-529-list.json",1248],d78ab406:[()=>n.e(9506).then(n.bind(n,8978)),"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/introduction.md",8978],dabb1858:[()=>n.e(877).then(n.bind(n,3639)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ui/android.md",3639],ddf22f37:[()=>n.e(1155).then(n.bind(n,2732)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/delete-contact.md",2732],dfb11b4d:[()=>n.e(7430).then(n.t.bind(n,8729,19)),"~blog/default/it-blog-tags-nightly-177.json",8729],e2032214:[()=>n.e(2411).then(n.bind(n,7332)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/accept-deny-new-conversation.md",7332],e31178cb:[()=>n.e(9661).then(n.bind(n,4933)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/change-profile-image.md",4933],e759f958:[()=>n.e(1384).then(n.bind(n,3962)),"@site/i18n/it/docusaurus-plugin-content-docs/current/servers/delete-server.md",3962],e83cebc7:[()=>n.e(7541).then(n.bind(n,1407)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/behaviour/notification-content.md",1407],e88d32a9:[()=>n.e(6585).then(n.t.bind(n,5745,19)),"/home/sarah/PARA/projects/docs.cwtch.im/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],ecbb35df:[()=>n.e(2469).then(n.t.bind(n,9012,19)),"~blog/default/it-blog-tags-support-f4c.json",9012],ef02fbbd:[()=>n.e(9565).then(n.bind(n,1772)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/create-group.md",1772],ef6f692b:[()=>n.e(1950).then(n.bind(n,618)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/ecosystem-overview.md",618],ef71f686:[()=>n.e(2481).then(n.bind(n,299)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/development.md",299],ef78badf:[()=>n.e(5532).then(n.bind(n,5481)),"@site/blog/2023-01-27-platform-support.md?truncated=true",5481],f041e880:[()=>n.e(5226).then(n.bind(n,3291)),"@site/blog/2023-03-31-cwtch-stable-roadmap-update.md?truncated=true",3291],f04f0ec9:[()=>n.e(4508).then(n.bind(n,9431)),"@site/i18n/it/docusaurus-plugin-content-docs/current/chat/message-formatting.md",9431],f21fe67f:[()=>n.e(48).then(n.bind(n,5493)),"@site/i18n/it/docusaurus-plugin-content-docs-docs-security/current/components/cwtch/groups.md",5493],f2d017e0:[()=>n.e(981).then(n.bind(n,8382)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/clickable-links.md",8382],f4279852:[()=>n.e(9902).then(n.t.bind(n,5391,19)),"~blog/default/it-blog-70b.json",5391],f748f255:[()=>n.e(8181).then(n.bind(n,5525)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/create-a-profile.md",5525],f76a3b8e:[()=>n.e(2184).then(n.bind(n,3103)),"@site/blog/2023-02-17-cwtch-testing-ii.md?truncated=true",3103],f7ca86a6:[()=>n.e(4612).then(n.bind(n,172)),"@site/i18n/it/docusaurus-plugin-content-docs/current/contribute/stickers.md",172],f894db60:[()=>n.e(2436).then(n.bind(n,8981)),"@site/i18n/it/docusaurus-plugin-content-docs/current/getting-started/supported_platforms.md",8981],f928e8d9:[()=>n.e(8786).then(n.t.bind(n,7160,19)),"~docs/docs-developer/version-current-metadata-prop-751.json",7160],f9b019e0:[()=>n.e(225).then(n.bind(n,9495)),"@site/i18n/it/docusaurus-plugin-content-docs/current/groups/introduction.md",9495],f9cff38b:[()=>n.e(1932).then(n.t.bind(n,6601,19)),"~blog/default/it-blog-tags-nightly-177-list.json",6601],fa088e0f:[()=>n.e(9399).then(n.bind(n,7172)),"@site/i18n/it/docusaurus-plugin-content-docs/current/settings/experiments/qrcodes.md",7172],fad3d52b:[()=>n.e(5003).then(n.t.bind(n,203,19)),"~blog/default/it-blog-tags-autobindings-89e.json",203],fb3c1916:[()=>n.e(276).then(n.bind(n,8886)),"@site/developing/intro.md",8886],fc999220:[()=>n.e(3224).then(n.t.bind(n,1298,19)),"~docs/default/category-itdocs-tutorialsidebar-category-servers-889.json",1298],fccc5d20:[()=>n.e(3056).then(n.t.bind(n,4765,19)),"~blog/default/it-blog-tags-testing-9c6-list.json",4765],fd27e325:[()=>n.e(1199).then(n.bind(n,9327)),"@site/developing/building-a-cwtch-app/building-an-echobot.md",9327],fe1dd7ae:[()=>n.e(1979).then(n.bind(n,1501)),"@site/blog/2023-06-07-new-nightly.md?truncated=true",1501],fe910059:[()=>n.e(27).then(n.bind(n,9457)),"@site/i18n/it/docusaurus-plugin-content-docs/current/profiles/change-name.md",9457]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],p={},f=[],m=[],g=(0,u.Z)(o);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=s[n];r&&(p[t]=r[0],f.push(r[1]),m.push(r[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const f=[{path:"/it/blog",component:p("/it/blog","779"),exact:!0},{path:"/it/blog/archive",component:p("/it/blog/archive","da9"),exact:!0},{path:"/it/blog/autobindings",component:p("/it/blog/autobindings","2f1"),exact:!0},{path:"/it/blog/autobindings-ii",component:p("/it/blog/autobindings-ii","291"),exact:!0},{path:"/it/blog/availability-status-profile-attributes",component:p("/it/blog/availability-status-profile-attributes","1ab"),exact:!0},{path:"/it/blog/cwtch-android-reproducibility",component:p("/it/blog/cwtch-android-reproducibility","526"),exact:!0},{path:"/it/blog/cwtch-bindings-reproducible",component:p("/it/blog/cwtch-bindings-reproducible","879"),exact:!0},{path:"/it/blog/cwtch-developer-documentation",component:p("/it/blog/cwtch-developer-documentation","22a"),exact:!0},{path:"/it/blog/cwtch-documentation",component:p("/it/blog/cwtch-documentation","129"),exact:!0},{path:"/it/blog/cwtch-nightly-1-11",component:p("/it/blog/cwtch-nightly-1-11","781"),exact:!0},{path:"/it/blog/cwtch-nightly-1-12",component:p("/it/blog/cwtch-nightly-1-12","9d1"),exact:!0},{path:"/it/blog/cwtch-nightly-v.11-74",component:p("/it/blog/cwtch-nightly-v.11-74","491"),exact:!0},{path:"/it/blog/cwtch-platform-support",component:p("/it/blog/cwtch-platform-support","164"),exact:!0},{path:"/it/blog/cwtch-stable-api-design",component:p("/it/blog/cwtch-stable-api-design","6c8"),exact:!0},{path:"/it/blog/cwtch-stable-roadmap-update",component:p("/it/blog/cwtch-stable-roadmap-update","794"),exact:!0},{path:"/it/blog/cwtch-stable-roadmap-update-june",component:p("/it/blog/cwtch-stable-roadmap-update-june","8cc"),exact:!0},{path:"/it/blog/cwtch-testing-i",component:p("/it/blog/cwtch-testing-i","c23"),exact:!0},{path:"/it/blog/cwtch-testing-ii",component:p("/it/blog/cwtch-testing-ii","d98"),exact:!0},{path:"/it/blog/page/2",component:p("/it/blog/page/2","dbd"),exact:!0},{path:"/it/blog/path-to-cwtch-stable",component:p("/it/blog/path-to-cwtch-stable","b83"),exact:!0},{path:"/it/blog/tags",component:p("/it/blog/tags","c5b"),exact:!0},{path:"/it/blog/tags/api",component:p("/it/blog/tags/api","e1b"),exact:!0},{path:"/it/blog/tags/autobindings",component:p("/it/blog/tags/autobindings","642"),exact:!0},{path:"/it/blog/tags/bindings",component:p("/it/blog/tags/bindings","ebf"),exact:!0},{path:"/it/blog/tags/cwtch",component:p("/it/blog/tags/cwtch","a84"),exact:!0},{path:"/it/blog/tags/cwtch-stable",component:p("/it/blog/tags/cwtch-stable","c87"),exact:!0},{path:"/it/blog/tags/cwtch-stable/page/2",component:p("/it/blog/tags/cwtch-stable/page/2","1e4"),exact:!0},{path:"/it/blog/tags/cwtch/page/2",component:p("/it/blog/tags/cwtch/page/2","54a"),exact:!0},{path:"/it/blog/tags/developer-documentation",component:p("/it/blog/tags/developer-documentation","c25"),exact:!0},{path:"/it/blog/tags/documentation",component:p("/it/blog/tags/documentation","897"),exact:!0},{path:"/it/blog/tags/libcwtch",component:p("/it/blog/tags/libcwtch","74c"),exact:!0},{path:"/it/blog/tags/nightly",component:p("/it/blog/tags/nightly","f8e"),exact:!0},{path:"/it/blog/tags/planning",component:p("/it/blog/tags/planning","918"),exact:!0},{path:"/it/blog/tags/release",component:p("/it/blog/tags/release","a5e"),exact:!0},{path:"/it/blog/tags/repliqate",component:p("/it/blog/tags/repliqate","967"),exact:!0},{path:"/it/blog/tags/reproducible-builds",component:p("/it/blog/tags/reproducible-builds","f52"),exact:!0},{path:"/it/blog/tags/security-handbook",component:p("/it/blog/tags/security-handbook","036"),exact:!0},{path:"/it/blog/tags/support",component:p("/it/blog/tags/support","872"),exact:!0},{path:"/it/blog/tags/testing",component:p("/it/blog/tags/testing","479"),exact:!0},{path:"/it/developing",component:p("/it/developing","724"),routes:[{path:"/it/developing/building-a-cwtch-app/building-an-echobot",component:p("/it/developing/building-a-cwtch-app/building-an-echobot","923"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/developing/building-a-cwtch-app/core-concepts",component:p("/it/developing/building-a-cwtch-app/core-concepts","a62"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/developing/building-a-cwtch-app/intro",component:p("/it/developing/building-a-cwtch-app/intro","702"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/developing/category/building-a-cwtch-app",component:p("/it/developing/category/building-a-cwtch-app","2e1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/developing/intro",component:p("/it/developing/intro","040"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/developing/release",component:p("/it/developing/release","429"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/it/docs",component:p("/it/docs","969"),routes:[{path:"/it/docs/category/appearance",component:p("/it/docs/category/appearance","225"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/behaviour",component:p("/it/docs/category/behaviour","638"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/contribute",component:p("/it/docs/category/contribute","8ef"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/conversations",component:p("/it/docs/category/conversations","c6e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/experiments",component:p("/it/docs/category/experiments","1ac"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/getting-started",component:p("/it/docs/category/getting-started","643"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/groups",component:p("/it/docs/category/groups","71d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/platforms",component:p("/it/docs/category/platforms","725"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/profiles",component:p("/it/docs/category/profiles","e2c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/servers",component:p("/it/docs/category/servers","465"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/category/settings",component:p("/it/docs/category/settings","1de"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/accept-deny-new-conversation",component:p("/it/docs/chat/accept-deny-new-conversation","7f0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/add-contact",component:p("/it/docs/chat/add-contact","a11"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/block-contact",component:p("/it/docs/chat/block-contact","5d2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/conversation-settings",component:p("/it/docs/chat/conversation-settings","3a2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/delete-contact",component:p("/it/docs/chat/delete-contact","072"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/introduction",component:p("/it/docs/chat/introduction","b74"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/message-formatting",component:p("/it/docs/chat/message-formatting","354"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/reply-to-message",component:p("/it/docs/chat/reply-to-message","3d0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/save-conversation-history",component:p("/it/docs/chat/save-conversation-history","d56"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/share-address-with-friends",component:p("/it/docs/chat/share-address-with-friends","d95"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/share-file",component:p("/it/docs/chat/share-file","482"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/chat/unblock-contact",component:p("/it/docs/chat/unblock-contact","1dd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/contribute/developing",component:p("/it/docs/contribute/developing","d9f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/contribute/documentation",component:p("/it/docs/contribute/documentation","fc4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/contribute/stickers",component:p("/it/docs/contribute/stickers","ac2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/contribute/testing",component:p("/it/docs/contribute/testing","57e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/contribute/translate",component:p("/it/docs/contribute/translate","402"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/getting-started/supported_platforms",component:p("/it/docs/getting-started/supported_platforms","d14"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/accept-group-invite",component:p("/it/docs/groups/accept-group-invite","c81"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/create-group",component:p("/it/docs/groups/create-group","50a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/edit-group-name",component:p("/it/docs/groups/edit-group-name","7a8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/introduction",component:p("/it/docs/groups/introduction","7f0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/leave-group",component:p("/it/docs/groups/leave-group","490"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/manage-known-servers",component:p("/it/docs/groups/manage-known-servers","704"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/groups/send-invite",component:p("/it/docs/groups/send-invite","8ec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/intro",component:p("/it/docs/intro","bda"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/platforms/tails",component:p("/it/docs/platforms/tails","264"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/availability-status",component:p("/it/docs/profiles/availability-status","dd7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/change-name",component:p("/it/docs/profiles/change-name","6c6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/change-password",component:p("/it/docs/profiles/change-password","8fa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/change-profile-image",component:p("/it/docs/profiles/change-profile-image","c17"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/create-a-profile",component:p("/it/docs/profiles/create-a-profile","1c8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/delete-profile",component:p("/it/docs/profiles/delete-profile","c89"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/exporting-profile",component:p("/it/docs/profiles/exporting-profile","6d7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/importing-a-profile",component:p("/it/docs/profiles/importing-a-profile","6ec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/introduction",component:p("/it/docs/profiles/introduction","55f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/profile-info",component:p("/it/docs/profiles/profile-info","d3a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/profiles/unlock-profile",component:p("/it/docs/profiles/unlock-profile","bc1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/servers/create-server",component:p("/it/docs/servers/create-server","7cf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/servers/delete-server",component:p("/it/docs/servers/delete-server","cea"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/servers/edit-server",component:p("/it/docs/servers/edit-server","ae8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/servers/introduction",component:p("/it/docs/servers/introduction","271"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/servers/share-key",component:p("/it/docs/servers/share-key","f89"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/servers/unlock-server",component:p("/it/docs/servers/unlock-server","252"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/appearance/change-language",component:p("/it/docs/settings/appearance/change-language","102"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/appearance/light-dark-mode",component:p("/it/docs/settings/appearance/light-dark-mode","05f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/appearance/streamer-mode",component:p("/it/docs/settings/appearance/streamer-mode","4af"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/appearance/ui-columns",component:p("/it/docs/settings/appearance/ui-columns","f68"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/behaviour/block-unknown-connections",component:p("/it/docs/settings/behaviour/block-unknown-connections","7f7"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/behaviour/notification-content",component:p("/it/docs/settings/behaviour/notification-content","eec"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/behaviour/notification-policy",component:p("/it/docs/settings/behaviour/notification-policy","c4a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/clickable-links",component:p("/it/docs/settings/experiments/clickable-links","dc3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/file-sharing",component:p("/it/docs/settings/experiments/file-sharing","52a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/group-experiment",component:p("/it/docs/settings/experiments/group-experiment","b2e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/image-previews-and-profile-pictures",component:p("/it/docs/settings/experiments/image-previews-and-profile-pictures","1e9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/message-formatting",component:p("/it/docs/settings/experiments/message-formatting","86c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/qrcodes",component:p("/it/docs/settings/experiments/qrcodes","537"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/experiments/server-hosting",component:p("/it/docs/settings/experiments/server-hosting","358"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/settings/introduction",component:p("/it/docs/settings/introduction","219"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/docs/tor",component:p("/it/docs/tor","960"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/it/security",component:p("/it/security","2ae"),routes:[{path:"/it/security/category/connectivity--tor",component:p("/it/security/category/connectivity--tor","5fe"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/category/cwtch",component:p("/it/security/category/cwtch","301"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/category/cwtch-components",component:p("/it/security/category/cwtch-components","3bc"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/category/cwtch-ui",component:p("/it/security/category/cwtch-ui","de2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/category/tapir",component:p("/it/security/category/tapir","c7d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/connectivity/intro",component:p("/it/security/components/connectivity/intro","30f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/cwtch/groups",component:p("/it/security/components/cwtch/groups","ca5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/cwtch/key_bundles",component:p("/it/security/components/cwtch/key_bundles","8c3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/cwtch/message_formats",component:p("/it/security/components/cwtch/message_formats","711"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/cwtch/server",component:p("/it/security/components/cwtch/server","645"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/ecosystem-overview",component:p("/it/security/components/ecosystem-overview","fdd"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/intro",component:p("/it/security/components/intro","b59"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/tapir/authentication_protocol",component:p("/it/security/components/tapir/authentication_protocol","189"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/tapir/packet_format",component:p("/it/security/components/tapir/packet_format","3b0"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/ui/android",component:p("/it/security/components/ui/android","906"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/ui/image_previews",component:p("/it/security/components/ui/image_previews","a95"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/ui/input",component:p("/it/security/components/ui/input","53e"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/components/ui/overlays",component:p("/it/security/components/ui/overlays","b2a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/deployment",component:p("/it/security/deployment","291"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/development",component:p("/it/security/development","04c"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/intro",component:p("/it/security/intro","e21"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/references",component:p("/it/security/references","889"),exact:!0,sidebar:"tutorialSidebar"},{path:"/it/security/risk",component:p("/it/security/risk","bcb"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/it/",component:p("/it/","e32"),exact:!0},{path:"*",component:p("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var f=n(7462),m=n(5742),g=n(2263),h=n(4996),b=n(6668),v=n(1944),y=n(4711),w=n(9727),k=n(3320),S=n(197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),a=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,u.TH)();return e+(0,h.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function x(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(_,null),r.createElement(E,null),r.createElement(S.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,f.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),A=n(8940);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const a=s.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const R=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),P("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function N(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),N(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(R,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const I=O,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",j="__docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${j}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n var suggestionContainer = document.getElementById('${j}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function z(){const{siteConfig:{baseUrl:e}}=(0,g.Z)();return(0,r.useLayoutEffect)((()=>{window[F]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:D}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(z,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,g.Z)(),i=(0,h.Z)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var q=n(4763);function G(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(q.Z,null,r.createElement(A.M,null,r.createElement(L.t,null,r.createElement(p,null,r.createElement($,null),r.createElement(x,null),r.createElement(U,null),r.createElement(I,{location:T(t)},e)))))}var H=n(6887);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var V=n(9670);const W=new Set,Y=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!K()&&!Y.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(H).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!Y.has(e))(e)&&(Y.add(e),N(e))},X=Object.freeze(Q);if(l.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;N(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(G,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"docs-security":{"path":"/it/security","versions":[{"name":"current","label":"Next","isLast":true,"path":"/it/security","mainDocId":"intro","docs":[{"id":"components/connectivity/intro","path":"/it/security/components/connectivity/intro","sidebar":"tutorialSidebar"},{"id":"components/cwtch/groups","path":"/it/security/components/cwtch/groups","sidebar":"tutorialSidebar"},{"id":"components/cwtch/key_bundles","path":"/it/security/components/cwtch/key_bundles","sidebar":"tutorialSidebar"},{"id":"components/cwtch/message_formats","path":"/it/security/components/cwtch/message_formats","sidebar":"tutorialSidebar"},{"id":"components/cwtch/server","path":"/it/security/components/cwtch/server","sidebar":"tutorialSidebar"},{"id":"components/ecosystem-overview","path":"/it/security/components/ecosystem-overview","sidebar":"tutorialSidebar"},{"id":"components/intro","path":"/it/security/components/intro","sidebar":"tutorialSidebar"},{"id":"components/tapir/authentication_protocol","path":"/it/security/components/tapir/authentication_protocol","sidebar":"tutorialSidebar"},{"id":"components/tapir/packet_format","path":"/it/security/components/tapir/packet_format","sidebar":"tutorialSidebar"},{"id":"components/ui/android","path":"/it/security/components/ui/android","sidebar":"tutorialSidebar"},{"id":"components/ui/image_previews","path":"/it/security/components/ui/image_previews","sidebar":"tutorialSidebar"},{"id":"components/ui/input","path":"/it/security/components/ui/input","sidebar":"tutorialSidebar"},{"id":"components/ui/overlays","path":"/it/security/components/ui/overlays","sidebar":"tutorialSidebar"},{"id":"deployment","path":"/it/security/deployment","sidebar":"tutorialSidebar"},{"id":"development","path":"/it/security/development","sidebar":"tutorialSidebar"},{"id":"intro","path":"/it/security/intro","sidebar":"tutorialSidebar"},{"id":"references","path":"/it/security/references","sidebar":"tutorialSidebar"},{"id":"risk","path":"/it/security/risk","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-components","path":"/it/security/category/cwtch-components","sidebar":"tutorialSidebar"},{"id":"/category/connectivity--tor","path":"/it/security/category/connectivity--tor","sidebar":"tutorialSidebar"},{"id":"/category/tapir","path":"/it/security/category/tapir","sidebar":"tutorialSidebar"},{"id":"/category/cwtch","path":"/it/security/category/cwtch","sidebar":"tutorialSidebar"},{"id":"/category/cwtch-ui","path":"/it/security/category/cwtch-ui","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/it/security/intro","label":"intro"}}}}],"breadcrumbs":true},"default":{"path":"/it/docs","versions":[{"name":"current","label":"Avanti","isLast":true,"path":"/it/docs","mainDocId":"intro","docs":[{"id":"chat/accept-deny-new-conversation","path":"/it/docs/chat/accept-deny-new-conversation","sidebar":"tutorialSidebar"},{"id":"chat/add-contact","path":"/it/docs/chat/add-contact","sidebar":"tutorialSidebar"},{"id":"chat/block-contact","path":"/it/docs/chat/block-contact","sidebar":"tutorialSidebar"},{"id":"chat/conversation-settings","path":"/it/docs/chat/conversation-settings","sidebar":"tutorialSidebar"},{"id":"chat/delete-contact","path":"/it/docs/chat/delete-contact","sidebar":"tutorialSidebar"},{"id":"chat/introduction","path":"/it/docs/chat/introduction","sidebar":"tutorialSidebar"},{"id":"chat/message-formatting","path":"/it/docs/chat/message-formatting","sidebar":"tutorialSidebar"},{"id":"chat/reply-to-message","path":"/it/docs/chat/reply-to-message","sidebar":"tutorialSidebar"},{"id":"chat/save-conversation-history","path":"/it/docs/chat/save-conversation-history","sidebar":"tutorialSidebar"},{"id":"chat/share-address-with-friends","path":"/it/docs/chat/share-address-with-friends","sidebar":"tutorialSidebar"},{"id":"chat/share-file","path":"/it/docs/chat/share-file","sidebar":"tutorialSidebar"},{"id":"chat/unblock-contact","path":"/it/docs/chat/unblock-contact","sidebar":"tutorialSidebar"},{"id":"contribute/developing","path":"/it/docs/contribute/developing","sidebar":"tutorialSidebar"},{"id":"contribute/documentation","path":"/it/docs/contribute/documentation","sidebar":"tutorialSidebar"},{"id":"contribute/stickers","path":"/it/docs/contribute/stickers","sidebar":"tutorialSidebar"},{"id":"contribute/testing","path":"/it/docs/contribute/testing","sidebar":"tutorialSidebar"},{"id":"contribute/translate","path":"/it/docs/contribute/translate","sidebar":"tutorialSidebar"},{"id":"getting-started/supported_platforms","path":"/it/docs/getting-started/supported_platforms","sidebar":"tutorialSidebar"},{"id":"groups/accept-group-invite","path":"/it/docs/groups/accept-group-invite","sidebar":"tutorialSidebar"},{"id":"groups/create-group","path":"/it/docs/groups/create-group","sidebar":"tutorialSidebar"},{"id":"groups/edit-group-name","path":"/it/docs/groups/edit-group-name","sidebar":"tutorialSidebar"},{"id":"groups/introduction","path":"/it/docs/groups/introduction","sidebar":"tutorialSidebar"},{"id":"groups/leave-group","path":"/it/docs/groups/leave-group","sidebar":"tutorialSidebar"},{"id":"groups/manage-known-servers","path":"/it/docs/groups/manage-known-servers","sidebar":"tutorialSidebar"},{"id":"groups/send-invite","path":"/it/docs/groups/send-invite","sidebar":"tutorialSidebar"},{"id":"intro","path":"/it/docs/intro","sidebar":"tutorialSidebar"},{"id":"platforms/tails","path":"/it/docs/platforms/tails","sidebar":"tutorialSidebar"},{"id":"profiles/availability-status","path":"/it/docs/profiles/availability-status","sidebar":"tutorialSidebar"},{"id":"profiles/change-name","path":"/it/docs/profiles/change-name","sidebar":"tutorialSidebar"},{"id":"profiles/change-password","path":"/it/docs/profiles/change-password","sidebar":"tutorialSidebar"},{"id":"profiles/change-profile-image","path":"/it/docs/profiles/change-profile-image","sidebar":"tutorialSidebar"},{"id":"profiles/create-a-profile","path":"/it/docs/profiles/create-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/delete-profile","path":"/it/docs/profiles/delete-profile","sidebar":"tutorialSidebar"},{"id":"profiles/exporting-profile","path":"/it/docs/profiles/exporting-profile","sidebar":"tutorialSidebar"},{"id":"profiles/importing-a-profile","path":"/it/docs/profiles/importing-a-profile","sidebar":"tutorialSidebar"},{"id":"profiles/introduction","path":"/it/docs/profiles/introduction","sidebar":"tutorialSidebar"},{"id":"profiles/profile-info","path":"/it/docs/profiles/profile-info","sidebar":"tutorialSidebar"},{"id":"profiles/unlock-profile","path":"/it/docs/profiles/unlock-profile","sidebar":"tutorialSidebar"},{"id":"servers/create-server","path":"/it/docs/servers/create-server","sidebar":"tutorialSidebar"},{"id":"servers/delete-server","path":"/it/docs/servers/delete-server","sidebar":"tutorialSidebar"},{"id":"servers/edit-server","path":"/it/docs/servers/edit-server","sidebar":"tutorialSidebar"},{"id":"servers/introduction","path":"/it/docs/servers/introduction","sidebar":"tutorialSidebar"},{"id":"servers/share-key","path":"/it/docs/servers/share-key","sidebar":"tutorialSidebar"},{"id":"servers/unlock-server","path":"/it/docs/servers/unlock-server","sidebar":"tutorialSidebar"},{"id":"settings/appearance/change-language","path":"/it/docs/settings/appearance/change-language","sidebar":"tutorialSidebar"},{"id":"settings/appearance/light-dark-mode","path":"/it/docs/settings/appearance/light-dark-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/streamer-mode","path":"/it/docs/settings/appearance/streamer-mode","sidebar":"tutorialSidebar"},{"id":"settings/appearance/ui-columns","path":"/it/docs/settings/appearance/ui-columns","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/block-unknown-connections","path":"/it/docs/settings/behaviour/block-unknown-connections","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-content","path":"/it/docs/settings/behaviour/notification-content","sidebar":"tutorialSidebar"},{"id":"settings/behaviour/notification-policy","path":"/it/docs/settings/behaviour/notification-policy","sidebar":"tutorialSidebar"},{"id":"settings/experiments/clickable-links","path":"/it/docs/settings/experiments/clickable-links","sidebar":"tutorialSidebar"},{"id":"settings/experiments/file-sharing","path":"/it/docs/settings/experiments/file-sharing","sidebar":"tutorialSidebar"},{"id":"settings/experiments/group-experiment","path":"/it/docs/settings/experiments/group-experiment","sidebar":"tutorialSidebar"},{"id":"settings/experiments/image-previews-and-profile-pictures","path":"/it/docs/settings/experiments/image-previews-and-profile-pictures","sidebar":"tutorialSidebar"},{"id":"settings/experiments/message-formatting","path":"/it/docs/settings/experiments/message-formatting","sidebar":"tutorialSidebar"},{"id":"settings/experiments/qrcodes","path":"/it/docs/settings/experiments/qrcodes","sidebar":"tutorialSidebar"},{"id":"settings/experiments/server-hosting","path":"/it/docs/settings/experiments/server-hosting","sidebar":"tutorialSidebar"},{"id":"settings/introduction","path":"/it/docs/settings/introduction","sidebar":"tutorialSidebar"},{"id":"tor","path":"/it/docs/tor","sidebar":"tutorialSidebar"},{"id":"/category/getting-started","path":"/it/docs/category/getting-started","sidebar":"tutorialSidebar"},{"id":"/category/profiles","path":"/it/docs/category/profiles","sidebar":"tutorialSidebar"},{"id":"/category/conversations","path":"/it/docs/category/conversations","sidebar":"tutorialSidebar"},{"id":"/category/groups","path":"/it/docs/category/groups","sidebar":"tutorialSidebar"},{"id":"/category/servers","path":"/it/docs/category/servers","sidebar":"tutorialSidebar"},{"id":"/category/settings","path":"/it/docs/category/settings","sidebar":"tutorialSidebar"},{"id":"/category/appearance","path":"/it/docs/category/appearance","sidebar":"tutorialSidebar"},{"id":"/category/behaviour","path":"/it/docs/category/behaviour","sidebar":"tutorialSidebar"},{"id":"/category/experiments","path":"/it/docs/category/experiments","sidebar":"tutorialSidebar"},{"id":"/category/contribute","path":"/it/docs/category/contribute","sidebar":"tutorialSidebar"},{"id":"/category/platforms","path":"/it/docs/category/platforms","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/it/docs/intro","label":"intro"}}}}],"breadcrumbs":true},"docs-developer":{"path":"/it/developing","versions":[{"name":"current","label":"Next","isLast":true,"path":"/it/developing","mainDocId":"intro","docs":[{"id":"building-a-cwtch-app/building-an-echobot","path":"/it/developing/building-a-cwtch-app/building-an-echobot","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/core-concepts","path":"/it/developing/building-a-cwtch-app/core-concepts","sidebar":"tutorialSidebar"},{"id":"building-a-cwtch-app/intro","path":"/it/developing/building-a-cwtch-app/intro","sidebar":"tutorialSidebar"},{"id":"intro","path":"/it/developing/intro","sidebar":"tutorialSidebar"},{"id":"release","path":"/it/developing/release","sidebar":"tutorialSidebar"},{"id":"/category/building-a-cwtch-app","path":"/it/developing/category/building-a-cwtch-app","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/it/developing/intro","label":"intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en","es","de","it"],"path":"i18n","currentLocale":"it","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"},"es":{"label":"Espa\xf1ol","direction":"ltr","htmlLang":"es","calendar":"gregory","path":"es"},"de":{"label":"Deutsch","direction":"ltr","htmlLang":"de","calendar":"gregory","path":"de"},"it":{"label":"Italiano","direction":"ltr","htmlLang":"it","calendar":"gregory","path":"it"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"}}}'),c={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(412),o=n(5742),i=n(8780),l=n(7961);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(p,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),l=n(2263),s=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}});var d=n(4996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,l.Z)(),{withBaseUrl:k}=(0,d.C)(),S=(0,a.useContext)(u),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const _=p||f;const x=(0,s.Z)(_),C=_?.replace("pathname://","");let T=void 0!==C?(L=C,b&&(e=>e.startsWith("/"))(L)?k(L):L):void 0;var L;T&&x&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const A=(0,a.useRef)(!1),P=n?o.OL:o.rU,R=c.Z.canUseIntersectionObserver,N=(0,a.useRef)(),O=()=>{A.current||null==T||(window.docusaurus.preload(T),A.current=!0)};(0,a.useEffect)((()=>(!R&&x&&null!=T&&window.docusaurus.prefetch(T),()=>{R&&N.current&&N.current.disconnect()})),[N,T,R,x]);const I=T?.startsWith("#")??!1,D=!T||!x||I;return D||h||S.collectLink(T),D?a.createElement("a",(0,r.Z)({ref:E,href:T},_&&!x&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(P,(0,r.Z)({},v,{onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,R&&e&&x&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T},n&&{isActive:g,activeClassName:m}))}const f=a.forwardRef(p)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>g,gA:()=>p,_r:()=>u,Jo:()=>h,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7961:(e,t,n)=>{"use strict";n.d(t,{Z:()=>dt});var r=n(7294),a=n(6010),o=n(4763),i=n(1944),l=n(7462),s=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??m,{containerRef:n,onClick:a}=f();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:`#${d}`,onClick:a}),t))}var h=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(g,{className:v.skipToContent})}var w=n(6668),k=n(9689);function S(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...s}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},s),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const E={closeButton:"closeButton_CVFx"};function _(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",E.closeButton,e.className)}),r.createElement(S,{width:14,height:14,strokeWidth:3.1}))}const x={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(x.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(_,{onClick:n,className:T.announcementBarClose}))}var A=n(2961),P=n(2466);var R=n(902),N=n(3102);const O=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,N.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,R.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(O.Provider,{value:n},t)}function D(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(O);if(!e)throw new R.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:D(o)})),[a,o,t])}function j(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var F=n(2949),B=n(2389);function z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const l=(0,B.Z)(),s=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!l&&$.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const G=r.memo(q),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,F.I)();return a?null:r.createElement(G,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return r.createElement(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,A.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(S,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(Y,null))}var Q=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:s,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,X.Z)(a),f=(0,X.Z)(t),m=(0,X.Z)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,J.Z)(o),h=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,g&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(Q.Z,(0,l.Z)({href:u?m:o},d,h)):r.createElement(Q.Z,(0,l.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},d,h))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),le=n(8596),se=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,l.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},s,{onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),s.children??s.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(_e,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[u,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":p})},r.createElement(ne,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>r.createElement(_e,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var fe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ge="iconLanguage_nlXk";var he=n(1875);const be={searchBox:"searchBox_ZlJk"};function ve(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,be.searchBox)},t)}var ye=n(143),we=n(2802);var ke=n(373);const Se=e=>e.docs.find((t=>t.id===e.mainDocId));const Ee={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,se.Z)(),p=(0,fe.l)(),{search:f,hash:m}=(0,s.TH)(),g=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(pe,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:ge}),h),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(ve,{className:n},r.createElement(he.Z,null))},dropdown:pe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.vY)(t,a);return null===s?null:r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===s.path||!!i?.sidebar&&i.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,we.lO)(a)[0],s=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,l.Z)({},o,{label:s,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:p}=(0,s.TH)(),f=(0,ye.Iw)(n),m=(0,ye.gB)(n),{savePreferredVersionName:g}=(0,ke.J)(n),h=[...o,...m.map((e=>{const t=f.alternateDocVersions[e.name]??Se(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>g(e.name)}})),...i],b=(0,we.lO)(n)[0],v=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:Se(b).path;return h.length<=1?r.createElement(oe,(0,l.Z)({},u,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(pe,(0,l.Z)({},u,{mobile:t,label:v,to:y,items:h,isActive:a?()=>!1:void 0}))}};function _e(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ee[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function xe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(_e,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ce(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Te(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ce,{onClick:()=>t.hide()}),t.content)}function Le(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(j,{header:r.createElement(K,null),primaryMenu:r.createElement(xe,null),secondaryMenu:r.createElement(Te,null)}):null}const Ae={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Re(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(a.current)return void(a.current=!1);const l=r?.scrollY,s=document.documentElement.scrollHeight-o.current,c=window.innerHeight;l&&i>=l?n(!1):i+c<s&&n(!0)})),(0,u.S)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Ae.navbarHideable,!s&&Ae.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Pe,{onClick:i.toggle}),r.createElement(Le,null))}var Ne=n(8780);const Oe={errorBoundaryError:"errorBoundaryError_a6uf"};function Ie(e){return r.createElement("button",(0,l.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function De(e){let{error:t}=e;const n=(0,Ne.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:Oe.errorBoundaryError},n)}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const je="right";function Fe(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Be(){const{toggle:e,shown:t}=(0,A.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Fe,null))}const ze={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Me,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(_e,e)))))}function $e(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function qe(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??je)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement($e,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(Be,null),r.createElement(W,null),r.createElement(Ue,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ue,{items:a}),r.createElement(Z,{className:ze.colorModeToggle}),!o&&r.createElement(ve,null,r.createElement(he.Z,null)))})}function Ge(){return r.createElement(Re,null,r.createElement(qe,null))}function He(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...s}=t,c=(0,X.Z)(n),u=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Q.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},s),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function Ze(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(He,{item:t}))}function Ve(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Ze,{key:t,item:e})))))}function We(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Ve,{key:t,column:e}))))}function Ye(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Ke(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(He,{item:t})}function Qe(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Ke,{item:e}),t.length!==n+1&&r.createElement(Ye,null))))))}function Xe(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(We,{columns:t}):r.createElement(Qe,{links:t})}var Je=n(941);const et={footerLogoLink:"footerLogoLink_BH7S"};function tt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Je.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function nt(e){let{logo:t}=e;return t.href?r.createElement(Q.Z,{href:t.href,className:et.footerLogoLink,target:t.target},r.createElement(tt,{logo:t})):r.createElement(tt,{logo:t})}function rt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function ot(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(at,{style:o,links:n&&n.length>0&&r.createElement(Xe,{links:n}),logo:a&&r.createElement(nt,{logo:a}),copyright:t&&r.createElement(rt,{copyright:t})})}const it=r.memo(ot),lt=(0,R.Qc)([F.S,k.pl,P.OC,ke.L5,i.VC,function(e){let{children:t}=e;return r.createElement(N.n2,null,r.createElement(A.M,null,r.createElement(I,null,t)))}]);function st(e){let{children:t}=e;return r.createElement(lt,null,t)}function ct(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Ie,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(De,{error:t})))))}const ut={mainWrapper:"mainWrapper_z2l0"};function dt(e){const{children:t,noFooter:n,wrapperClassName:l,title:s,description:c}=e;return(0,b.t)(),r.createElement(st,null,r.createElement(i.d,{title:s,description:c}),r.createElement(y,null),r.createElement(L,null),r.createElement(Ge,null),r.createElement("div",{id:d,className:(0,a.Z)(h.k.wrapper.main,ut.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(ct,e)},t)),!n&&r.createElement(it,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),l=n(2263),s=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},l=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.Z)(),{navbar:{title:n,logo:c}}=(0,s.L)(),{imageClassName:d,titleClassName:p,...f}=e,m=(0,i.Z)(c?.href||"/"),g=n?"":t,h=c?.alt??g;return a.createElement(o.Z,(0,r.Z)({to:m},f,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:h,imageClassName:d}),null!=n&&a.createElement("b",{className:p},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),l=n(2949);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,l.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,f.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(s.themedImage,s[`themedImage--${e}`],u)},p)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>h});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const l="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?c:u}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const c=(0,a.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:s?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:l},r)}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:l})):null}function h(e){let{lazy:t,...n}=e;const r=t?g:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>f});var r=n(7294),a=n(2389),o=n(12),i=n(902),l=n(6668);const s=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===s.get(),d=e=>s.set(String(e)),p=r.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(p.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),l=n(6668);const s=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},p=e=>e===d.dark?d.dark:d.light,f=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{u.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(f(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>h});var r=n(7294),a=n(143),o=n(9935),i=n(6668),l=n(2802),s=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(f.Provider,{value:n},t)}function h(e){let{children:t}=e;return l.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(f);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t,version:n}=e;return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(null===e)throw new a.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),l=(n(1688),n(902));function s(e){!function(e){const t=(0,i.k6)(),n=(0,l.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=d();return r.createElement(u.Provider,{value:n},t)}function f(){const e=r.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function c(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>x,Wl:()=>m,_F:()=>v,cE:()=>p,jA:()=>g,xz:()=>f,hI:()=>_,lO:()=>k,vY:()=>E,oz:()=>S,s1:()=>w});var r=n(7294),a=n(6550),o=n(8790),i=n(143),l=n(373),s=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!i._r;function f(e){const t=(0,s.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=m(t);if(e)return e}}}function g(){const{pathname:e}=(0,a.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>v(e,t)));function v(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||b(e.items,t))}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function w(){const e=(0,c.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function S(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function E(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,l=i.find((e=>(0,a.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.H)(i),sidebarName:s,sidebarItems:c}}function x(e){return e.filter((e=>"category"!==e.type||!!m(e)))}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),c=n(2263);function u(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&r.createElement("meta",{property:"og:image",content:p}),p&&r.createElement("meta",{name:"twitter:image",content:p}),l)}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function f(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(p,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>s,i6:()=>l,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>s,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&a<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(a-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>s});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function s(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),l=o===n?e:e.replace(`/${o}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(a&&(a+=" "),a+=n);else for(t in e)e[t]&&(a&&(a+=" "),a+=t);return a}n.d(t,{Z:()=>a});const a=function(){for(var e,t,n=0,a="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(a&&(a+=" "),a+=t);return a}},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>f,PP:()=>L,Ep:()=>p});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r<a;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],l=e&&a(e),s=t&&a(t),c=l||s;if(e&&a(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=i.length;p>=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(2177);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function f(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var g=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",v="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),g||(0,l.Z)(!1);var t,n=window.history,a=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,c=i.forceRefresh,w=void 0!==c&&c,k=i.getUserConfirmation,S=void 0===k?h:k,E=i.keyLength,_=void 0===E?6:E,x=e.basename?d(s(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,a=window.location,o=a.pathname+a.search+a.hash;return x&&(o=u(o,x)),f(o,r,n)}function T(){return Math.random().toString(36).substr(2,_)}var L=m();function A(e){(0,r.Z)(U,e),U.length=n.length,L.notifyListeners(U.location,U.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||O(C(e.state))}function R(){O(C(y()))}var N=!1;function O(e){if(N)N=!1,A();else{L.confirmTransitionTo(e,"POP",S,(function(t){t?A({action:"POP",location:e}):function(e){var t=U.location,n=D.indexOf(t.key);-1===n&&(n=0);var r=D.indexOf(e.key);-1===r&&(r=0);var a=n-r;a&&(N=!0,j(a))}(e)}))}}var I=C(y()),D=[I.key];function M(e){return x+p(e)}function j(e){n.go(e)}var F=0;function B(e){1===(F+=e)&&1===e?(window.addEventListener(b,P),o&&window.addEventListener(v,R)):0===F&&(window.removeEventListener(b,P),o&&window.removeEventListener(v,R))}var z=!1;var U={length:n.length,action:"POP",location:I,createHref:M,push:function(e,t){var r="PUSH",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,l=o.state;if(a)if(n.pushState({key:i,state:l},null,t),w)window.location.href=t;else{var s=D.indexOf(U.location.key),c=D.slice(0,s+1);c.push(o.key),D=c,A({action:r,location:o})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,T(),U.location);L.confirmTransitionTo(o,r,S,(function(e){if(e){var t=M(o),i=o.key,l=o.state;if(a)if(n.replaceState({key:i,state:l},null,t),w)window.location.replace(t);else{var s=D.indexOf(U.location.key);-1!==s&&(D[s]=o.key),A({action:r,location:o})}else window.location.replace(t)}}))},go:j,goBack:function(){j(-1)},goForward:function(){j(1)},block:function(e){void 0===e&&(e=!1);var t=L.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=L.appendListener(e);return B(1),function(){B(-1),t()}}};return U}var k="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+c(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:c,decodePath:s},slash:{encodePath:s,decodePath:s}};function E(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function _(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function x(e){window.location.replace(E(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),g||(0,l.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),a=n.getUserConfirmation,o=void 0===a?h:a,i=n.hashType,c=void 0===i?"slash":i,b=e.basename?d(s(e.basename)):"",v=S[c],y=v.encodePath,w=v.decodePath;function C(){var e=w(_());return b&&(e=u(e,b)),f(e)}var T=m();function L(e){(0,r.Z)(z,e),z.length=t.length,T.notifyListeners(z.location,z.action)}var A=!1,P=null;function R(){var e,t,n=_(),r=y(n);if(n!==r)x(r);else{var a=C(),i=z.location;if(!A&&(t=a,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===p(a))return;P=null,function(e){if(A)A=!1,L();else{var t="POP";T.confirmTransitionTo(e,t,o,(function(n){n?L({action:t,location:e}):function(e){var t=z.location,n=D.lastIndexOf(p(t));-1===n&&(n=0);var r=D.lastIndexOf(p(e));-1===r&&(r=0);var a=n-r;a&&(A=!0,M(a))}(e)}))}}(a)}}var N=_(),O=y(N);N!==O&&x(O);var I=C(),D=[p(I)];function M(e){t.go(e)}var j=0;function F(e){1===(j+=e)&&1===e?window.addEventListener(k,R):0===j&&window.removeEventListener(k,R)}var B=!1;var z={length:t.length,action:"POP",location:I,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=E(window.location.href)),n+"#"+y(b+p(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);if(_()!==a){P=t,function(e){window.location.hash=e}(a);var o=D.lastIndexOf(p(z.location)),i=D.slice(0,o+1);i.push(t),D=i,L({action:n,location:r})}else L()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);T.confirmTransitionTo(r,n,o,(function(e){if(e){var t=p(r),a=y(b+t);_()!==a&&(P=t,x(a));var o=D.indexOf(p(z.location));-1!==o&&(D[o]=t),L({action:n,location:r})}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return B||(F(1),B=!0),function(){return B&&(B=!1,F(-1)),t()}},listen:function(e){var t=T.appendListener(e);return F(1),function(){F(-1),t()}}};return z}function T(e,t,n){return Math.min(Math.max(e,t),n)}function L(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,a=t.initialEntries,o=void 0===a?["/"]:a,i=t.initialIndex,l=void 0===i?0:i,s=t.keyLength,c=void 0===s?6:s,u=m();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function g(){return Math.random().toString(36).substr(2,c)}var h=T(l,0,o.length-1),b=o.map((function(e){return f(e,void 0,"string"==typeof e?g():e.key||g())})),v=p;function y(e){var t=T(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:v,push:function(e,t){var r="PUSH",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,g(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=f(n);a&&a!==m&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),g=s(n),h=0;h<i.length;++h){var b=i[h];if(!(o[b]||r&&r[b]||g&&g[b]||l&&l[b])){var v=p(n,b);try{c(t,b,v)}catch(y){}}}}return t}},1143:e=>{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function a(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&f(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s<arguments.length;s++){for(var c in o=Object(arguments[s]))n.call(o,c)&&(l[c]=o[c]);if(t){i=t(o);for(var u=0;u<i.length;u++)r.call(o,i[u])&&(l[i[u]]=o[i[u]])}}return l}},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=p;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],p=n[1],f=n.index;if(l+=e.slice(i,f),i=f+d.length,p)l+=p[1];else{var m=e[i],g=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=g&&null!=m&&m!==g,S="+"===y||"*"===y,E="?"===y||"*"===y,_=n[2]||u,x=b||v;r.push({name:h||o++,prefix:g||"",delimiter:_,optional:E,repeat:S,partial:k,asterisk:!!w,pattern:x?c(x):w?".*":"[^"+s(_)+"]+?"})}}return i<e.length&&(l+=e.substr(i)),l&&r.push(l),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function l(e,t){for(var n=new Array(e.length),a=0;a<e.length;a++)"object"==typeof e[a]&&(n[a]=new RegExp("^(?:"+e[a].pattern+")$",d(t)));return function(t,a){for(var o="",l=t||{},s=(a||{}).pretty?i:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=l[u.name];if(null==p){if(u.optional){u.partial&&(o+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(r(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=s(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):s(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');o+=u.prefix+d}}else o+=u}return o}}function s(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var a=(n=n||{}).strict,o=!1!==n.end,i="",l=0;l<e.length;l++){var c=e[l];if("string"==typeof c)i+=s(c);else{var p=s(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),i+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var m=s(n.delimiter||"/"),g=i.slice(-m.length)===m;return a||(i=(g?i.slice(0,-m.length):i)+"(?:"+m+"(?=$))?"),i+=o?"$":a&&g?"":"(?="+m+"|$)",u(new RegExp("^"+i,d(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],a=0;a<e.length;a++)r.push(f(e[a],t,n).source);return u(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},7410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var a,o;switch(n=n||{},r.util.type(t)){case"Object":if(o=r.util.objId(t),n[o])return n[o];for(var i in a={},n[o]=a,t)t.hasOwnProperty(i)&&(a[i]=e(t[i],n));return a;case"Array":return o=r.util.objId(t),n[o]?n[o]:(a=[],n[o]=a,t.forEach((function(t,r){a[r]=e(t,n)})),a);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var a in t)n[a]=t[a];return n},insertBefore:function(e,t,n,a){var o=(a=a||r.languages)[e],i={};for(var l in o)if(o.hasOwnProperty(l)){if(l==t)for(var s in n)n.hasOwnProperty(s)&&(i[s]=n[s]);n.hasOwnProperty(l)||(i[l]=o[l])}var c=a[e];return a[e]=i,r.languages.DFS(r.languages,(function(t,n){n===c&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,a,o){o=o||{};var i=r.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],a||l);var s=t[l],c=r.util.type(s);"Object"!==c||o[i(s)]?"Array"!==c||o[i(s)]||(o[i(s)]=!0,e(s,n,l,o)):(o[i(s)]=!0,e(s,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};return r.hooks.run("before-tokenize",o),o.tokens=r.tokenize(o.code,o.grammar),r.hooks.run("after-tokenize",o),a.stringify(r.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var a=new l;return s(a,a.head,e),i(e,a,t,a.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(a)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var a,o=0;a=n[o++];)a(t)}},Token:a};function a(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function o(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var o=a[1].length;a.index+=o,a[0]=a[0].slice(o)}return a}function i(e,t,n,l,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(d&&d.cause==p+","+m)return;var g=f[m],h=g.inside,b=!!g.lookbehind,v=!!g.greedy,y=g.alias;if(v&&!g.pattern.global){var w=g.pattern.toString().match(/[imsuy]*$/)[0];g.pattern=RegExp(g.pattern.source,w+"g")}for(var k=g.pattern||g,S=l.next,E=u;S!==t.tail&&!(d&&E>=d.reach);E+=S.value.length,S=S.next){var _=S.value;if(t.length>e.length)return;if(!(_ instanceof a)){var x,C=1;if(v){if(!(x=o(k,E,e,b))||x.index>=e.length)break;var T=x.index,L=x.index+x[0].length,A=E;for(A+=S.value.length;T>=A;)A+=(S=S.next).value.length;if(E=A-=S.value.length,S.value instanceof a)continue;for(var P=S;P!==t.tail&&(A<L||"string"==typeof P.value);P=P.next)C++,A+=P.value.length;C--,_=e.slice(E,A),x.index-=E}else if(!(x=o(k,0,_,b)))continue;T=x.index;var R=x[0],N=_.slice(0,T),O=_.slice(T+R.length),I=E+_.length;d&&I>d.reach&&(d.reach=I);var D=S.prev;if(N&&(D=s(t,D,N),E+=N.length),c(t,D,C),S=s(t,D,new a(p,h?r.tokenize(R,h):R,y,R)),O&&s(t,S,O),C>1){var M={cause:p+","+m,reach:I};i(e,t,n,S.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}return a.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var a="";return t.forEach((function(t){a+=e(t,n)})),a}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),r.hooks.run("wrap",o);var l="";for(var s in o.attributes)l+=" "+s+'="'+(o.attributes[s]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+l+">"+o.content+"</"+o.tag+">"},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i<a.length;i++)o[a[i]]=e.languages.bash[a[i]];e.languages.shell=e.languages.bash}(a),a.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var a=t[n];if("code"===a.type){var o=a.content[1],i=a.content[3];if(o&&i&&"code-language"===o.type&&"code-block"===i.type&&"string"==typeof o.content){var l=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),s="language-"+(l=(/[a-z][\w-]*/i.exec(l)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,s]:i.alias.push(s):i.alias=[s]}}else e(a.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,a=t.classes.length;r<a;r++){var o=t.classes[r],c=/language-(.+)/.exec(o);if(c){n=c[1];break}}var u,d=e.languages[n];if(d)t.content=e.highlight((u=t.content,u.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),s(n);var r=l[t];return r||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var p="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=p,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(p);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),l={amp:"&",lt:"<",gt:">",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var a=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=p(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),a.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),a.length>0)){var l=p(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s<l;s++){var c=t[s];"variable"===c.type&&a.indexOf(c.content)>=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return!1}return!0}function p(e,r){for(var a=1,o=n;o<t.length;o++){var i=t[o],l=i.content;if("punctuation"===i.type&&"string"==typeof l)if(e.test(l))a++;else if(r.test(l)&&0===--a)return o}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),a.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return u[n]=a,n})).join(""),n,r),p=Object.keys(u);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=p.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=p[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=c(u[a]),f=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),f){var g=[f];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r<a;r++){var o=n[r];if("string"!=typeof o){var i=o.content;if(Array.isArray(i))if("template-string"===o.type){var l=i[1];if(3===i.length&&"string"!=typeof l&&"embedded-code"===l.type){var s=p(l),c=l.alias,d=Array.isArray(c)?c[0]:c,f=e.languages[d];if(!f)continue;i[1]=u(s,f,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(a),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var a=n[r],o=e.languages.javascript[a];"RegExp"===e.util.type(o)&&(o=e.languages.javascript[a]={pattern:o});var i=o.inside||{};o.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(a),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=!1;if("string"!=typeof a&&("tag"===a.type&&a.content[0]&&"tag"===a.content[0].type?"</"===a.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),r>0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s<l.length&&!(a>=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++a;var g=p.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),v=[];g&&v.push.apply(v,i([g])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function a(r,o){if(!(r in n)){o.push(r);var i=o.indexOf(r);if(i<o.length-1)throw new Error("Circular dependency: "+o.slice(i).join(" -> "));var l={},s=e[r];if(s){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,c),t(s.optional,c),t(s.modify,c)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(c),l=(l||[]).map(c);var u=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(s),m=u;a(m);){for(var g in p={},m){var h=s[g];t(h&&h.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in f(b))if(v in u){p[b]=!0;break}for(var y in m=p)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function c(e){if(e in l)return l[e];s[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var p=i(u.map((function(e){var t=c(e);return delete s[e],t})));o?a=o(p,(function(){return r(e)})):r(e)}return l[e]=a}for(var u in n)c(u);var d=[];for(var p in s)d.push(l[p]);return i(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!r)throw Error(i(227));var l=new Set,s={};function c(e,t){u(e,t),u(e+"Capture",t)}function u(e,t){for(s[e]=t,e=0;e<t.length;e++)l.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f=Object.prototype.hasOwnProperty,m={},g={};function h(e,t,n,r,a,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=a,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){b[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];b[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){b[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){b[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){b[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){b[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){b[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){b[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){b[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,r){var a=b.hasOwnProperty(t)?b[t]:null;(null!==a?0===a.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,a,r)&&(n=null),r||null===a?function(e){return!!f.call(g,e)||!f.call(m,e)&&(p.test(e)?g[e]=!0:(m[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):a.mustUseProperty?e[a.propertyName]=null===n?3!==a.type&&"":n:(t=a.attributeName,r=a.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(a=a.type)||4===a&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),b.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var k=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,S=60103,E=60106,_=60107,x=60108,C=60114,T=60109,L=60110,A=60112,P=60113,R=60120,N=60115,O=60116,I=60121,D=60128,M=60129,j=60130,F=60131;if("function"==typeof Symbol&&Symbol.for){var B=Symbol.for;S=B("react.element"),E=B("react.portal"),_=B("react.fragment"),x=B("react.strict_mode"),C=B("react.profiler"),T=B("react.provider"),L=B("react.context"),A=B("react.forward_ref"),P=B("react.suspense"),R=B("react.suspense_list"),N=B("react.memo"),O=B("react.lazy"),I=B("react.block"),B("react.scope"),D=B("react.opaque.id"),M=B("react.debug_trace_mode"),j=B("react.offscreen"),F=B("react.legacy_hidden")}var z,U="function"==typeof Symbol&&Symbol.iterator;function $(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=U&&e[U]||e["@@iterator"])?e:null}function q(e){if(void 0===z)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);z=t&&t[1]||""}return"\n"+z+e}var G=!1;function H(e,t){if(!e||G)return"";G=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(s){var r=s}Reflect.construct(e,[],t)}else{try{t.call()}catch(s){r=s}e.call(t.prototype)}else{try{throw Error()}catch(s){r=s}e()}}catch(s){if(s&&r&&"string"==typeof s.stack){for(var a=s.stack.split("\n"),o=r.stack.split("\n"),i=a.length-1,l=o.length-1;1<=i&&0<=l&&a[i]!==o[l];)l--;for(;1<=i&&0<=l;i--,l--)if(a[i]!==o[l]){if(1!==i||1!==l)do{if(i--,0>--l||a[i]!==o[l])return"\n"+a[i].replace(" at new "," at ")}while(1<=i&&0<=l);break}}}finally{G=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?q(e):""}function Z(e){switch(e.tag){case 5:return q(e.type);case 16:return q("Lazy");case 13:return q("Suspense");case 19:return q("SuspenseList");case 0:case 2:case 15:return e=H(e.type,!1);case 11:return e=H(e.type.render,!1);case 22:return e=H(e.type._render,!1);case 1:return e=H(e.type,!0);default:return""}}function V(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case E:return"Portal";case C:return"Profiler";case x:return"StrictMode";case P:return"Suspense";case R:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case L:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case A:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case N:return V(e.type);case I:return V(e._render);case O:t=e._payload,e=e._init;try{return V(e(t))}catch(n){}}return null}function W(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function Y(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function K(e){e._valueTracker||(e._valueTracker=function(e){var t=Y(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var a=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Y(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function X(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return a({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=W(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=W(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ae(e,t.type,n):t.hasOwnProperty("defaultValue")&&ae(e,t.type,W(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function re(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ae(e,t,n){"number"===t&&X(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function oe(e,t){return e=a({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,r){if(e=e.options,t){t={};for(var a=0;a<n.length;a++)t["$"+n[a]]=!0;for(n=0;n<e.length;n++)a=t.hasOwnProperty("$"+e[n].value),e[n].selected!==a&&(e[n].selected=a),a&&r&&(e[n].defaultSelected=!0)}else{for(n=""+W(n),t=null,a=0;a<e.length;a++){if(e[a].value===n)return e[a].selected=!0,void(r&&(e[a].defaultSelected=!0));null!==t||e[a].disabled||(t=e[a])}null!==t&&(t.selected=!0)}}function le(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return a({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function se(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:W(n)}}function ce(e,t){var n=W(t.value),r=W(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ue(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function pe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function fe(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?pe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,ge,he=(ge=function(e,t){if(e.namespaceURI!==de.svg||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ge(e,t)}))}:ge);function be(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ve={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ye=["Webkit","ms","Moz","O"];function we(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ve.hasOwnProperty(e)&&ve[e]?(""+t).trim():t+"px"}function ke(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),a=we(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,a):e[n]=a}}Object.keys(ve).forEach((function(e){ye.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ve[t]=ve[e]}))}));var Se=a({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(Se[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function _e(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function xe(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Ce=null,Te=null,Le=null;function Ae(e){if(e=na(e)){if("function"!=typeof Ce)throw Error(i(280));var t=e.stateNode;t&&(t=aa(t),Ce(e.stateNode,e.type,t))}}function Pe(e){Te?Le?Le.push(e):Le=[e]:Te=e}function Re(){if(Te){var e=Te,t=Le;if(Le=Te=null,Ae(e),t)for(e=0;e<t.length;e++)Ae(t[e])}}function Ne(e,t){return e(t)}function Oe(e,t,n,r,a){return e(t,n,r,a)}function Ie(){}var De=Ne,Me=!1,je=!1;function Fe(){null===Te&&null===Le||(Ie(),Re())}function Be(e,t){var n=e.stateNode;if(null===n)return null;var r=aa(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var ze=!1;if(d)try{var Ue={};Object.defineProperty(Ue,"passive",{get:function(){ze=!0}}),window.addEventListener("test",Ue,Ue),window.removeEventListener("test",Ue,Ue)}catch(ge){ze=!1}function $e(e,t,n,r,a,o,i,l,s){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var qe=!1,Ge=null,He=!1,Ze=null,Ve={onError:function(e){qe=!0,Ge=e}};function We(e,t,n,r,a,o,i,l,s){qe=!1,Ge=null,$e.apply(Ve,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ke(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Qe(e){if(Ye(e)!==e)throw Error(i(188))}function Xe(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,r=t;;){var a=n.return;if(null===a)break;var o=a.alternate;if(null===o){if(null!==(r=a.return)){n=r;continue}break}if(a.child===o.child){for(o=a.child;o;){if(o===n)return Qe(a),e;if(o===r)return Qe(a),t;o=o.sibling}throw Error(i(188))}if(n.return!==r.return)n=a,r=o;else{for(var l=!1,s=a.child;s;){if(s===n){l=!0,n=a,r=o;break}if(s===r){l=!0,r=a,n=o;break}s=s.sibling}if(!l){for(s=o.child;s;){if(s===n){l=!0,n=o,r=a;break}if(s===r){l=!0,r=o,n=a;break}s=s.sibling}if(!l)throw Error(i(189))}}if(n.alternate!==r)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function Je(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var et,tt,nt,rt,at=!1,ot=[],it=null,lt=null,st=null,ct=new Map,ut=new Map,dt=[],pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function ft(e,t,n,r,a){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:a,targetContainers:[r]}}function mt(e,t){switch(e){case"focusin":case"focusout":it=null;break;case"dragenter":case"dragleave":lt=null;break;case"mouseover":case"mouseout":st=null;break;case"pointerover":case"pointerout":ct.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":ut.delete(t.pointerId)}}function gt(e,t,n,r,a,o){return null===e||e.nativeEvent!==o?(e=ft(t,n,r,a,o),null!==t&&(null!==(t=na(t))&&tt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==a&&-1===t.indexOf(a)&&t.push(a),e)}function ht(e){var t=ta(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ke(n)))return e.blockedOn=t,void rt(e.lanePriority,(function(){o.unstable_runWithPriority(e.priority,(function(){nt(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function bt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=na(n))&&tt(t),e.blockedOn=n,!1;t.shift()}return!0}function vt(e,t,n){bt(e)&&n.delete(t)}function yt(){for(at=!1;0<ot.length;){var e=ot[0];if(null!==e.blockedOn){null!==(e=na(e.blockedOn))&&et(e);break}for(var t=e.targetContainers;0<t.length;){var n=Xt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&ot.shift()}null!==it&&bt(it)&&(it=null),null!==lt&&bt(lt)&&(lt=null),null!==st&&bt(st)&&(st=null),ct.forEach(vt),ut.forEach(vt)}function wt(e,t){e.blockedOn===t&&(e.blockedOn=null,at||(at=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,yt)))}function kt(e){function t(t){return wt(t,e)}if(0<ot.length){wt(ot[0],e);for(var n=1;n<ot.length;n++){var r=ot[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==it&&wt(it,e),null!==lt&&wt(lt,e),null!==st&&wt(st,e),ct.forEach(t),ut.forEach(t),n=0;n<dt.length;n++)(r=dt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<dt.length&&null===(n=dt[0]).blockedOn;)ht(n),null===n.blockedOn&&dt.shift()}function St(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:St("Animation","AnimationEnd"),animationiteration:St("Animation","AnimationIteration"),animationstart:St("Animation","AnimationStart"),transitionend:St("Transition","TransitionEnd")},_t={},xt={};function Ct(e){if(_t[e])return _t[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in xt)return _t[e]=n[t];return e}d&&(xt=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var Tt=Ct("animationend"),Lt=Ct("animationiteration"),At=Ct("animationstart"),Pt=Ct("transitionend"),Rt=new Map,Nt=new Map,Ot=["abort","abort",Tt,"animationEnd",Lt,"animationIteration",At,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Pt,"transitionEnd","waiting","waiting"];function It(e,t){for(var n=0;n<e.length;n+=2){var r=e[n],a=e[n+1];a="on"+(a[0].toUpperCase()+a.slice(1)),Nt.set(r,t),Rt.set(r,a),c(a,[r])}}(0,o.unstable_now)();var Dt=8;function Mt(e){if(0!=(1&e))return Dt=15,1;if(0!=(2&e))return Dt=14,2;if(0!=(4&e))return Dt=13,4;var t=24&e;return 0!==t?(Dt=12,t):0!=(32&e)?(Dt=11,32):0!==(t=192&e)?(Dt=10,t):0!=(256&e)?(Dt=9,256):0!==(t=3584&e)?(Dt=8,t):0!=(4096&e)?(Dt=7,4096):0!==(t=4186112&e)?(Dt=6,t):0!==(t=62914560&e)?(Dt=5,t):67108864&e?(Dt=4,67108864):0!=(134217728&e)?(Dt=3,134217728):0!==(t=805306368&e)?(Dt=2,t):0!=(1073741824&e)?(Dt=1,1073741824):(Dt=8,e)}function jt(e,t){var n=e.pendingLanes;if(0===n)return Dt=0;var r=0,a=0,o=e.expiredLanes,i=e.suspendedLanes,l=e.pingedLanes;if(0!==o)r=o,a=Dt=15;else if(0!==(o=134217727&n)){var s=o&~i;0!==s?(r=Mt(s),a=Dt):0!==(l&=o)&&(r=Mt(l),a=Dt)}else 0!==(o=n&~i)?(r=Mt(o),a=Dt):0!==l&&(r=Mt(l),a=Dt);if(0===r)return 0;if(r=n&((0>(r=31-qt(r))?0:1<<r)<<1)-1,0!==t&&t!==r&&0==(t&i)){if(Mt(t),a<=Dt)return t;Dt=a}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)a=1<<(n=31-qt(t)),r|=e[n],t&=~a;return r}function Ft(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function Bt(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=zt(24&~t))?Bt(10,t):e;case 10:return 0===(e=zt(192&~t))?Bt(8,t):e;case 8:return 0===(e=zt(3584&~t))&&(0===(e=zt(4186112&~t))&&(e=512)),e;case 2:return 0===(t=zt(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function zt(e){return e&-e}function Ut(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function $t(e,t,n){e.pendingLanes|=t;var r=t-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[t=31-qt(t)]=n}var qt=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(Gt(e)/Ht|0)|0},Gt=Math.log,Ht=Math.LN2;var Zt=o.unstable_UserBlockingPriority,Vt=o.unstable_runWithPriority,Wt=!0;function Yt(e,t,n,r){Me||Ie();var a=Qt,o=Me;Me=!0;try{Oe(a,e,t,n,r)}finally{(Me=o)||Fe()}}function Kt(e,t,n,r){Vt(Zt,Qt.bind(null,e,t,n,r))}function Qt(e,t,n,r){var a;if(Wt)if((a=0==(4&t))&&0<ot.length&&-1<pt.indexOf(e))e=ft(null,e,t,n,r),ot.push(e);else{var o=Xt(e,t,n,r);if(null===o)a&&mt(e,r);else{if(a){if(-1<pt.indexOf(e))return e=ft(o,e,t,n,r),void ot.push(e);if(function(e,t,n,r,a){switch(t){case"focusin":return it=gt(it,e,t,n,r,a),!0;case"dragenter":return lt=gt(lt,e,t,n,r,a),!0;case"mouseover":return st=gt(st,e,t,n,r,a),!0;case"pointerover":var o=a.pointerId;return ct.set(o,gt(ct.get(o)||null,e,t,n,r,a)),!0;case"gotpointercapture":return o=a.pointerId,ut.set(o,gt(ut.get(o)||null,e,t,n,r,a)),!0}return!1}(o,e,t,n,r))return;mt(e,r)}Ir(e,t,r,null,n)}}}function Xt(e,t,n,r){var a=xe(r);if(null!==(a=ta(a))){var o=Ye(a);if(null===o)a=null;else{var i=o.tag;if(13===i){if(null!==(a=Ke(o)))return a;a=null}else if(3===i){if(o.stateNode.hydrate)return 3===o.tag?o.stateNode.containerInfo:null;a=null}else o!==a&&(a=null)}}return Ir(e,t,r,a,n),null}var Jt=null,en=null,tn=null;function nn(){if(tn)return tn;var e,t,n=en,r=n.length,a="value"in Jt?Jt.value:Jt.textContent,o=a.length;for(e=0;e<r&&n[e]===a[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===a[o-t];t++);return tn=a.slice(e,1<t?1-t:void 0)}function rn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function an(){return!0}function on(){return!1}function ln(e){function t(t,n,r,a,o){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=a,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(a):a[i]);return this.isDefaultPrevented=(null!=a.defaultPrevented?a.defaultPrevented:!1===a.returnValue)?an:on,this.isPropagationStopped=on,this}return a(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=an)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=an)},persist:function(){},isPersistent:an}),t}var sn,cn,un,dn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},pn=ln(dn),fn=a({},dn,{view:0,detail:0}),mn=ln(fn),gn=a({},fn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Tn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==un&&(un&&"mousemove"===e.type?(sn=e.screenX-un.screenX,cn=e.screenY-un.screenY):cn=sn=0,un=e),sn)},movementY:function(e){return"movementY"in e?e.movementY:cn}}),hn=ln(gn),bn=ln(a({},gn,{dataTransfer:0})),vn=ln(a({},fn,{relatedTarget:0})),yn=ln(a({},dn,{animationName:0,elapsedTime:0,pseudoElement:0})),wn=a({},dn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),kn=ln(wn),Sn=ln(a({},dn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},_n={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},xn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Cn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=xn[e])&&!!t[e]}function Tn(){return Cn}var Ln=a({},fn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=rn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?_n[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Tn,charCode:function(e){return"keypress"===e.type?rn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?rn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),An=ln(Ln),Pn=ln(a({},gn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Rn=ln(a({},fn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Tn})),Nn=ln(a({},dn,{propertyName:0,elapsedTime:0,pseudoElement:0})),On=a({},gn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),In=ln(On),Dn=[9,13,27,32],Mn=d&&"CompositionEvent"in window,jn=null;d&&"documentMode"in document&&(jn=document.documentMode);var Fn=d&&"TextEvent"in window&&!jn,Bn=d&&(!Mn||jn&&8<jn&&11>=jn),zn=String.fromCharCode(32),Un=!1;function $n(e,t){switch(e){case"keyup":return-1!==Dn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function qn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Gn=!1;var Hn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Zn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Hn[e.type]:"textarea"===t}function Vn(e,t,n,r){Pe(r),0<(t=Mr(t,"onChange")).length&&(n=new pn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Wn=null,Yn=null;function Kn(e){Lr(e,0)}function Qn(e){if(Q(ra(e)))return e}function Xn(e,t){if("change"===e)return t}var Jn=!1;if(d){var er;if(d){var tr="oninput"in document;if(!tr){var nr=document.createElement("div");nr.setAttribute("oninput","return;"),tr="function"==typeof nr.oninput}er=tr}else er=!1;Jn=er&&(!document.documentMode||9<document.documentMode)}function rr(){Wn&&(Wn.detachEvent("onpropertychange",ar),Yn=Wn=null)}function ar(e){if("value"===e.propertyName&&Qn(Yn)){var t=[];if(Vn(t,Yn,e,xe(e)),e=Kn,Me)e(t);else{Me=!0;try{Ne(e,t)}finally{Me=!1,Fe()}}}}function or(e,t,n){"focusin"===e?(rr(),Yn=n,(Wn=t).attachEvent("onpropertychange",ar)):"focusout"===e&&rr()}function ir(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Qn(Yn)}function lr(e,t){if("click"===e)return Qn(t)}function sr(e,t){if("input"===e||"change"===e)return Qn(t)}var cr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},ur=Object.prototype.hasOwnProperty;function dr(e,t){if(cr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!ur.call(t,n[r])||!cr(e[n[r]],t[n[r]]))return!1;return!0}function pr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function fr(e,t){var n,r=pr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=pr(r)}}function mr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function gr(){for(var e=window,t=X();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=X((e=t.contentWindow).document)}return t}function hr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var br=d&&"documentMode"in document&&11>=document.documentMode,vr=null,yr=null,wr=null,kr=!1;function Sr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;kr||null==vr||vr!==X(r)||("selectionStart"in(r=vr)&&hr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},wr&&dr(wr,r)||(wr=r,0<(r=Mr(yr,"onSelect")).length&&(t=new pn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=vr)))}It("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),It("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),It(Ot,2);for(var Er="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),_r=0;_r<Er.length;_r++)Nt.set(Er[_r],0);u("onMouseEnter",["mouseout","mouseover"]),u("onMouseLeave",["mouseout","mouseover"]),u("onPointerEnter",["pointerout","pointerover"]),u("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var xr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Cr=new Set("cancel close invalid load scroll toggle".split(" ").concat(xr));function Tr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,a,o,l,s,c){if(We.apply(this,arguments),qe){if(!qe)throw Error(i(198));var u=Ge;qe=!1,Ge=null,He||(He=!0,Ze=u)}}(r,t,void 0,e),e.currentTarget=null}function Lr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],a=r.event;r=r.listeners;e:{var o=void 0;if(t)for(var i=r.length-1;0<=i;i--){var l=r[i],s=l.instance,c=l.currentTarget;if(l=l.listener,s!==o&&a.isPropagationStopped())break e;Tr(a,l,c),o=s}else for(i=0;i<r.length;i++){if(s=(l=r[i]).instance,c=l.currentTarget,l=l.listener,s!==o&&a.isPropagationStopped())break e;Tr(a,l,c),o=s}}}if(He)throw e=Ze,He=!1,Ze=null,e}function Ar(e,t){var n=oa(t),r=e+"__bubble";n.has(r)||(Or(t,e,2,!1),n.add(r))}var Pr="_reactListening"+Math.random().toString(36).slice(2);function Rr(e){e[Pr]||(e[Pr]=!0,l.forEach((function(t){Cr.has(t)||Nr(t,!1,e,null),Nr(t,!0,e,null)})))}function Nr(e,t,n,r){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,o=n;if("selectionchange"===e&&9!==n.nodeType&&(o=n.ownerDocument),null!==r&&!t&&Cr.has(e)){if("scroll"!==e)return;a|=2,o=r}var i=oa(o),l=e+"__"+(t?"capture":"bubble");i.has(l)||(t&&(a|=4),Or(o,e,a,t),i.add(l))}function Or(e,t,n,r){var a=Nt.get(t);switch(void 0===a?2:a){case 0:a=Yt;break;case 1:a=Kt;break;default:a=Qt}n=a.bind(null,t,n,e),a=void 0,!ze||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(a=!0),r?void 0!==a?e.addEventListener(t,n,{capture:!0,passive:a}):e.addEventListener(t,n,!0):void 0!==a?e.addEventListener(t,n,{passive:a}):e.addEventListener(t,n,!1)}function Ir(e,t,n,r,a){var o=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var l=r.stateNode.containerInfo;if(l===a||8===l.nodeType&&l.parentNode===a)break;if(4===i)for(i=r.return;null!==i;){var s=i.tag;if((3===s||4===s)&&((s=i.stateNode.containerInfo)===a||8===s.nodeType&&s.parentNode===a))return;i=i.return}for(;null!==l;){if(null===(i=ta(l)))return;if(5===(s=i.tag)||6===s){r=o=i;continue e}l=l.parentNode}}r=r.return}!function(e,t,n){if(je)return e(t,n);je=!0;try{return De(e,t,n)}finally{je=!1,Fe()}}((function(){var r=o,a=xe(n),i=[];e:{var l=Rt.get(e);if(void 0!==l){var s=pn,c=e;switch(e){case"keypress":if(0===rn(n))break e;case"keydown":case"keyup":s=An;break;case"focusin":c="focus",s=vn;break;case"focusout":c="blur",s=vn;break;case"beforeblur":case"afterblur":s=vn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":s=hn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":s=bn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":s=Rn;break;case Tt:case Lt:case At:s=yn;break;case Pt:s=Nn;break;case"scroll":s=mn;break;case"wheel":s=In;break;case"copy":case"cut":case"paste":s=kn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":s=Pn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==l?l+"Capture":null:l;u=[];for(var f,m=r;null!==m;){var g=(f=m).stateNode;if(5===f.tag&&null!==g&&(f=g,null!==p&&(null!=(g=Be(m,p))&&u.push(Dr(m,g,f)))),d)break;m=m.return}0<u.length&&(l=new s(l,c,null,n,a),i.push({event:l,listeners:u}))}}if(0==(7&t)){if(s="mouseout"===e||"pointerout"===e,(!(l="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(c=n.relatedTarget||n.fromElement)||!ta(c)&&!c[Jr])&&(s||l)&&(l=a.window===a?a:(l=a.ownerDocument)?l.defaultView||l.parentWindow:window,s?(s=r,null!==(c=(c=n.relatedTarget||n.toElement)?ta(c):null)&&(c!==(d=Ye(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(s=null,c=r),s!==c)){if(u=hn,g="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Pn,g="onPointerLeave",p="onPointerEnter",m="pointer"),d=null==s?l:ra(s),f=null==c?l:ra(c),(l=new u(g,m+"leave",s,n,a)).target=d,l.relatedTarget=f,g=null,ta(a)===r&&((u=new u(p,m+"enter",c,n,a)).target=f,u.relatedTarget=d,g=u),d=g,s&&c)e:{for(p=c,m=0,f=u=s;f;f=jr(f))m++;for(f=0,g=p;g;g=jr(g))f++;for(;0<m-f;)u=jr(u),m--;for(;0<f-m;)p=jr(p),f--;for(;m--;){if(u===p||null!==p&&u===p.alternate)break e;u=jr(u),p=jr(p)}u=null}else u=null;null!==s&&Fr(i,l,s,u,!1),null!==c&&null!==d&&Fr(i,d,c,u,!0)}if("select"===(s=(l=r?ra(r):window).nodeName&&l.nodeName.toLowerCase())||"input"===s&&"file"===l.type)var h=Xn;else if(Zn(l))if(Jn)h=sr;else{h=ir;var b=or}else(s=l.nodeName)&&"input"===s.toLowerCase()&&("checkbox"===l.type||"radio"===l.type)&&(h=lr);switch(h&&(h=h(e,r))?Vn(i,h,n,a):(b&&b(e,l,r),"focusout"===e&&(b=l._wrapperState)&&b.controlled&&"number"===l.type&&ae(l,"number",l.value)),b=r?ra(r):window,e){case"focusin":(Zn(b)||"true"===b.contentEditable)&&(vr=b,yr=r,wr=null);break;case"focusout":wr=yr=vr=null;break;case"mousedown":kr=!0;break;case"contextmenu":case"mouseup":case"dragend":kr=!1,Sr(i,n,a);break;case"selectionchange":if(br)break;case"keydown":case"keyup":Sr(i,n,a)}var v;if(Mn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else Gn?$n(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Bn&&"ko"!==n.locale&&(Gn||"onCompositionStart"!==y?"onCompositionEnd"===y&&Gn&&(v=nn()):(en="value"in(Jt=a)?Jt.value:Jt.textContent,Gn=!0)),0<(b=Mr(r,y)).length&&(y=new Sn(y,e,null,n,a),i.push({event:y,listeners:b}),v?y.data=v:null!==(v=qn(n))&&(y.data=v))),(v=Fn?function(e,t){switch(e){case"compositionend":return qn(t);case"keypress":return 32!==t.which?null:(Un=!0,zn);case"textInput":return(e=t.data)===zn&&Un?null:e;default:return null}}(e,n):function(e,t){if(Gn)return"compositionend"===e||!Mn&&$n(e,t)?(e=nn(),tn=en=Jt=null,Gn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Bn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Mr(r,"onBeforeInput")).length&&(a=new Sn("onBeforeInput","beforeinput",null,n,a),i.push({event:a,listeners:r}),a.data=v))}Lr(i,t)}))}function Dr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Mr(e,t){for(var n=t+"Capture",r=[];null!==e;){var a=e,o=a.stateNode;5===a.tag&&null!==o&&(a=o,null!=(o=Be(e,n))&&r.unshift(Dr(e,o,a)),null!=(o=Be(e,t))&&r.push(Dr(e,o,a))),e=e.return}return r}function jr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Fr(e,t,n,r,a){for(var o=t._reactName,i=[];null!==n&&n!==r;){var l=n,s=l.alternate,c=l.stateNode;if(null!==s&&s===r)break;5===l.tag&&null!==c&&(l=c,a?null!=(s=Be(n,o))&&i.unshift(Dr(n,s,l)):a||null!=(s=Be(n,o))&&i.push(Dr(n,s,l))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function Br(){}var zr=null,Ur=null;function $r(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function qr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var Gr="function"==typeof setTimeout?setTimeout:void 0,Hr="function"==typeof clearTimeout?clearTimeout:void 0;function Zr(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Vr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Wr(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Yr=0;var Kr=Math.random().toString(36).slice(2),Qr="__reactFiber$"+Kr,Xr="__reactProps$"+Kr,Jr="__reactContainer$"+Kr,ea="__reactEvents$"+Kr;function ta(e){var t=e[Qr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[Jr]||n[Qr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Wr(e);null!==e;){if(n=e[Qr])return n;e=Wr(e)}return t}n=(e=n).parentNode}return null}function na(e){return!(e=e[Qr]||e[Jr])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function ra(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function aa(e){return e[Xr]||null}function oa(e){var t=e[ea];return void 0===t&&(t=e[ea]=new Set),t}var ia=[],la=-1;function sa(e){return{current:e}}function ca(e){0>la||(e.current=ia[la],ia[la]=null,la--)}function ua(e,t){la++,ia[la]=e.current,e.current=t}var da={},pa=sa(da),fa=sa(!1),ma=da;function ga(e,t){var n=e.type.contextTypes;if(!n)return da;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var a,o={};for(a in n)o[a]=t[a];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function ha(e){return null!=(e=e.childContextTypes)}function ba(){ca(fa),ca(pa)}function va(e,t,n){if(pa.current!==da)throw Error(i(168));ua(pa,t),ua(fa,n)}function ya(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(i(108,V(t)||"Unknown",o));return a({},n,r)}function wa(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||da,ma=pa.current,ua(pa,e),ua(fa,fa.current),!0}function ka(e,t,n){var r=e.stateNode;if(!r)throw Error(i(169));n?(e=ya(e,t,ma),r.__reactInternalMemoizedMergedChildContext=e,ca(fa),ca(pa),ua(pa,e)):ca(fa),ua(fa,n)}var Sa=null,Ea=null,_a=o.unstable_runWithPriority,xa=o.unstable_scheduleCallback,Ca=o.unstable_cancelCallback,Ta=o.unstable_shouldYield,La=o.unstable_requestPaint,Aa=o.unstable_now,Pa=o.unstable_getCurrentPriorityLevel,Ra=o.unstable_ImmediatePriority,Na=o.unstable_UserBlockingPriority,Oa=o.unstable_NormalPriority,Ia=o.unstable_LowPriority,Da=o.unstable_IdlePriority,Ma={},ja=void 0!==La?La:function(){},Fa=null,Ba=null,za=!1,Ua=Aa(),$a=1e4>Ua?Aa:function(){return Aa()-Ua};function qa(){switch(Pa()){case Ra:return 99;case Na:return 98;case Oa:return 97;case Ia:return 96;case Da:return 95;default:throw Error(i(332))}}function Ga(e){switch(e){case 99:return Ra;case 98:return Na;case 97:return Oa;case 96:return Ia;case 95:return Da;default:throw Error(i(332))}}function Ha(e,t){return e=Ga(e),_a(e,t)}function Za(e,t,n){return e=Ga(e),xa(e,t,n)}function Va(){if(null!==Ba){var e=Ba;Ba=null,Ca(e)}Wa()}function Wa(){if(!za&&null!==Fa){za=!0;var e=0;try{var t=Fa;Ha(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),Fa=null}catch(n){throw null!==Fa&&(Fa=Fa.slice(e+1)),xa(Ra,Va),n}finally{za=!1}}}var Ya=k.ReactCurrentBatchConfig;function Ka(e,t){if(e&&e.defaultProps){for(var n in t=a({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Qa=sa(null),Xa=null,Ja=null,eo=null;function to(){eo=Ja=Xa=null}function no(e){var t=Qa.current;ca(Qa),e.type._context._currentValue=t}function ro(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function ao(e,t){Xa=e,eo=Ja=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Mi=!0),e.firstContext=null)}function oo(e,t){if(eo!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(eo=e,t=1073741823),t={context:e,observedBits:t,next:null},null===Ja){if(null===Xa)throw Error(i(308));Ja=t,Xa.dependencies={lanes:0,firstContext:t,responders:null}}else Ja=Ja.next=t;return e._currentValue}var io=!1;function lo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function so(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function co(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function uo(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function po(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var a=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===o?a=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?a=o=t:o=o.next=t}else a=o=t;return n={baseState:r.baseState,firstBaseUpdate:a,lastBaseUpdate:o,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function fo(e,t,n,r){var o=e.updateQueue;io=!1;var i=o.firstBaseUpdate,l=o.lastBaseUpdate,s=o.shared.pending;if(null!==s){o.shared.pending=null;var c=s,u=c.next;c.next=null,null===l?i=u:l.next=u,l=c;var d=e.alternate;if(null!==d){var p=(d=d.updateQueue).lastBaseUpdate;p!==l&&(null===p?d.firstBaseUpdate=u:p.next=u,d.lastBaseUpdate=c)}}if(null!==i){for(p=o.baseState,l=0,d=u=c=null;;){s=i.lane;var f=i.eventTime;if((r&s)===s){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var m=e,g=i;switch(s=t,f=n,g.tag){case 1:if("function"==typeof(m=g.payload)){p=m.call(f,p,s);break e}p=m;break e;case 3:m.flags=-4097&m.flags|64;case 0:if(null==(s="function"==typeof(m=g.payload)?m.call(f,p,s):m))break e;p=a({},p,s);break e;case 2:io=!0}}null!==i.callback&&(e.flags|=32,null===(s=o.effects)?o.effects=[i]:s.push(i))}else f={eventTime:f,lane:s,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(u=d=f,c=p):d=d.next=f,l|=s;if(null===(i=i.next)){if(null===(s=o.shared.pending))break;i=s.next,s.next=null,o.lastBaseUpdate=s,o.shared.pending=null}}null===d&&(c=p),o.baseState=c,o.firstBaseUpdate=u,o.lastBaseUpdate=d,Ul|=l,e.lanes=l,e.memoizedState=p}}function mo(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],a=r.callback;if(null!==a){if(r.callback=null,r=n,"function"!=typeof a)throw Error(i(191,a));a.call(r)}}}var go=(new r.Component).refs;function ho(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:a({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var bo={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=ps(),a=fs(e),o=co(r,a);o.payload=t,null!=n&&(o.callback=n),uo(e,o),ms(e,a,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=ps(),a=fs(e),o=co(r,a);o.tag=1,o.payload=t,null!=n&&(o.callback=n),uo(e,o),ms(e,a,r)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=ps(),r=fs(e),a=co(n,r);a.tag=2,null!=t&&(a.callback=t),uo(e,a),ms(e,r,n)}};function vo(e,t,n,r,a,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!dr(n,r)||!dr(a,o))}function yo(e,t,n){var r=!1,a=da,o=t.contextType;return"object"==typeof o&&null!==o?o=oo(o):(a=ha(t)?ma:pa.current,o=(r=null!=(r=t.contextTypes))?ga(e,a):da),t=new t(n,o),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=bo,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=a,e.__reactInternalMemoizedMaskedChildContext=o),t}function wo(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&bo.enqueueReplaceState(t,t.state,null)}function ko(e,t,n,r){var a=e.stateNode;a.props=n,a.state=e.memoizedState,a.refs=go,lo(e);var o=t.contextType;"object"==typeof o&&null!==o?a.context=oo(o):(o=ha(t)?ma:pa.current,a.context=ga(e,o)),fo(e,n,a,r),a.state=e.memoizedState,"function"==typeof(o=t.getDerivedStateFromProps)&&(ho(e,t,o,n),a.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof a.getSnapshotBeforeUpdate||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||(t=a.state,"function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount(),t!==a.state&&bo.enqueueReplaceState(a,a.state,null),fo(e,n,a,r),a.state=e.memoizedState),"function"==typeof a.componentDidMount&&(e.flags|=4)}var So=Array.isArray;function Eo(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var r=n.stateNode}if(!r)throw Error(i(147,e));var a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=r.refs;t===go&&(t=r.refs={}),null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function _o(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function xo(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function a(e,t){return(e=Zs(e,t)).index=0,e.sibling=null,e}function o(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags=2,n):r:(t.flags=2,n):n}function l(t){return e&&null===t.alternate&&(t.flags=2),t}function s(e,t,n,r){return null===t||6!==t.tag?((t=Ks(n,e.mode,r)).return=e,t):((t=a(t,n)).return=e,t)}function c(e,t,n,r){return null!==t&&t.elementType===n.type?((r=a(t,n.props)).ref=Eo(e,t,n),r.return=e,r):((r=Vs(n.type,n.key,n.props,null,e.mode,r)).ref=Eo(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Qs(n,e.mode,r)).return=e,t):((t=a(t,n.children||[])).return=e,t)}function d(e,t,n,r,o){return null===t||7!==t.tag?((t=Ws(n,e.mode,r,o)).return=e,t):((t=a(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Ks(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case S:return(n=Vs(t.type,t.key,t.props,null,e.mode,n)).ref=Eo(e,null,t),n.return=e,n;case E:return(t=Qs(t,e.mode,n)).return=e,t}if(So(t)||$(t))return(t=Ws(t,e.mode,n,null)).return=e,t;_o(e,t)}return null}function f(e,t,n,r){var a=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==a?null:s(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case S:return n.key===a?n.type===_?d(e,t,n.props.children,r,a):c(e,t,n,r):null;case E:return n.key===a?u(e,t,n,r):null}if(So(n)||$(n))return null!==a?null:d(e,t,n,r,null);_o(e,n)}return null}function m(e,t,n,r,a){if("string"==typeof r||"number"==typeof r)return s(t,e=e.get(n)||null,""+r,a);if("object"==typeof r&&null!==r){switch(r.$$typeof){case S:return e=e.get(null===r.key?n:r.key)||null,r.type===_?d(t,e,r.props.children,a,r.key):c(t,e,r,a);case E:return u(t,e=e.get(null===r.key?n:r.key)||null,r,a)}if(So(r)||$(r))return d(t,e=e.get(n)||null,r,a,null);_o(t,r)}return null}function g(a,i,l,s){for(var c=null,u=null,d=i,g=i=0,h=null;null!==d&&g<l.length;g++){d.index>g?(h=d,d=null):h=d.sibling;var b=f(a,d,l[g],s);if(null===b){null===d&&(d=h);break}e&&d&&null===b.alternate&&t(a,d),i=o(b,i,g),null===u?c=b:u.sibling=b,u=b,d=h}if(g===l.length)return n(a,d),c;if(null===d){for(;g<l.length;g++)null!==(d=p(a,l[g],s))&&(i=o(d,i,g),null===u?c=d:u.sibling=d,u=d);return c}for(d=r(a,d);g<l.length;g++)null!==(h=m(d,a,g,l[g],s))&&(e&&null!==h.alternate&&d.delete(null===h.key?g:h.key),i=o(h,i,g),null===u?c=h:u.sibling=h,u=h);return e&&d.forEach((function(e){return t(a,e)})),c}function h(a,l,s,c){var u=$(s);if("function"!=typeof u)throw Error(i(150));if(null==(s=u.call(s)))throw Error(i(151));for(var d=u=null,g=l,h=l=0,b=null,v=s.next();null!==g&&!v.done;h++,v=s.next()){g.index>h?(b=g,g=null):b=g.sibling;var y=f(a,g,v.value,c);if(null===y){null===g&&(g=b);break}e&&g&&null===y.alternate&&t(a,g),l=o(y,l,h),null===d?u=y:d.sibling=y,d=y,g=b}if(v.done)return n(a,g),u;if(null===g){for(;!v.done;h++,v=s.next())null!==(v=p(a,v.value,c))&&(l=o(v,l,h),null===d?u=v:d.sibling=v,d=v);return u}for(g=r(a,g);!v.done;h++,v=s.next())null!==(v=m(g,a,h,v.value,c))&&(e&&null!==v.alternate&&g.delete(null===v.key?h:v.key),l=o(v,l,h),null===d?u=v:d.sibling=v,d=v);return e&&g.forEach((function(e){return t(a,e)})),u}return function(e,r,o,s){var c="object"==typeof o&&null!==o&&o.type===_&&null===o.key;c&&(o=o.props.children);var u="object"==typeof o&&null!==o;if(u)switch(o.$$typeof){case S:e:{for(u=o.key,c=r;null!==c;){if(c.key===u){if(7===c.tag){if(o.type===_){n(e,c.sibling),(r=a(c,o.props.children)).return=e,e=r;break e}}else if(c.elementType===o.type){n(e,c.sibling),(r=a(c,o.props)).ref=Eo(e,c,o),r.return=e,e=r;break e}n(e,c);break}t(e,c),c=c.sibling}o.type===_?((r=Ws(o.props.children,e.mode,s,o.key)).return=e,e=r):((s=Vs(o.type,o.key,o.props,null,e.mode,s)).ref=Eo(e,r,o),s.return=e,e=s)}return l(e);case E:e:{for(c=o.key;null!==r;){if(r.key===c){if(4===r.tag&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),(r=a(r,o.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Qs(o,e.mode,s)).return=e,e=r}return l(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==r&&6===r.tag?(n(e,r.sibling),(r=a(r,o)).return=e,e=r):(n(e,r),(r=Ks(o,e.mode,s)).return=e,e=r),l(e);if(So(o))return g(e,r,o,s);if($(o))return h(e,r,o,s);if(u&&_o(e,o),void 0===o&&!c)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,V(e.type)||"Component"))}return n(e,r)}}var Co=xo(!0),To=xo(!1),Lo={},Ao=sa(Lo),Po=sa(Lo),Ro=sa(Lo);function No(e){if(e===Lo)throw Error(i(174));return e}function Oo(e,t){switch(ua(Ro,t),ua(Po,e),ua(Ao,Lo),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:fe(null,"");break;default:t=fe(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}ca(Ao),ua(Ao,t)}function Io(){ca(Ao),ca(Po),ca(Ro)}function Do(e){No(Ro.current);var t=No(Ao.current),n=fe(t,e.type);t!==n&&(ua(Po,e),ua(Ao,n))}function Mo(e){Po.current===e&&(ca(Ao),ca(Po))}var jo=sa(0);function Fo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Bo=null,zo=null,Uo=!1;function $o(e,t){var n=Gs(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function qo(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function Go(e){if(Uo){var t=zo;if(t){var n=t;if(!qo(e,t)){if(!(t=Vr(n.nextSibling))||!qo(e,t))return e.flags=-1025&e.flags|2,Uo=!1,void(Bo=e);$o(Bo,n)}Bo=e,zo=Vr(t.firstChild)}else e.flags=-1025&e.flags|2,Uo=!1,Bo=e}}function Ho(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;Bo=e}function Zo(e){if(e!==Bo)return!1;if(!Uo)return Ho(e),Uo=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!qr(t,e.memoizedProps))for(t=zo;t;)$o(e,t),t=Vr(t.nextSibling);if(Ho(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){zo=Vr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}zo=null}}else zo=Bo?Vr(e.stateNode.nextSibling):null;return!0}function Vo(){zo=Bo=null,Uo=!1}var Wo=[];function Yo(){for(var e=0;e<Wo.length;e++)Wo[e]._workInProgressVersionPrimary=null;Wo.length=0}var Ko=k.ReactCurrentDispatcher,Qo=k.ReactCurrentBatchConfig,Xo=0,Jo=null,ei=null,ti=null,ni=!1,ri=!1;function ai(){throw Error(i(321))}function oi(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!cr(e[n],t[n]))return!1;return!0}function ii(e,t,n,r,a,o){if(Xo=o,Jo=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Ko.current=null===e||null===e.memoizedState?Ni:Oi,e=n(r,a),ri){o=0;do{if(ri=!1,!(25>o))throw Error(i(301));o+=1,ti=ei=null,t.updateQueue=null,Ko.current=Ii,e=n(r,a)}while(ri)}if(Ko.current=Ri,t=null!==ei&&null!==ei.next,Xo=0,ti=ei=Jo=null,ni=!1,t)throw Error(i(300));return e}function li(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ti?Jo.memoizedState=ti=e:ti=ti.next=e,ti}function si(){if(null===ei){var e=Jo.alternate;e=null!==e?e.memoizedState:null}else e=ei.next;var t=null===ti?Jo.memoizedState:ti.next;if(null!==t)ti=t,ei=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ei=e).memoizedState,baseState:ei.baseState,baseQueue:ei.baseQueue,queue:ei.queue,next:null},null===ti?Jo.memoizedState=ti=e:ti=ti.next=e}return ti}function ci(e,t){return"function"==typeof t?t(e):t}function ui(e){var t=si(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=ei,a=r.baseQueue,o=n.pending;if(null!==o){if(null!==a){var l=a.next;a.next=o.next,o.next=l}r.baseQueue=a=o,n.pending=null}if(null!==a){a=a.next,r=r.baseState;var s=l=o=null,c=a;do{var u=c.lane;if((Xo&u)===u)null!==s&&(s=s.next={lane:0,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null}),r=c.eagerReducer===e?c.eagerState:e(r,c.action);else{var d={lane:u,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null};null===s?(l=s=d,o=r):s=s.next=d,Jo.lanes|=u,Ul|=u}c=c.next}while(null!==c&&c!==a);null===s?o=r:s.next=l,cr(r,t.memoizedState)||(Mi=!0),t.memoizedState=r,t.baseState=o,t.baseQueue=s,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function di(e){var t=si(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var r=n.dispatch,a=n.pending,o=t.memoizedState;if(null!==a){n.pending=null;var l=a=a.next;do{o=e(o,l.action),l=l.next}while(l!==a);cr(o,t.memoizedState)||(Mi=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function pi(e,t,n){var r=t._getVersion;r=r(t._source);var a=t._workInProgressVersionPrimary;if(null!==a?e=a===r:(e=e.mutableReadLanes,(e=(Xo&e)===e)&&(t._workInProgressVersionPrimary=r,Wo.push(t))),e)return n(t._source);throw Wo.push(t),Error(i(350))}function fi(e,t,n,r){var a=Ol;if(null===a)throw Error(i(349));var o=t._getVersion,l=o(t._source),s=Ko.current,c=s.useState((function(){return pi(a,t,n)})),u=c[1],d=c[0];c=ti;var p=e.memoizedState,f=p.refs,m=f.getSnapshot,g=p.source;p=p.subscribe;var h=Jo;return e.memoizedState={refs:f,source:t,subscribe:r},s.useEffect((function(){f.getSnapshot=n,f.setSnapshot=u;var e=o(t._source);if(!cr(l,e)){e=n(t._source),cr(d,e)||(u(e),e=fs(h),a.mutableReadLanes|=e&a.pendingLanes),e=a.mutableReadLanes,a.entangledLanes|=e;for(var r=a.entanglements,i=e;0<i;){var s=31-qt(i),c=1<<s;r[s]|=e,i&=~c}}}),[n,t,r]),s.useEffect((function(){return r(t._source,(function(){var e=f.getSnapshot,n=f.setSnapshot;try{n(e(t._source));var r=fs(h);a.mutableReadLanes|=r&a.pendingLanes}catch(o){n((function(){throw o}))}}))}),[t,r]),cr(m,n)&&cr(g,t)&&cr(p,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:d}).dispatch=u=Pi.bind(null,Jo,e),c.queue=e,c.baseQueue=null,d=pi(a,t,n),c.memoizedState=c.baseState=d),d}function mi(e,t,n){return fi(si(),e,t,n)}function gi(e){var t=li();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ci,lastRenderedState:e}).dispatch=Pi.bind(null,Jo,e),[t.memoizedState,e]}function hi(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=Jo.updateQueue)?(t={lastEffect:null},Jo.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function bi(e){return e={current:e},li().memoizedState=e}function vi(){return si().memoizedState}function yi(e,t,n,r){var a=li();Jo.flags|=e,a.memoizedState=hi(1|t,n,void 0,void 0===r?null:r)}function wi(e,t,n,r){var a=si();r=void 0===r?null:r;var o=void 0;if(null!==ei){var i=ei.memoizedState;if(o=i.destroy,null!==r&&oi(r,i.deps))return void hi(t,n,o,r)}Jo.flags|=e,a.memoizedState=hi(1|t,n,o,r)}function ki(e,t){return yi(516,4,e,t)}function Si(e,t){return wi(516,4,e,t)}function Ei(e,t){return wi(4,2,e,t)}function _i(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function xi(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,_i.bind(null,t,e),n)}function Ci(){}function Ti(e,t){var n=si();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Li(e,t){var n=si();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&oi(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Ai(e,t){var n=qa();Ha(98>n?98:n,(function(){e(!0)})),Ha(97<n?97:n,(function(){var n=Qo.transition;Qo.transition=1;try{e(!1),t()}finally{Qo.transition=n}}))}function Pi(e,t,n){var r=ps(),a=fs(e),o={lane:a,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?o.next=o:(o.next=i.next,i.next=o),t.pending=o,i=e.alternate,e===Jo||null!==i&&i===Jo)ri=ni=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var l=t.lastRenderedState,s=i(l,n);if(o.eagerReducer=i,o.eagerState=s,cr(s,l))return}catch(c){}ms(e,a,r)}}var Ri={readContext:oo,useCallback:ai,useContext:ai,useEffect:ai,useImperativeHandle:ai,useLayoutEffect:ai,useMemo:ai,useReducer:ai,useRef:ai,useState:ai,useDebugValue:ai,useDeferredValue:ai,useTransition:ai,useMutableSource:ai,useOpaqueIdentifier:ai,unstable_isNewReconciler:!1},Ni={readContext:oo,useCallback:function(e,t){return li().memoizedState=[e,void 0===t?null:t],e},useContext:oo,useEffect:ki,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,yi(4,2,_i.bind(null,t,e),n)},useLayoutEffect:function(e,t){return yi(4,2,e,t)},useMemo:function(e,t){var n=li();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=li();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Pi.bind(null,Jo,e),[r.memoizedState,e]},useRef:bi,useState:gi,useDebugValue:Ci,useDeferredValue:function(e){var t=gi(e),n=t[0],r=t[1];return ki((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=gi(!1),t=e[0];return bi(e=Ai.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var r=li();return r.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},fi(r,e,t,n)},useOpaqueIdentifier:function(){if(Uo){var e=!1,t=function(e){return{$$typeof:D,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Yr++).toString(36))),Error(i(355))})),n=gi(t)[1];return 0==(2&Jo.mode)&&(Jo.flags|=516,hi(5,(function(){n("r:"+(Yr++).toString(36))}),void 0,null)),t}return gi(t="r:"+(Yr++).toString(36)),t},unstable_isNewReconciler:!1},Oi={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:ui,useRef:vi,useState:function(){return ui(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=ui(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=ui(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return ui(ci)[0]},unstable_isNewReconciler:!1},Ii={readContext:oo,useCallback:Ti,useContext:oo,useEffect:Si,useImperativeHandle:xi,useLayoutEffect:Ei,useMemo:Li,useReducer:di,useRef:vi,useState:function(){return di(ci)},useDebugValue:Ci,useDeferredValue:function(e){var t=di(ci),n=t[0],r=t[1];return Si((function(){var t=Qo.transition;Qo.transition=1;try{r(e)}finally{Qo.transition=t}}),[e]),n},useTransition:function(){var e=di(ci)[0];return[vi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ci)[0]},unstable_isNewReconciler:!1},Di=k.ReactCurrentOwner,Mi=!1;function ji(e,t,n,r){t.child=null===e?To(t,null,n,r):Co(t,e.child,n,r)}function Fi(e,t,n,r,a){n=n.render;var o=t.ref;return ao(t,a),r=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,r,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,ol(e,t,a))}function Bi(e,t,n,r,a,o){if(null===e){var i=n.type;return"function"!=typeof i||Hs(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Vs(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,zi(e,t,i,r,a,o))}return i=e.child,0==(a&o)&&(a=i.memoizedProps,(n=null!==(n=n.compare)?n:dr)(a,r)&&e.ref===t.ref)?ol(e,t,o):(t.flags|=1,(e=Zs(i,r)).ref=t.ref,e.return=t,t.child=e)}function zi(e,t,n,r,a,o){if(null!==e&&dr(e.memoizedProps,r)&&e.ref===t.ref){if(Mi=!1,0==(o&a))return t.lanes=e.lanes,ol(e,t,o);0!=(16384&e.flags)&&(Mi=!0)}return qi(e,t,n,r,o)}function Ui(e,t,n){var r=t.pendingProps,a=r.children,o=null!==e?e.memoizedState:null;if("hidden"===r.mode||"unstable-defer-without-hiding"===r.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},Ss(t,n);else{if(0==(1073741824&n))return e=null!==o?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},Ss(t,e),null;t.memoizedState={baseLanes:0},Ss(t,null!==o?o.baseLanes:n)}else null!==o?(r=o.baseLanes|n,t.memoizedState=null):r=n,Ss(t,r);return ji(e,t,a,n),t.child}function $i(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function qi(e,t,n,r,a){var o=ha(n)?ma:pa.current;return o=ga(t,o),ao(t,a),n=ii(e,t,n,r,o,a),null===e||Mi?(t.flags|=1,ji(e,t,n,a),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~a,ol(e,t,a))}function Gi(e,t,n,r,a){if(ha(n)){var o=!0;wa(t)}else o=!1;if(ao(t,a),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),yo(t,n,r),ko(t,n,r,a),r=!0;else if(null===e){var i=t.stateNode,l=t.memoizedProps;i.props=l;var s=i.context,c=n.contextType;"object"==typeof c&&null!==c?c=oo(c):c=ga(t,c=ha(n)?ma:pa.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==r||s!==c)&&wo(t,i,r,c),io=!1;var p=t.memoizedState;i.state=p,fo(t,r,i,a),s=t.memoizedState,l!==r||p!==s||fa.current||io?("function"==typeof u&&(ho(t,n,u,r),s=t.memoizedState),(l=io||vo(t,n,l,r,p,s,c))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=r,t.memoizedState=s),i.props=r,i.state=s,i.context=c,r=l):("function"==typeof i.componentDidMount&&(t.flags|=4),r=!1)}else{i=t.stateNode,so(e,t),l=t.memoizedProps,c=t.type===t.elementType?l:Ka(t.type,l),i.props=c,d=t.pendingProps,p=i.context,"object"==typeof(s=n.contextType)&&null!==s?s=oo(s):s=ga(t,s=ha(n)?ma:pa.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(l!==d||p!==s)&&wo(t,i,r,s),io=!1,p=t.memoizedState,i.state=p,fo(t,r,i,a);var m=t.memoizedState;l!==d||p!==m||fa.current||io?("function"==typeof f&&(ho(t,n,f,r),m=t.memoizedState),(c=io||vo(t,n,c,r,p,m,s))?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,m,s),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,m,s)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),t.memoizedProps=r,t.memoizedState=m),i.props=r,i.state=m,i.context=s,r=c):("function"!=typeof i.componentDidUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),r=!1)}return Hi(e,t,n,r,o,a)}function Hi(e,t,n,r,a,o){$i(e,t);var i=0!=(64&t.flags);if(!r&&!i)return a&&ka(t,n,!1),ol(e,t,o);r=t.stateNode,Di.current=t;var l=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=Co(t,e.child,null,o),t.child=Co(t,null,l,o)):ji(e,t,l,o),t.memoizedState=r.state,a&&ka(t,n,!0),t.child}function Zi(e){var t=e.stateNode;t.pendingContext?va(0,t.pendingContext,t.pendingContext!==t.context):t.context&&va(0,t.context,!1),Oo(e,t.containerInfo)}var Vi,Wi,Yi,Ki,Qi={dehydrated:null,retryLane:0};function Xi(e,t,n){var r,a=t.pendingProps,o=jo.current,i=!1;return(r=0!=(64&t.flags))||(r=(null===e||null!==e.memoizedState)&&0!=(2&o)),r?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===a.fallback||!0===a.unstable_avoidThisFallback||(o|=1),ua(jo,1&o),null===e?(void 0!==a.fallback&&Go(t),e=a.children,o=a.fallback,i?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,e):"number"==typeof a.unstable_expectedLoadTime?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,t.lanes=33554432,e):((n=Ys({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(a=tl(e,t,a.children,a.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=null===o?{baseLanes:n}:{baseLanes:o.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Qi,a):(n=el(e,t,a.children,n),t.memoizedState=null,n))}function Ji(e,t,n,r){var a=e.mode,o=e.child;return t={mode:"hidden",children:t},0==(2&a)&&null!==o?(o.childLanes=0,o.pendingProps=t):o=Ys(t,a,0,null),n=Ws(n,a,r,null),o.return=e,n.return=e,o.sibling=n,e.child=o,n}function el(e,t,n,r){var a=e.child;return e=a.sibling,n=Zs(a,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=r),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function tl(e,t,n,r,a){var o=t.mode,i=e.child;e=i.sibling;var l={mode:"hidden",children:n};return 0==(2&o)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=l,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=Zs(i,l),null!==e?r=Zs(e,r):(r=Ws(r,o,a,null)).flags|=2,r.return=t,n.return=t,n.sibling=r,t.child=n,r}function nl(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),ro(e.return,t)}function rl(e,t,n,r,a,o){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:a,lastEffect:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=r,i.tail=n,i.tailMode=a,i.lastEffect=o)}function al(e,t,n){var r=t.pendingProps,a=r.revealOrder,o=r.tail;if(ji(e,t,r.children,n),0!=(2&(r=jo.current)))r=1&r|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&nl(e,n);else if(19===e.tag)nl(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(ua(jo,r),0==(2&t.mode))t.memoizedState=null;else switch(a){case"forwards":for(n=t.child,a=null;null!==n;)null!==(e=n.alternate)&&null===Fo(e)&&(a=n),n=n.sibling;null===(n=a)?(a=t.child,t.child=null):(a=n.sibling,n.sibling=null),rl(t,!1,a,n,o,t.lastEffect);break;case"backwards":for(n=null,a=t.child,t.child=null;null!==a;){if(null!==(e=a.alternate)&&null===Fo(e)){t.child=a;break}e=a.sibling,a.sibling=n,n=a,a=e}rl(t,!0,n,null,o,t.lastEffect);break;case"together":rl(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function ol(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Ul|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=Zs(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Zs(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function il(e,t){if(!Uo)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function ll(e,t,n){var r=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return ha(t.type)&&ba(),null;case 3:return Io(),ca(fa),ca(pa),Yo(),(r=t.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Zo(t)?t.flags|=4:r.hydrate||(t.flags|=256)),Wi(t),null;case 5:Mo(t);var o=No(Ro.current);if(n=t.type,null!==e&&null!=t.stateNode)Yi(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=128);else{if(!r){if(null===t.stateNode)throw Error(i(166));return null}if(e=No(Ao.current),Zo(t)){r=t.stateNode,n=t.type;var l=t.memoizedProps;switch(r[Qr]=t,r[Xr]=l,n){case"dialog":Ar("cancel",r),Ar("close",r);break;case"iframe":case"object":case"embed":Ar("load",r);break;case"video":case"audio":for(e=0;e<xr.length;e++)Ar(xr[e],r);break;case"source":Ar("error",r);break;case"img":case"image":case"link":Ar("error",r),Ar("load",r);break;case"details":Ar("toggle",r);break;case"input":ee(r,l),Ar("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!l.multiple},Ar("invalid",r);break;case"textarea":se(r,l),Ar("invalid",r)}for(var c in Ee(n,l),e=null,l)l.hasOwnProperty(c)&&(o=l[c],"children"===c?"string"==typeof o?r.textContent!==o&&(e=["children",o]):"number"==typeof o&&r.textContent!==""+o&&(e=["children",""+o]):s.hasOwnProperty(c)&&null!=o&&"onScroll"===c&&Ar("scroll",r));switch(n){case"input":K(r),re(r,l,!0);break;case"textarea":K(r),ue(r);break;case"select":case"option":break;default:"function"==typeof l.onClick&&(r.onclick=Br)}r=e,t.updateQueue=r,null!==r&&(t.flags|=4)}else{switch(c=9===o.nodeType?o:o.ownerDocument,e===de.html&&(e=pe(n)),e===de.html?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[Qr]=t,e[Xr]=r,Vi(e,t,!1,!1),t.stateNode=e,c=_e(n,r),n){case"dialog":Ar("cancel",e),Ar("close",e),o=r;break;case"iframe":case"object":case"embed":Ar("load",e),o=r;break;case"video":case"audio":for(o=0;o<xr.length;o++)Ar(xr[o],e);o=r;break;case"source":Ar("error",e),o=r;break;case"img":case"image":case"link":Ar("error",e),Ar("load",e),o=r;break;case"details":Ar("toggle",e),o=r;break;case"input":ee(e,r),o=J(e,r),Ar("invalid",e);break;case"option":o=oe(e,r);break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=a({},r,{value:void 0}),Ar("invalid",e);break;case"textarea":se(e,r),o=le(e,r),Ar("invalid",e);break;default:o=r}Ee(n,o);var u=o;for(l in u)if(u.hasOwnProperty(l)){var d=u[l];"style"===l?ke(e,d):"dangerouslySetInnerHTML"===l?null!=(d=d?d.__html:void 0)&&he(e,d):"children"===l?"string"==typeof d?("textarea"!==n||""!==d)&&be(e,d):"number"==typeof d&&be(e,""+d):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(s.hasOwnProperty(l)?null!=d&&"onScroll"===l&&Ar("scroll",e):null!=d&&w(e,l,d,c))}switch(n){case"input":K(e),re(e,r,!1);break;case"textarea":K(e),ue(e);break;case"option":null!=r.value&&e.setAttribute("value",""+W(r.value));break;case"select":e.multiple=!!r.multiple,null!=(l=r.value)?ie(e,!!r.multiple,l,!1):null!=r.defaultValue&&ie(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Br)}$r(n,r)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Ki(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(i(166));n=No(Ro.current),No(Ao.current),Zo(t)?(r=t.stateNode,n=t.memoizedProps,r[Qr]=t,r.nodeValue!==n&&(t.flags|=4)):((r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[Qr]=t,t.stateNode=r)}return null;case 13:return ca(jo),r=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(r=null!==r,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Zo(t):n=null!==e.memoizedState,r&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&jo.current)?0===Fl&&(Fl=3):(0!==Fl&&3!==Fl||(Fl=4),null===Ol||0==(134217727&Ul)&&0==(134217727&$l)||vs(Ol,Dl))),(r||n)&&(t.flags|=4),null);case 4:return Io(),Wi(t),null===e&&Rr(t.stateNode.containerInfo),null;case 10:return no(t),null;case 19:if(ca(jo),null===(r=t.memoizedState))return null;if(l=0!=(64&t.flags),null===(c=r.rendering))if(l)il(r,!1);else{if(0!==Fl||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(c=Fo(e))){for(t.flags|=64,il(r,!1),null!==(l=c.updateQueue)&&(t.updateQueue=l,t.flags|=4),null===r.lastEffect&&(t.firstEffect=null),t.lastEffect=r.lastEffect,r=n,n=t.child;null!==n;)e=r,(l=n).flags&=2,l.nextEffect=null,l.firstEffect=null,l.lastEffect=null,null===(c=l.alternate)?(l.childLanes=0,l.lanes=e,l.child=null,l.memoizedProps=null,l.memoizedState=null,l.updateQueue=null,l.dependencies=null,l.stateNode=null):(l.childLanes=c.childLanes,l.lanes=c.lanes,l.child=c.child,l.memoizedProps=c.memoizedProps,l.memoizedState=c.memoizedState,l.updateQueue=c.updateQueue,l.type=c.type,e=c.dependencies,l.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return ua(jo,1&jo.current|2),t.child}e=e.sibling}null!==r.tail&&$a()>Zl&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432)}else{if(!l)if(null!==(e=Fo(c))){if(t.flags|=64,l=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),il(r,!0),null===r.tail&&"hidden"===r.tailMode&&!c.alternate&&!Uo)return null!==(t=t.lastEffect=r.lastEffect)&&(t.nextEffect=null),null}else 2*$a()-r.renderingStartTime>Zl&&1073741824!==n&&(t.flags|=64,l=!0,il(r,!1),t.lanes=33554432);r.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=r.last)?n.sibling=c:t.child=c,r.last=c)}return null!==r.tail?(n=r.tail,r.rendering=n,r.tail=n.sibling,r.lastEffect=t.lastEffect,r.renderingStartTime=$a(),n.sibling=null,t=jo.current,ua(jo,l?1&t|2:1&t),n):null;case 23:case 24:return Es(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==r.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function sl(e){switch(e.tag){case 1:ha(e.type)&&ba();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Io(),ca(fa),ca(pa),Yo(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Mo(e),null;case 13:return ca(jo),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return ca(jo),null;case 4:return Io(),null;case 10:return no(e),null;case 23:case 24:return Es(),null;default:return null}}function cl(e,t){try{var n="",r=t;do{n+=Z(r),r=r.return}while(r);var a=n}catch(o){a="\nError generating stack: "+o.message+"\n"+o.stack}return{value:e,source:t,stack:a}}function ul(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Vi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Wi=function(){},Yi=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,No(Ao.current);var i,l=null;switch(n){case"input":o=J(e,o),r=J(e,r),l=[];break;case"option":o=oe(e,o),r=oe(e,r),l=[];break;case"select":o=a({},o,{value:void 0}),r=a({},r,{value:void 0}),l=[];break;case"textarea":o=le(e,o),r=le(e,r),l=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Br)}for(d in Ee(n,r),n=null,o)if(!r.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(i in c)c.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(s.hasOwnProperty(d)?l||(l=[]):(l=l||[]).push(d,null));for(d in r){var u=r[d];if(c=null!=o?o[d]:void 0,r.hasOwnProperty(d)&&u!==c&&(null!=u||null!=c))if("style"===d)if(c){for(i in c)!c.hasOwnProperty(i)||u&&u.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in u)u.hasOwnProperty(i)&&c[i]!==u[i]&&(n||(n={}),n[i]=u[i])}else n||(l||(l=[]),l.push(d,n)),n=u;else"dangerouslySetInnerHTML"===d?(u=u?u.__html:void 0,c=c?c.__html:void 0,null!=u&&c!==u&&(l=l||[]).push(d,u)):"children"===d?"string"!=typeof u&&"number"!=typeof u||(l=l||[]).push(d,""+u):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(s.hasOwnProperty(d)?(null!=u&&"onScroll"===d&&Ar("scroll",e),l||c===u||(l=[])):"object"==typeof u&&null!==u&&u.$$typeof===D?u.toString():(l=l||[]).push(d,u))}n&&(l=l||[]).push("style",n);var d=l;(t.updateQueue=d)&&(t.flags|=4)}},Ki=function(e,t,n,r){n!==r&&(t.flags|=4)};var dl="function"==typeof WeakMap?WeakMap:Map;function pl(e,t,n){(n=co(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Kl||(Kl=!0,Ql=r),ul(0,t)},n}function fl(e,t,n){(n=co(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var a=t.value;n.payload=function(){return ul(0,t),r(a)}}var o=e.stateNode;return null!==o&&"function"==typeof o.componentDidCatch&&(n.callback=function(){"function"!=typeof r&&(null===Xl?Xl=new Set([this]):Xl.add(this),ul(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var ml="function"==typeof WeakSet?WeakSet:Set;function gl(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){zs(e,n)}else t.current=null}function hl(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Ka(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Zr(t.stateNode.containerInfo))}throw Error(i(163))}function bl(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var a=e;r=a.next,0!=(4&(a=a.tag))&&0!=(1&a)&&(js(n,e),Ms(n,e)),e=r}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(r=n.elementType===n.type?t.memoizedProps:Ka(n.type,t.memoizedProps),e.componentDidUpdate(r,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&mo(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}mo(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&$r(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&kt(n)))))}throw Error(i(163))}function vl(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)"function"==typeof(r=r.style).setProperty?r.setProperty("display","none","important"):r.display="none";else{r=n.stateNode;var a=n.memoizedProps.style;a=null!=a&&a.hasOwnProperty("display")?a.display:null,r.style.display=we("display",a)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function yl(e,t){if(Ea&&"function"==typeof Ea.onCommitFiberUnmount)try{Ea.onCommitFiberUnmount(Sa,t)}catch(o){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var r=n,a=r.destroy;if(r=r.tag,void 0!==a)if(0!=(4&r))js(t,n);else{r=t;try{a()}catch(o){zs(r,o)}}n=n.next}while(n!==e)}break;case 1:if(gl(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(o){zs(t,o)}break;case 5:gl(t);break;case 4:xl(e,t)}}function wl(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function kl(e){return 5===e.tag||3===e.tag||4===e.tag}function Sl(e){e:{for(var t=e.return;null!==t;){if(kl(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var r=!1;break;case 3:case 4:t=t.containerInfo,r=!0;break;default:throw Error(i(161))}16&n.flags&&(be(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||kl(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}r?El(e,n,t):_l(e,n,t)}function El(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Br));else if(4!==r&&null!==(e=e.child))for(El(e,t,n),e=e.sibling;null!==e;)El(e,t,n),e=e.sibling}function _l(e,t,n){var r=e.tag,a=5===r||6===r;if(a)e=a?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(_l(e,t,n),e=e.sibling;null!==e;)_l(e,t,n),e=e.sibling}function xl(e,t){for(var n,r,a=t,o=!1;;){if(!o){o=a.return;e:for(;;){if(null===o)throw Error(i(160));switch(n=o.stateNode,o.tag){case 5:r=!1;break e;case 3:case 4:n=n.containerInfo,r=!0;break e}o=o.return}o=!0}if(5===a.tag||6===a.tag){e:for(var l=e,s=a,c=s;;)if(yl(l,c),null!==c.child&&4!==c.tag)c.child.return=c,c=c.child;else{if(c===s)break e;for(;null===c.sibling;){if(null===c.return||c.return===s)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}r?(l=n,s=a.stateNode,8===l.nodeType?l.parentNode.removeChild(s):l.removeChild(s)):n.removeChild(a.stateNode)}else if(4===a.tag){if(null!==a.child){n=a.stateNode.containerInfo,r=!0,a.child.return=a,a=a.child;continue}}else if(yl(e,a),null!==a.child){a.child.return=a,a=a.child;continue}if(a===t)break;for(;null===a.sibling;){if(null===a.return||a.return===t)return;4===(a=a.return).tag&&(o=!1)}a.sibling.return=a.return,a=a.sibling}}function Cl(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var r=n=n.next;do{3==(3&r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){r=t.memoizedProps;var a=null!==e?e.memoizedProps:r;e=t.type;var o=t.updateQueue;if(t.updateQueue=null,null!==o){for(n[Xr]=r,"input"===e&&"radio"===r.type&&null!=r.name&&te(n,r),_e(e,a),t=_e(e,r),a=0;a<o.length;a+=2){var l=o[a],s=o[a+1];"style"===l?ke(n,s):"dangerouslySetInnerHTML"===l?he(n,s):"children"===l?be(n,s):w(n,l,s,t)}switch(e){case"input":ne(n,r);break;case"textarea":ce(n,r);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!r.multiple,null!=(o=r.value)?ie(n,!!r.multiple,o,!1):e!==!!r.multiple&&(null!=r.defaultValue?ie(n,!!r.multiple,r.defaultValue,!0):ie(n,!!r.multiple,r.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,kt(n.containerInfo)));case 13:return null!==t.memoizedState&&(Hl=$a(),vl(t.child,!0)),void Tl(t);case 19:return void Tl(t);case 23:case 24:return void vl(t,null!==t.memoizedState)}throw Error(i(163))}function Tl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new ml),t.forEach((function(t){var r=$s.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function Ll(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var Al=Math.ceil,Pl=k.ReactCurrentDispatcher,Rl=k.ReactCurrentOwner,Nl=0,Ol=null,Il=null,Dl=0,Ml=0,jl=sa(0),Fl=0,Bl=null,zl=0,Ul=0,$l=0,ql=0,Gl=null,Hl=0,Zl=1/0;function Vl(){Zl=$a()+500}var Wl,Yl=null,Kl=!1,Ql=null,Xl=null,Jl=!1,es=null,ts=90,ns=[],rs=[],as=null,os=0,is=null,ls=-1,ss=0,cs=0,us=null,ds=!1;function ps(){return 0!=(48&Nl)?$a():-1!==ls?ls:ls=$a()}function fs(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===qa()?1:2;if(0===ss&&(ss=zl),0!==Ya.transition){0!==cs&&(cs=null!==Gl?Gl.pendingLanes:0),e=ss;var t=4186112&~cs;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=qa(),0!=(4&Nl)&&98===e?e=Bt(12,ss):e=Bt(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ss),e}function ms(e,t,n){if(50<os)throw os=0,is=null,Error(i(185));if(null===(e=gs(e,t)))return null;$t(e,t,n),e===Ol&&($l|=t,4===Fl&&vs(e,Dl));var r=qa();1===t?0!=(8&Nl)&&0==(48&Nl)?ys(e):(hs(e,n),0===Nl&&(Vl(),Va())):(0==(4&Nl)||98!==r&&99!==r||(null===as?as=new Set([e]):as.add(e)),hs(e,n)),Gl=e}function gs(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function hs(e,t){for(var n=e.callbackNode,r=e.suspendedLanes,a=e.pingedLanes,o=e.expirationTimes,l=e.pendingLanes;0<l;){var s=31-qt(l),c=1<<s,u=o[s];if(-1===u){if(0==(c&r)||0!=(c&a)){u=t,Mt(c);var d=Dt;o[s]=10<=d?u+250:6<=d?u+5e3:-1}}else u<=t&&(e.expiredLanes|=c);l&=~c}if(r=jt(e,e===Ol?Dl:0),t=Dt,0===r)null!==n&&(n!==Ma&&Ca(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Ma&&Ca(n)}15===t?(n=ys.bind(null,e),null===Fa?(Fa=[n],Ba=xa(Ra,Wa)):Fa.push(n),n=Ma):14===t?n=Za(99,ys.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Za(n,bs.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function bs(e){if(ls=-1,cs=ss=0,0!=(48&Nl))throw Error(i(327));var t=e.callbackNode;if(Ds()&&e.callbackNode!==t)return null;var n=jt(e,e===Ol?Dl:0);if(0===n)return null;var r=n,a=Nl;Nl|=16;var o=Cs();for(Ol===e&&Dl===r||(Vl(),_s(e,r));;)try{As();break}catch(s){xs(e,s)}if(to(),Pl.current=o,Nl=a,null!==Il?r=0:(Ol=null,Dl=0,r=Fl),0!=(zl&$l))_s(e,0);else if(0!==r){if(2===r&&(Nl|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(n=Ft(e))&&(r=Ts(e,n))),1===r)throw t=Bl,_s(e,0),vs(e,n),hs(e,$a()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,r){case 0:case 1:throw Error(i(345));case 2:case 5:Ns(e);break;case 3:if(vs(e,n),(62914560&n)===n&&10<(r=Hl+500-$a())){if(0!==jt(e,0))break;if(((a=e.suspendedLanes)&n)!==n){ps(),e.pingedLanes|=e.suspendedLanes&a;break}e.timeoutHandle=Gr(Ns.bind(null,e),r);break}Ns(e);break;case 4:if(vs(e,n),(4186112&n)===n)break;for(r=e.eventTimes,a=-1;0<n;){var l=31-qt(n);o=1<<l,(l=r[l])>a&&(a=l),n&=~o}if(n=a,10<(n=(120>(n=$a()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Al(n/1960))-n)){e.timeoutHandle=Gr(Ns.bind(null,e),n);break}Ns(e);break;default:throw Error(i(329))}}return hs(e,$a()),e.callbackNode===t?bs.bind(null,e):null}function vs(e,t){for(t&=~ql,t&=~$l,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-qt(t),r=1<<n;e[n]=-1,t&=~r}}function ys(e){if(0!=(48&Nl))throw Error(i(327));if(Ds(),e===Ol&&0!=(e.expiredLanes&Dl)){var t=Dl,n=Ts(e,t);0!=(zl&$l)&&(n=Ts(e,t=jt(e,t)))}else n=Ts(e,t=jt(e,0));if(0!==e.tag&&2===n&&(Nl|=64,e.hydrate&&(e.hydrate=!1,Zr(e.containerInfo)),0!==(t=Ft(e))&&(n=Ts(e,t))),1===n)throw n=Bl,_s(e,0),vs(e,t),hs(e,$a()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,Ns(e),hs(e,$a()),null}function ws(e,t){var n=Nl;Nl|=1;try{return e(t)}finally{0===(Nl=n)&&(Vl(),Va())}}function ks(e,t){var n=Nl;Nl&=-2,Nl|=8;try{return e(t)}finally{0===(Nl=n)&&(Vl(),Va())}}function Ss(e,t){ua(jl,Ml),Ml|=t,zl|=t}function Es(){Ml=jl.current,ca(jl)}function _s(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,Hr(n)),null!==Il)for(n=Il.return;null!==n;){var r=n;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&ba();break;case 3:Io(),ca(fa),ca(pa),Yo();break;case 5:Mo(r);break;case 4:Io();break;case 13:case 19:ca(jo);break;case 10:no(r);break;case 23:case 24:Es()}n=n.return}Ol=e,Il=Zs(e.current,null),Dl=Ml=zl=t,Fl=0,Bl=null,ql=$l=Ul=0}function xs(e,t){for(;;){var n=Il;try{if(to(),Ko.current=Ri,ni){for(var r=Jo.memoizedState;null!==r;){var a=r.queue;null!==a&&(a.pending=null),r=r.next}ni=!1}if(Xo=0,ti=ei=Jo=null,ri=!1,Rl.current=null,null===n||null===n.return){Fl=1,Bl=t,Il=null;break}e:{var o=e,i=n.return,l=n,s=t;if(t=Dl,l.flags|=2048,l.firstEffect=l.lastEffect=null,null!==s&&"object"==typeof s&&"function"==typeof s.then){var c=s;if(0==(2&l.mode)){var u=l.alternate;u?(l.updateQueue=u.updateQueue,l.memoizedState=u.memoizedState,l.lanes=u.lanes):(l.updateQueue=null,l.memoizedState=null)}var d=0!=(1&jo.current),p=i;do{var f;if(f=13===p.tag){var m=p.memoizedState;if(null!==m)f=null!==m.dehydrated;else{var g=p.memoizedProps;f=void 0!==g.fallback&&(!0!==g.unstable_avoidThisFallback||!d)}}if(f){var h=p.updateQueue;if(null===h){var b=new Set;b.add(c),p.updateQueue=b}else h.add(c);if(0==(2&p.mode)){if(p.flags|=64,l.flags|=16384,l.flags&=-2981,1===l.tag)if(null===l.alternate)l.tag=17;else{var v=co(-1,1);v.tag=2,uo(l,v)}l.lanes|=1;break e}s=void 0,l=t;var y=o.pingCache;if(null===y?(y=o.pingCache=new dl,s=new Set,y.set(c,s)):void 0===(s=y.get(c))&&(s=new Set,y.set(c,s)),!s.has(l)){s.add(l);var w=Us.bind(null,o,c,l);c.then(w,w)}p.flags|=4096,p.lanes=t;break e}p=p.return}while(null!==p);s=Error((V(l.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Fl&&(Fl=2),s=cl(s,l),p=i;do{switch(p.tag){case 3:o=s,p.flags|=4096,t&=-t,p.lanes|=t,po(p,pl(0,o,t));break e;case 1:o=s;var k=p.type,S=p.stateNode;if(0==(64&p.flags)&&("function"==typeof k.getDerivedStateFromError||null!==S&&"function"==typeof S.componentDidCatch&&(null===Xl||!Xl.has(S)))){p.flags|=4096,t&=-t,p.lanes|=t,po(p,fl(p,o,t));break e}}p=p.return}while(null!==p)}Rs(n)}catch(E){t=E,Il===n&&null!==n&&(Il=n=n.return);continue}break}}function Cs(){var e=Pl.current;return Pl.current=Ri,null===e?Ri:e}function Ts(e,t){var n=Nl;Nl|=16;var r=Cs();for(Ol===e&&Dl===t||_s(e,t);;)try{Ls();break}catch(a){xs(e,a)}if(to(),Nl=n,Pl.current=r,null!==Il)throw Error(i(261));return Ol=null,Dl=0,Fl}function Ls(){for(;null!==Il;)Ps(Il)}function As(){for(;null!==Il&&!Ta();)Ps(Il)}function Ps(e){var t=Wl(e.alternate,e,Ml);e.memoizedProps=e.pendingProps,null===t?Rs(e):Il=t,Rl.current=null}function Rs(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ll(n,t,Ml)))return void(Il=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&Ml)||0==(4&n.mode)){for(var r=0,a=n.child;null!==a;)r|=a.lanes|a.childLanes,a=a.sibling;n.childLanes=r}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=sl(t)))return n.flags&=2047,void(Il=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Il=t);Il=t=e}while(null!==t);0===Fl&&(Fl=5)}function Ns(e){var t=qa();return Ha(99,Os.bind(null,e,t)),null}function Os(e,t){do{Ds()}while(null!==es);if(0!=(48&Nl))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var r=n.lanes|n.childLanes,a=r,o=e.pendingLanes&~a;e.pendingLanes=a,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=a,e.mutableReadLanes&=a,e.entangledLanes&=a,a=e.entanglements;for(var l=e.eventTimes,s=e.expirationTimes;0<o;){var c=31-qt(o),u=1<<c;a[c]=0,l[c]=-1,s[c]=-1,o&=~u}if(null!==as&&0==(24&r)&&as.has(e)&&as.delete(e),e===Ol&&(Il=Ol=null,Dl=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,r=n.firstEffect):r=n:r=n.firstEffect,null!==r){if(a=Nl,Nl|=32,Rl.current=null,zr=Wt,hr(l=gr())){if("selectionStart"in l)s={start:l.selectionStart,end:l.selectionEnd};else e:if(s=(s=l.ownerDocument)&&s.defaultView||window,(u=s.getSelection&&s.getSelection())&&0!==u.rangeCount){s=u.anchorNode,o=u.anchorOffset,c=u.focusNode,u=u.focusOffset;try{s.nodeType,c.nodeType}catch(C){s=null;break e}var d=0,p=-1,f=-1,m=0,g=0,h=l,b=null;t:for(;;){for(var v;h!==s||0!==o&&3!==h.nodeType||(p=d+o),h!==c||0!==u&&3!==h.nodeType||(f=d+u),3===h.nodeType&&(d+=h.nodeValue.length),null!==(v=h.firstChild);)b=h,h=v;for(;;){if(h===l)break t;if(b===s&&++m===o&&(p=d),b===c&&++g===u&&(f=d),null!==(v=h.nextSibling))break;b=(h=b).parentNode}h=v}s=-1===p||-1===f?null:{start:p,end:f}}else s=null;s=s||{start:0,end:0}}else s=null;Ur={focusedElem:l,selectionRange:s},Wt=!1,us=null,ds=!1,Yl=r;do{try{Is()}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);us=null,Yl=r;do{try{for(l=e;null!==Yl;){var y=Yl.flags;if(16&y&&be(Yl.stateNode,""),128&y){var w=Yl.alternate;if(null!==w){var k=w.ref;null!==k&&("function"==typeof k?k(null):k.current=null)}}switch(1038&y){case 2:Sl(Yl),Yl.flags&=-3;break;case 6:Sl(Yl),Yl.flags&=-3,Cl(Yl.alternate,Yl);break;case 1024:Yl.flags&=-1025;break;case 1028:Yl.flags&=-1025,Cl(Yl.alternate,Yl);break;case 4:Cl(Yl.alternate,Yl);break;case 8:xl(l,s=Yl);var S=s.alternate;wl(s),null!==S&&wl(S)}Yl=Yl.nextEffect}}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);if(k=Ur,w=gr(),y=k.focusedElem,l=k.selectionRange,w!==y&&y&&y.ownerDocument&&mr(y.ownerDocument.documentElement,y)){null!==l&&hr(y)&&(w=l.start,void 0===(k=l.end)&&(k=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(k,y.value.length)):(k=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(k=k.getSelection(),s=y.textContent.length,S=Math.min(l.start,s),l=void 0===l.end?S:Math.min(l.end,s),!k.extend&&S>l&&(s=l,l=S,S=s),s=fr(y,S),o=fr(y,l),s&&o&&(1!==k.rangeCount||k.anchorNode!==s.node||k.anchorOffset!==s.offset||k.focusNode!==o.node||k.focusOffset!==o.offset)&&((w=w.createRange()).setStart(s.node,s.offset),k.removeAllRanges(),S>l?(k.addRange(w),k.extend(o.node,o.offset)):(w.setEnd(o.node,o.offset),k.addRange(w))))),w=[];for(k=y;k=k.parentNode;)1===k.nodeType&&w.push({element:k,left:k.scrollLeft,top:k.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(k=w[y]).element.scrollLeft=k.left,k.element.scrollTop=k.top}Wt=!!zr,Ur=zr=null,e.current=n,Yl=r;do{try{for(y=e;null!==Yl;){var E=Yl.flags;if(36&E&&bl(y,Yl.alternate,Yl),128&E){w=void 0;var _=Yl.ref;if(null!==_){var x=Yl.stateNode;Yl.tag,w=x,"function"==typeof _?_(w):_.current=w}}Yl=Yl.nextEffect}}catch(C){if(null===Yl)throw Error(i(330));zs(Yl,C),Yl=Yl.nextEffect}}while(null!==Yl);Yl=null,ja(),Nl=a}else e.current=n;if(Jl)Jl=!1,es=e,ts=t;else for(Yl=r;null!==Yl;)t=Yl.nextEffect,Yl.nextEffect=null,8&Yl.flags&&((E=Yl).sibling=null,E.stateNode=null),Yl=t;if(0===(r=e.pendingLanes)&&(Xl=null),1===r?e===is?os++:(os=0,is=e):os=0,n=n.stateNode,Ea&&"function"==typeof Ea.onCommitFiberRoot)try{Ea.onCommitFiberRoot(Sa,n,void 0,64==(64&n.current.flags))}catch(C){}if(hs(e,$a()),Kl)throw Kl=!1,e=Ql,Ql=null,e;return 0!=(8&Nl)||Va(),null}function Is(){for(;null!==Yl;){var e=Yl.alternate;ds||null===us||(0!=(8&Yl.flags)?Je(Yl,us)&&(ds=!0):13===Yl.tag&&Ll(e,Yl)&&Je(Yl,us)&&(ds=!0));var t=Yl.flags;0!=(256&t)&&hl(e,Yl),0==(512&t)||Jl||(Jl=!0,Za(97,(function(){return Ds(),null}))),Yl=Yl.nextEffect}}function Ds(){if(90!==ts){var e=97<ts?97:ts;return ts=90,Ha(e,Fs)}return!1}function Ms(e,t){ns.push(t,e),Jl||(Jl=!0,Za(97,(function(){return Ds(),null})))}function js(e,t){rs.push(t,e),Jl||(Jl=!0,Za(97,(function(){return Ds(),null})))}function Fs(){if(null===es)return!1;var e=es;if(es=null,0!=(48&Nl))throw Error(i(331));var t=Nl;Nl|=32;var n=rs;rs=[];for(var r=0;r<n.length;r+=2){var a=n[r],o=n[r+1],l=a.destroy;if(a.destroy=void 0,"function"==typeof l)try{l()}catch(c){if(null===o)throw Error(i(330));zs(o,c)}}for(n=ns,ns=[],r=0;r<n.length;r+=2){a=n[r],o=n[r+1];try{var s=a.create;a.destroy=s()}catch(c){if(null===o)throw Error(i(330));zs(o,c)}}for(s=e.current.firstEffect;null!==s;)e=s.nextEffect,s.nextEffect=null,8&s.flags&&(s.sibling=null,s.stateNode=null),s=e;return Nl=t,Va(),!0}function Bs(e,t,n){uo(e,t=pl(0,t=cl(n,t),1)),t=ps(),null!==(e=gs(e,1))&&($t(e,1,t),hs(e,t))}function zs(e,t){if(3===e.tag)Bs(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Bs(n,e,t);break}if(1===n.tag){var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Xl||!Xl.has(r))){var a=fl(n,e=cl(t,e),1);if(uo(n,a),a=ps(),null!==(n=gs(n,1)))$t(n,1,a),hs(n,a);else if("function"==typeof r.componentDidCatch&&(null===Xl||!Xl.has(r)))try{r.componentDidCatch(t,e)}catch(o){}break}}n=n.return}}function Us(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=ps(),e.pingedLanes|=e.suspendedLanes&n,Ol===e&&(Dl&n)===n&&(4===Fl||3===Fl&&(62914560&Dl)===Dl&&500>$a()-Hl?_s(e,0):ql|=n),hs(e,t)}function $s(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===qa()?1:2:(0===ss&&(ss=zl),0===(t=zt(62914560&~ss))&&(t=4194304))),n=ps(),null!==(e=gs(e,t))&&($t(e,t,n),hs(e,n))}function qs(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Gs(e,t,n,r){return new qs(e,t,n,r)}function Hs(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Zs(e,t){var n=e.alternate;return null===n?((n=Gs(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Vs(e,t,n,r,a,o){var l=2;if(r=e,"function"==typeof e)Hs(e)&&(l=1);else if("string"==typeof e)l=5;else e:switch(e){case _:return Ws(n.children,a,o,t);case M:l=8,a|=16;break;case x:l=8,a|=1;break;case C:return(e=Gs(12,n,t,8|a)).elementType=C,e.type=C,e.lanes=o,e;case P:return(e=Gs(13,n,t,a)).type=P,e.elementType=P,e.lanes=o,e;case R:return(e=Gs(19,n,t,a)).elementType=R,e.lanes=o,e;case j:return Ys(n,a,o,t);case F:return(e=Gs(24,n,t,a)).elementType=F,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:l=10;break e;case L:l=9;break e;case A:l=11;break e;case N:l=14;break e;case O:l=16,r=null;break e;case I:l=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=Gs(l,n,t,a)).elementType=e,t.type=r,t.lanes=o,t}function Ws(e,t,n,r){return(e=Gs(7,e,r,t)).lanes=n,e}function Ys(e,t,n,r){return(e=Gs(23,e,r,t)).elementType=j,e.lanes=n,e}function Ks(e,t,n){return(e=Gs(6,e,null,t)).lanes=n,e}function Qs(e,t,n){return(t=Gs(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Xs(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Ut(0),this.expirationTimes=Ut(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ut(0),this.mutableSourceEagerHydrationData=null}function Js(e,t,n,r){var a=t.current,o=ps(),l=fs(a);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var s=n;do{switch(s.tag){case 3:s=s.stateNode.context;break t;case 1:if(ha(s.type)){s=s.stateNode.__reactInternalMemoizedMergedChildContext;break t}}s=s.return}while(null!==s);throw Error(i(171))}if(1===n.tag){var c=n.type;if(ha(c)){n=ya(n,c,s);break e}}n=s}else n=da;return null===t.context?t.context=n:t.pendingContext=n,(t=co(o,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),uo(a,t),ms(a,l,o),l}function ec(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function tc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function nc(e,t){tc(e,t),(e=e.alternate)&&tc(e,t)}function rc(e,t,n){var r=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Xs(e,t,null!=n&&!0===n.hydrate),t=Gs(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,lo(t),e[Jr]=n.current,Rr(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var a=(t=r[e])._getVersion;a=a(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,a]:n.mutableSourceEagerHydrationData.push(t,a)}this._internalRoot=n}function ac(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function oc(e,t,n,r,a){var o=n._reactRootContainer;if(o){var i=o._internalRoot;if("function"==typeof a){var l=a;a=function(){var e=ec(i);l.call(e)}}Js(t,i,e,a)}else{if(o=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new rc(e,0,t?{hydrate:!0}:void 0)}(n,r),i=o._internalRoot,"function"==typeof a){var s=a;a=function(){var e=ec(i);s.call(e)}}ks((function(){Js(t,i,e,a)}))}return ec(i)}function ic(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!ac(t))throw Error(i(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:E,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)}Wl=function(e,t,n){var r=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||fa.current)Mi=!0;else{if(0==(n&r)){switch(Mi=!1,t.tag){case 3:Zi(t),Vo();break;case 5:Do(t);break;case 1:ha(t.type)&&wa(t);break;case 4:Oo(t,t.stateNode.containerInfo);break;case 10:r=t.memoizedProps.value;var a=t.type._context;ua(Qa,a._currentValue),a._currentValue=r;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Xi(e,t,n):(ua(jo,1&jo.current),null!==(t=ol(e,t,n))?t.sibling:null);ua(jo,1&jo.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(64&e.flags)){if(r)return al(e,t,n);t.flags|=64}if(null!==(a=t.memoizedState)&&(a.rendering=null,a.tail=null,a.lastEffect=null),ua(jo,jo.current),r)break;return null;case 23:case 24:return t.lanes=0,Ui(e,t,n)}return ol(e,t,n)}Mi=0!=(16384&e.flags)}else Mi=!1;switch(t.lanes=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=ga(t,pa.current),ao(t,n),a=ii(null,t,r,e,a,n),t.flags|=1,"object"==typeof a&&null!==a&&"function"==typeof a.render&&void 0===a.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,ha(r)){var o=!0;wa(t)}else o=!1;t.memoizedState=null!==a.state&&void 0!==a.state?a.state:null,lo(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&ho(t,r,l,e),a.updater=bo,t.stateNode=a,a._reactInternals=t,ko(t,r,e,n),t=Hi(null,t,r,!0,o,n)}else t.tag=0,ji(null,t,a,n),t=t.child;return t;case 16:a=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,a=(o=a._init)(a._payload),t.type=a,o=t.tag=function(e){if("function"==typeof e)return Hs(e)?1:0;if(null!=e){if((e=e.$$typeof)===A)return 11;if(e===N)return 14}return 2}(a),e=Ka(a,e),o){case 0:t=qi(null,t,a,e,n);break e;case 1:t=Gi(null,t,a,e,n);break e;case 11:t=Fi(null,t,a,e,n);break e;case 14:t=Bi(null,t,a,Ka(a.type,e),r,n);break e}throw Error(i(306,a,""))}return t;case 0:return r=t.type,a=t.pendingProps,qi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 1:return r=t.type,a=t.pendingProps,Gi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 3:if(Zi(t),r=t.updateQueue,null===e||null===r)throw Error(i(282));if(r=t.pendingProps,a=null!==(a=t.memoizedState)?a.element:null,so(e,t),fo(t,r,null,n),(r=t.memoizedState.element)===a)Vo(),t=ol(e,t,n);else{if((o=(a=t.stateNode).hydrate)&&(zo=Vr(t.stateNode.containerInfo.firstChild),Bo=t,o=Uo=!0),o){if(null!=(e=a.mutableSourceEagerHydrationData))for(a=0;a<e.length;a+=2)(o=e[a])._workInProgressVersionPrimary=e[a+1],Wo.push(o);for(n=To(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else ji(e,t,r,n),Vo();t=t.child}return t;case 5:return Do(t),null===e&&Go(t),r=t.type,a=t.pendingProps,o=null!==e?e.memoizedProps:null,l=a.children,qr(r,a)?l=null:null!==o&&qr(r,o)&&(t.flags|=16),$i(e,t),ji(e,t,l,n),t.child;case 6:return null===e&&Go(t),null;case 13:return Xi(e,t,n);case 4:return Oo(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Co(t,null,r,n):ji(e,t,r,n),t.child;case 11:return r=t.type,a=t.pendingProps,Fi(e,t,r,a=t.elementType===r?a:Ka(r,a),n);case 7:return ji(e,t,t.pendingProps,n),t.child;case 8:case 12:return ji(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,a=t.pendingProps,l=t.memoizedProps,o=a.value;var s=t.type._context;if(ua(Qa,s._currentValue),s._currentValue=o,null!==l)if(s=l.value,0===(o=cr(s,o)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(s,o):1073741823))){if(l.children===a.children&&!fa.current){t=ol(e,t,n);break e}}else for(null!==(s=t.child)&&(s.return=t);null!==s;){var c=s.dependencies;if(null!==c){l=s.child;for(var u=c.firstContext;null!==u;){if(u.context===r&&0!=(u.observedBits&o)){1===s.tag&&((u=co(-1,n&-n)).tag=2,uo(s,u)),s.lanes|=n,null!==(u=s.alternate)&&(u.lanes|=n),ro(s.return,n),c.lanes|=n;break}u=u.next}}else l=10===s.tag&&s.type===t.type?null:s.child;if(null!==l)l.return=s;else for(l=s;null!==l;){if(l===t){l=null;break}if(null!==(s=l.sibling)){s.return=l.return,l=s;break}l=l.return}s=l}ji(e,t,a.children,n),t=t.child}return t;case 9:return a=t.type,r=(o=t.pendingProps).children,ao(t,n),r=r(a=oo(a,o.unstable_observedBits)),t.flags|=1,ji(e,t,r,n),t.child;case 14:return o=Ka(a=t.type,t.pendingProps),Bi(e,t,a,o=Ka(a.type,o),r,n);case 15:return zi(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,a=t.pendingProps,a=t.elementType===r?a:Ka(r,a),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,ha(r)?(e=!0,wa(t)):e=!1,ao(t,n),yo(t,r,a),ko(t,r,a,n),Hi(null,t,r,!0,e,n);case 19:return al(e,t,n);case 23:case 24:return Ui(e,t,n)}throw Error(i(156,t.tag))},rc.prototype.render=function(e){Js(e,this._internalRoot,null,null)},rc.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;Js(null,e,null,(function(){t[Jr]=null}))},et=function(e){13===e.tag&&(ms(e,4,ps()),nc(e,4))},tt=function(e){13===e.tag&&(ms(e,67108864,ps()),nc(e,67108864))},nt=function(e){if(13===e.tag){var t=ps(),n=fs(e);ms(e,n,t),nc(e,n)}},rt=function(e,t){return t()},Ce=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var a=aa(r);if(!a)throw Error(i(90));Q(r),ne(r,a)}}}break;case"textarea":ce(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Ne=ws,Oe=function(e,t,n,r,a){var o=Nl;Nl|=4;try{return Ha(98,e.bind(null,t,n,r,a))}finally{0===(Nl=o)&&(Vl(),Va())}},Ie=function(){0==(49&Nl)&&(function(){if(null!==as){var e=as;as=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,hs(e,$a())}))}Va()}(),Ds())},De=function(e,t){var n=Nl;Nl|=2;try{return e(t)}finally{0===(Nl=n)&&(Vl(),Va())}};var lc={Events:[na,ra,aa,Pe,Re,Ds,{current:!1}]},sc={findFiberByHostInstance:ta,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},cc={bundleType:sc.bundleType,version:sc.version,rendererPackageName:sc.rendererPackageName,rendererConfig:sc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:k.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Xe(e))?null:e.stateNode},findFiberByHostInstance:sc.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var uc=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!uc.isDisabled&&uc.supportsFiber)try{Sa=uc.inject(cc),Ea=uc}catch(ge){}}t.hydrate=function(e,t,n){if(!ac(t))throw Error(i(200));return oc(null,e,t,!0,n)}},3935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(4448)},9590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,a="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var l,s,c,u;if(Array.isArray(e)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(!o(e[s],i[s]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;for(u=e.entries();!(s=u.next()).done;)if(!o(s.value[1],i.get(s.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(s=u.next()).done;)if(!i.has(s.value[0]))return!1;return!0}if(a&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((l=e.length)!=i.length)return!1;for(s=l;0!=s--;)if(e[s]!==i[s])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((l=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(s=l;0!=s--;)if(!Object.prototype.hasOwnProperty.call(i,c[s]))return!1;if(t&&e instanceof Element)return!1;for(s=l;0!=s--;)if(("_owner"!==c[s]&&"__v"!==c[s]&&"__o"!==c[s]||!e.$$typeof)&&!o(e[c[s]],i[c[s]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>H,ql:()=>J});var r=n(7294),a=n(5697),o=n.n(a),i=n(9590),l=n.n(i),s=n(1143),c=n.n(s),u=n(6774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function g(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(h).map((function(e){return h[e]})),k={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},S=Object.keys(k).reduce((function(e,t){return e[k[t]]=t,e}),{}),E=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},_=function(e){var t=E(e,h.TITLE),n=E(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=E(e,"defaultTitle");return t||r||void 0},x=function(e){return E(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a<r.length;a+=1){var o=r[a].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},L=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var a={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var l=o[i],s=l.toLowerCase();-1===t.indexOf(s)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===s&&"stylesheet"===e[s].toLowerCase()||(n=s),-1===t.indexOf(l)||"innerHTML"!==l&&"cssText"!==l&&"itemprop"!==l||(n=l)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),a[n]||(a[n]={}),!r[n][c]&&(a[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(a),i=0;i<o.length;i+=1){var l=o[i],s=p({},r[l],a[l]);r[l]=s}return e}),[]).reverse()},A=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},R=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},O=[h.NOSCRIPT,h.SCRIPT,h.STYLE],I=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},D=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},M=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[k[n]||n]=e[n],t}),t)},j=function(e,t){return t.map((function(t,n){var a,o=((a={key:n})["data-rh"]=!0,a);return Object.keys(t).forEach((function(e){var n=k[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),r.createElement(e,o)}))},F=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(a={key:e=t.title})["data-rh"]=!0,o=M(n,a),[r.createElement(h.TITLE,o,e)];var e,n,a,o},toString:function(){return function(e,t,n,r){var a=D(n),o=P(t);return a?"<"+e+' data-rh="true" '+a+">"+I(o,r)+"</"+e+">":"<"+e+' data-rh="true">'+I(o,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return M(t)},toString:function(){return D(t)}};default:return{toComponent:function(){return j(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+I(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===O.indexOf(e);return t+"<"+e+' data-rh="true" '+a+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,l=e.title,s=void 0===l?"":l,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,a=R(e.metaTags,y),o=R(t,b),i=R(n,v);return{priorityMethods:{toComponent:function(){return[].concat(j(h.META,a.priority),j(h.LINK,o.priority),j(h.SCRIPT,i.priority))},toString:function(){return F(h.META,a.priority,r)+" "+F(h.LINK,o.priority,r)+" "+F(h.SCRIPT,i.priority,r)}},metaTags:a.default,linkTags:o.default,scriptTags:i.default}}(e);f=m.priorityMethods,u=m.linkTags,d=m.metaTags,p=m.scriptTags}return{priority:f,base:F(h.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",a,r),link:F(h.LINK,u,r),meta:F(h.META,d,r),noscript:F(h.NOSCRIPT,o,r),script:F(h.SCRIPT,p,r),style:F(h.STYLE,i,r),title:F(h.TITLE,{title:s,titleAttributes:c},r)}},z=[],U=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},$=r.createContext({}),q=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),G="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new U(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement($.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=G,H.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var Z=function(e,t){var n,r=document.head||document.querySelector(h.HEAD),a=r.querySelectorAll(e+"[data-rh]"),o=[].slice.call(a),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&("innerHTML"===a?r.innerHTML=t.innerHTML:"cssText"===a?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(a,void 0===t[a]?"":t[a]));r.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,r.isEqualNode(e)}))?o.splice(n,1):i.push(r)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:o,newTags:i}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l<i.length;l+=1){var s=i[l],c=t[s]||"";n.getAttribute(s)!==c&&n.setAttribute(s,c),-1===a.indexOf(s)&&a.push(s);var u=o.indexOf(s);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},W=function(e,t){var n=e.baseTag,r=e.htmlAttributes,a=e.linkTags,o=e.metaTags,i=e.noscriptTags,l=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;V(h.BODY,e.bodyAttributes),V(h.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),V(h.TITLE,t)}(u,d);var p={baseTag:Z(h.BASE,n),linkTags:Z(h.LINK,a),metaTags:Z(h.META,o),noscriptTags:Z(h.NOSCRIPT,i),scriptTags:Z(h.SCRIPT,s),styleTags:Z(h.STYLE,c)},f={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),l(e,f,m)},Y=null,K=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,a=null,o=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:E(e,"defer"),encode:E(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:L(h.LINK,["rel","href"],e),metaTags:L(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:L(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:x(e),scriptTags:L(h.SCRIPT,["src","innerHTML"],e),styleTags:L(h.STYLE,["cssText"],e),title:_(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:A(e,"prioritizeSeoTags")});H.canUseDOM?(t=o,Y&&cancelAnimationFrame(Y),t.defer?Y=requestAnimationFrame((function(){W(t,(function(){Y=null}))})):(W(t),Y=null)):B&&(a=B(o)),r(a)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);K.propTypes={context:q.isRequired},K.displayName="HelmetDispatcher";var Q=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!l()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case h.TITLE:return p({},a,((t={})[r.type]=i,t.titleAttributes=p({},o),t));case h.BODY:return p({},a,{bodyAttributes:p({},o)});case h.HTML:return p({},a,{htmlAttributes:p({},o)});default:return p({},a,((n={})[r.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,a={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,o=r.children,i=g(r,Q),l=Object.keys(i).reduce((function(e,t){return e[S[t]||t]=i[t],e}),{}),s=e.type;switch("symbol"==typeof s?s=s.toString():n.warnOnInvalidChildren(e,o),s){case h.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:a=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:a,newChildProps:l,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:l,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(a,t)},n.render=function(){var e=this.props,t=e.children,n=g(e,X),a=p({},n),o=n.helmetData;return t&&(a=this.mapChildrenToProps(t,a)),!o||o instanceof U||(o=new U(o.context,o.instances)),o?r.createElement(K,p({},a,{context:o.value,helmetData:void 0})):r.createElement($.Consumer,null,(function(e){return r.createElement(K,p({},a,{context:e}))}))},t}(r.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},9921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,a=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,g=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function k(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case o:case l:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case h:case g:case s:return e;default:return t}}case a:return t}}}function S(e){return k(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=p,t.Fragment=o,t.Lazy=h,t.Memo=g,t.Portal=a,t.Profiler=l,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return S(e)||k(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return k(e)===c},t.isContextProvider=function(e){return k(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return k(e)===p},t.isFragment=function(e){return k(e)===o},t.isLazy=function(e){return k(e)===h},t.isMemo=function(e){return k(e)===g},t.isPortal=function(e){return k(e)===a},t.isProfiler=function(e){return k(e)===l},t.isStrictMode=function(e){return k(e)===i},t.isSuspense=function(e){return k(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===l||e===i||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===g||e.$$typeof===s||e.$$typeof===c||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=k},9864:(e,t,n)=>{"use strict";e.exports=n(9921)},8356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var l=n(7294),s=n(5697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var a=d(e[r]);a.loading?t.loading=!0:(t.loaded[r]=a.loaded,t.error=a.error),n.push(a.promise),a.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return l.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),g=null;function h(){return g||(g=e(m.loader)),g.promise}return c.push(h),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=d=function(t){function n(n){var r;return o(a(a(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),g=e(m.loader),r._loadModule()})),h(),r.state={error:g.error,pastDelay:!1,timedOut:!1,loading:g.loading,loaded:g.loaded},r}r(n,t),n.preload=function(){return h()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.loadable.report(t)})),g.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:g.error,loaded:g.loaded,loading:g.loading}),e._clearTimeouts()};g.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?l.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(l.Component),o(d,"contextTypes",{loadable:s.shape({report:s.func.isRequired})}),p}function g(e){return m(d,e)}g.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return l.Children.only(this.props.children)},t}(l.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}o(h,"propTypes",{report:s.func.isRequired}),o(h,"childContextTypes",{loadable:s.shape({report:s.func.isRequired}).isRequired}),g.Capture=h,g.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},g.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=g},8790:(e,t,n)=>{"use strict";n.d(t,{H:()=>l,f:()=>i});var r=n(6550),a=n(7462),o=n(7294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var a=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return a&&(n.push({route:e,match:a}),e.routes&&i(e.routes,t,n)),a})),n}function l(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(r.rs,n,e.map((function(e,n){return o.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,a.Z)({},n,{},t,{route:e})):o.createElement(e.component,(0,a.Z)({},n,t,{route:e}))}})}))):null}},3727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>u,rU:()=>h});var r=n(6550),a=n(5068),o=n(7294),i=n(9318),l=n(7462),s=n(3366),c=n(2177),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.lX)(t.props),t}return(0,a.Z)(t,e),t.prototype.render=function(){return o.createElement(r.F0,{history:this.history,children:this.props.children})},t}(o.Component);o.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},f=function(e){return e},m=o.forwardRef;void 0===m&&(m=f);var g=m((function(e,t){var n=e.innerRef,r=e.navigate,a=e.onClick,i=(0,s.Z)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,l.Z)({},i,{onClick:function(e){try{a&&a(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=f!==m&&t||n,o.createElement("a",u)}));var h=m((function(e,t){var n=e.component,a=void 0===n?g:n,u=e.replace,h=e.to,b=e.innerRef,v=(0,s.Z)(e,["component","replace","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,r=p(d(h,e.location),e.location),s=r?n.createHref(r):"",g=(0,l.Z)({},v,{href:s,navigate:function(){var t=d(h,e.location),r=(0,i.Ep)(e.location)===(0,i.Ep)(p(t));(u||r?n.replace:n.push)(t)}});return f!==m?g.ref=t||b:g.innerRef=b,o.createElement(a,g)}))})),b=function(e){return e},v=o.forwardRef;void 0===v&&(v=b);var y=v((function(e,t){var n=e["aria-current"],a=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,f=e.activeStyle,m=e.className,g=e.exact,y=e.isActive,w=e.location,k=e.sensitive,S=e.strict,E=e.style,_=e.to,x=e.innerRef,C=(0,s.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=w||e.location,i=p(d(_,n),n),s=i.pathname,T=s&&s.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),L=T?(0,r.LX)(n.pathname,{path:T,exact:g,sensitive:k,strict:S}):null,A=!!(y?y(L,n):L),P="function"==typeof m?m(A):m,R="function"==typeof E?E(A):E;A&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,u),R=(0,l.Z)({},R,f));var N=(0,l.Z)({"aria-current":A&&a||null,className:P,style:R,to:i},C);return b!==v?N.ref=t||x:N.innerRef=x,o.createElement(h,N)}))}))},6550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>_,F0:()=>y,LX:()=>E,TH:()=>O,k6:()=>N,rs:()=>P,s6:()=>v});var r=n(5068),a=n(7294),o=n(5697),i=n.n(o),l=n(9318),s=n(2177),c=n(7462),u=n(4779),d=n.n(u),p=(n(9864),n(3366)),f=(n(8679),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var g=a.createContext||function(e,t){var n,o,l="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",s=function(e){function n(){for(var t,n,r,a=arguments.length,o=new Array(a),i=0;i<a;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.Z)(n,e);var a=n.prototype;return a.getChildContext=function(){var e;return(e={})[l]=this.emitter,e},a.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,a=e.value;((o=r)===(i=a)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(r,a):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},a.render=function(){return this.props.children},n}(a.Component);s.childContextTypes=((n={})[l]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),a=0;a<n;a++)r[a]=arguments[a];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var a=n.prototype;return a.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},a.componentDidMount=function(){this.context[l]&&this.context[l].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},a.componentWillUnmount=function(){this.context[l]&&this.context[l].off(this.onUpdate)},a.getValue=function(){return this.context[l]?this.context[l].get():e},a.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(a.Component);return c.contextTypes=((o={})[l]=i().object,o),{Provider:s,Consumer:c}},h=function(e){var t=g();return t.displayName=e,t},b=h("Router-History"),v=h("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return a.createElement(v.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},a.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(a.Component);a.Component;a.Component;var w={},k=1e4,S=0;function E(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,a=n.exact,o=void 0!==a&&a,i=n.strict,l=void 0!==i&&i,s=n.sensitive,c=void 0!==s&&s;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var a=[],o={regexp:d()(e,a,t),keys:a};return S<k&&(r[e]=o,S++),o}(n,{end:o,strict:l,sensitive:c}),a=r.regexp,i=r.keys,s=a.exec(e);if(!s)return null;var u=s[0],p=s.slice(1),f=e===u;return o&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var _=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,s.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?E(n.pathname,e.props):t.match,o=(0,c.Z)({},t,{location:n,match:r}),i=e.props,l=i.children,u=i.component,d=i.render;return Array.isArray(l)&&function(e){return 0===a.Children.count(e)}(l)&&(l=null),a.createElement(v.Provider,{value:o},o.match?l?"function"==typeof l?l(o):l:u?a.createElement(u,o):d?d(o):null:"function"==typeof l?l(o):null)}))},t}(a.Component);function x(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=x(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,l.Ep)(e)}function L(e){return function(){(0,s.Z)(!1)}}function A(){}a.Component;var P=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return a.createElement(v.Consumer,null,(function(t){t||(0,s.Z)(!1);var n,r,o=e.props.location||t.location;return a.Children.forEach(e.props.children,(function(e){if(null==r&&a.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?E(o.pathname,(0,c.Z)({},e.props,{path:i})):t.match}})),r?a.cloneElement(n,{location:o,computedMatch:r}):null}))},t}(a.Component);var R=a.useContext;function N(){return R(b)}function O(){return R(v).location}},2408:(e,t,n)=>{"use strict";var r=n(7418),a=60103,o=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,l=60110,s=60112;t.Suspense=60113;var c=60115,u=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;a=d("react.element"),o=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),l=d("react.context"),s=d("react.forward_ref"),t.Suspense=d("react.suspense"),c=d("react.memo"),u=d("react.lazy")}var p="function"==typeof Symbol&&Symbol.iterator;function f(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g={};function h(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}function b(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}h.prototype.isReactComponent={},h.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(f(85));this.updater.enqueueSetState(this,e,t,"setState")},h.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=h.prototype;var y=v.prototype=new b;y.constructor=v,r(y,h.prototype),y.isPureReactComponent=!0;var w={current:null},k=Object.prototype.hasOwnProperty,S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,n){var r,o={},i=null,l=null;if(null!=t)for(r in void 0!==t.ref&&(l=t.ref),void 0!==t.key&&(i=""+t.key),t)k.call(t,r)&&!S.hasOwnProperty(r)&&(o[r]=t[r]);var s=arguments.length-2;if(1===s)o.children=n;else if(1<s){for(var c=Array(s),u=0;u<s;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(r in s=e.defaultProps)void 0===o[r]&&(o[r]=s[r]);return{$$typeof:a,type:e,key:i,ref:l,props:o,_owner:w.current}}function _(e){return"object"==typeof e&&null!==e&&e.$$typeof===a}var x=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,n,r,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s=!1;if(null===e)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(e.$$typeof){case a:case o:s=!0}}if(s)return i=i(s=e),e=""===r?"."+C(s,0):r,Array.isArray(i)?(n="",null!=e&&(n=e.replace(x,"$&/")+"/"),T(i,t,n,"",(function(e){return e}))):null!=i&&(_(i)&&(i=function(e,t){return{$$typeof:a,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||s&&s.key===i.key?"":(""+i.key).replace(x,"$&/")+"/")+e)),t.push(i)),1;if(s=0,r=""===r?".":r+":",Array.isArray(e))for(var c=0;c<e.length;c++){var u=r+C(l=e[c],c);s+=T(l,t,n,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=p&&e[p]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(l=e.next()).done;)s+=T(l=l.value,t,n,u=r+C(l,c++),i);else if("object"===l)throw t=""+e,Error(f(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return s}function L(e,t,n){if(null==e)return e;var r=[],a=0;return T(e,r,"","",(function(e){return t.call(n,e,a++)})),r}function A(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function R(){var e=P.current;if(null===e)throw Error(f(321));return e}var N={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:r};t.Children={map:L,forEach:function(e,t,n){L(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return L(e,(function(){t++})),t},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!_(e))throw Error(f(143));return e}},t.Component=h,t.PureComponent=v,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=N,t.cloneElement=function(e,t,n){if(null==e)throw Error(f(267,e));var o=r({},e.props),i=e.key,l=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(l=t.ref,s=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(u in t)k.call(t,u)&&!S.hasOwnProperty(u)&&(o[u]=void 0===t[u]&&void 0!==c?c[u]:t[u])}var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){c=Array(u);for(var d=0;d<u;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:a,type:e.type,key:i,ref:l,props:o,_owner:s}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:l,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:s,render:e}},t.isValidElement=_,t.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:A}},t.memo=function(e,t){return{$$typeof:c,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return R().useCallback(e,t)},t.useContext=function(e,t){return R().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return R().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return R().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return R().useLayoutEffect(e,t)},t.useMemo=function(e,t){return R().useMemo(e,t)},t.useReducer=function(e,t,n){return R().useReducer(e,t,n)},t.useRef=function(e){return R().useRef(e)},t.useState=function(e){return R().useState(e)},t.version="17.0.2"},7294:(e,t,n)=>{"use strict";e.exports=n(2408)},53:(e,t)=>{"use strict";var n,r,a,o;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var c=null,u=null,d=function(){if(null!==c)try{var e=t.unstable_now();c(!0,e),c=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==c?setTimeout(n,0,e):(c=e,setTimeout(d,0))},r=function(e,t){u=setTimeout(e,t)},a=function(){clearTimeout(u)},t.unstable_shouldYield=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var p=window.setTimeout,f=window.clearTimeout;if("undefined"!=typeof console){var m=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof m&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var g=!1,h=null,b=-1,v=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):v=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,k=w.port2;w.port1.onmessage=function(){if(null!==h){var e=t.unstable_now();y=e+v;try{h(!0,e)?k.postMessage(null):(g=!1,h=null)}catch(n){throw k.postMessage(null),n}}else g=!1},n=function(e){h=e,g||(g=!0,k.postMessage(null))},r=function(e,n){b=p((function(){e(t.unstable_now())}),n)},a=function(){f(b),b=-1}}function S(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<x(a,t)))break e;e[r]=t,e[n]=a,n=r}}function E(e){return void 0===(e=e[0])?null:e}function _(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var o=2*(r+1)-1,i=e[o],l=o+1,s=e[l];if(void 0!==i&&0>x(i,n))void 0!==s&&0>x(s,i)?(e[r]=s,e[l]=n,r=l):(e[r]=i,e[o]=n,r=o);else{if(!(void 0!==s&&0>x(s,n)))break e;e[r]=s,e[l]=n,r=l}}}return t}return null}function x(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var C=[],T=[],L=1,A=null,P=3,R=!1,N=!1,O=!1;function I(e){for(var t=E(T);null!==t;){if(null===t.callback)_(T);else{if(!(t.startTime<=e))break;_(T),t.sortIndex=t.expirationTime,S(C,t)}t=E(T)}}function D(e){if(O=!1,I(e),!N)if(null!==E(C))N=!0,n(M);else{var t=E(T);null!==t&&r(D,t.startTime-e)}}function M(e,n){N=!1,O&&(O=!1,a()),R=!0;var o=P;try{for(I(n),A=E(C);null!==A&&(!(A.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=A.callback;if("function"==typeof i){A.callback=null,P=A.priorityLevel;var l=i(A.expirationTime<=n);n=t.unstable_now(),"function"==typeof l?A.callback=l:A===E(C)&&_(C),I(n)}else _(C);A=E(C)}if(null!==A)var s=!0;else{var c=E(T);null!==c&&r(D,c.startTime-n),s=!1}return s}finally{A=null,P=o,R=!1}}var j=o;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){N||R||(N=!0,n(M))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return E(C)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=j,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,o,i){var l=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?l+i:l:i=l,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:L++,callback:o,priorityLevel:e,startTime:i,expirationTime:s=i+s,sortIndex:-1},i>l?(e.sortIndex=i,S(T,e),null===E(C)&&e===E(T)&&(O?a():O=!0,r(D,i-l))):(e.sortIndex=s,S(C,e),N||R||(N=!0,n(M))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},3840:(e,t,n)=>{"use strict";e.exports=n(53)},6774:e=>{e.exports=function(e,t,n,r){var a=n?n.call(r,e,t):void 0;if(void 0!==a)return!!a;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var l=Object.prototype.hasOwnProperty.bind(t),s=0;s<o.length;s++){var c=o[s];if(!l(c))return!1;var u=e[c],d=t[c];if(!1===(a=n?n.call(r,u,d,c):void 0)||void 0===a&&u!==d)return!1}return!0}},2177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=!0,a="Invariant failed";function o(e,t){if(!e){if(r)throw new Error(a);var n="function"==typeof t?t():t;throw new Error(n?a+": "+n:a)}}},3250:(e,t,n)=>{"use strict";var r=n(7294);var a="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=r.useState,i=r.useEffect,l=r.useLayoutEffect,s=r.useDebugValue;function c(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!a(e,n)}catch(r){return!0}}var u="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),r=o({inst:{value:n,getSnapshot:t}}),a=r[0].inst,u=r[1];return l((function(){a.value=n,a.getSnapshot=t,c(a)&&u({inst:a})}),[e,n,t]),i((function(){return c(a)&&u({inst:a}),e((function(){c(a)&&u({inst:a})}))}),[e]),s(n),n};void 0!==r.useSyncExternalStore&&r.useSyncExternalStore},1688:(e,t,n)=>{"use strict";n(3250)},6809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"The Cwtch Handbook",tagline:"Your Guide to setting up, and using, Surveillance Resistant Infrastructure",url:"https://docs.cwtch.im",baseUrl:"/it/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/favicon.png",organizationName:"Open Privacy Research Society",projectName:"cwtch.im",i18n:{defaultLocale:"en",locales:["en","es","de","it"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",editUrl:"https://git.openprivacy.ca/cwtch.im/docs.cwtch.im/src/branch/staging/",remarkPlugins:[null],rehypePlugins:[null]},blog:{feedOptions:{type:"all",copyright:"Copyright \xa9 ${new Date().getFullYear()} Open Privacy Research Society",title:"Cwtch Development Log",description:"The latest insight into Cwtch Development and what the Cwtch team are working on"},blogSidebarCount:20},theme:{customCss:"/home/sarah/PARA/projects/docs.cwtch.im/src/css/custom.css"}}]],themeConfig:{image:"img/cwtch_handbook_header.jpg",colorMode:{defaultMode:"dark",disableSwitch:!1,respectPrefersColorScheme:!1},navbar:{title:"Manuale Di Cwtch",logo:{alt:"Cwtch Logo",src:"img/knott.png"},items:[{type:"doc",docId:"intro",position:"left",label:"Introduzione a Cwtch"},{to:"/security/intro",position:"left",label:"Security Handbook"},{to:"/developing/intro",position:"left",label:"Developers Handbook"},{to:"blog",position:"left",label:"Development Log"},{href:"https://openprivacy.ca/donate",label:"Donate",position:"right"},{href:"https://patreon.com/openprivacy",label:"Patreon",position:"right"},{href:"https://cwtch.im/download",label:"Download",position:"right"},{type:"localeDropdown",position:"right",dropdownItemsBefore:[],dropdownItemsAfter:[]}],hideOnScroll:!1},footer:{links:[{title:"Documentazione",items:[{label:"Introduction",to:"/docs/intro"},{to:"/security/intro",label:"Security Handbook"},{to:"/developing/intro",label:"Developer Guide"}]},{title:"Comunit\xe0",items:[{label:"Mastodon",href:"https://fosstodon.org/@cwtch"},{label:"Twitter",href:"https://twitter.com/cwtch_im"}]},{title:"Contribute",items:[{label:"Donate",href:"https://openprivacy.ca/donate"},{label:"Patreon",href:"https://patreon.com/openprivacy"},{label:"Source Code",href:"https://git.openprivacy.ca/cwtch.im"},{label:"Download",href:"https://cwtch.im/download"}]}],copyright:"Copyright \xa9 Open Privacy Research Society",style:"light"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},plugins:[["@docusaurus/plugin-content-docs",{id:"docs-security",path:"security",routeBasePath:"security",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}],["@docusaurus/plugin-content-docs",{id:"docs-developer",path:"developing",routeBasePath:"developing",sidebarPath:"/home/sarah/PARA/projects/docs.cwtch.im/sidebars.js",remarkPlugins:[null],rehypePlugins:[null]}]],stylesheets:[{href:"/katex/katex.min.css",type:"text/css"}],baseUrlIssueBanner:!0,onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},themes:[],scripts:[],headTags:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{mermaid:!1}}},7462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},5068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>a})},3366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}n.d(t,{Z:()=>r})},7529:e=>{"use strict";e.exports=JSON.parse('{"theme.AnnouncementBar.closeButtonAriaLabel":"Chiudi","theme.BackToTopButton.buttonAriaLabel":"Torna in cima","theme.CodeBlock.copied":"Copiato","theme.CodeBlock.copy":"Copia","theme.CodeBlock.copyButtonAriaLabel":"Copia il codice negli appunti","theme.CodeBlock.wordWrapToggle":"Attiva/disattiva a capo automatico","theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel":"Attiva/disattiva la categoria \'{label}\' della barra laterale collassabile","theme.ErrorPageContent.title":"Questa pagina \xe8 andata in crash.","theme.ErrorPageContent.tryAgain":"Riprova","theme.NavBar.navAriaLabel":"Main","theme.NotFound.p1":"Non abbiamo trovato quello che stavi cercando.","theme.NotFound.p2":"Contatta il proprietario del sito che ha linkato l\'URL originario ed informalo che il collegamento non funziona.","theme.NotFound.title":"Pagina non trovata","theme.TOCCollapsible.toggleButtonLabel":"In questa pagina","theme.admonition.caution":"caution","theme.admonition.danger":"danger","theme.admonition.info":"info","theme.admonition.note":"note","theme.admonition.tip":"tip","theme.blog.archive.description":"Archivio","theme.blog.archive.title":"Archivio","theme.blog.paginator.navAriaLabel":"Navigazione della pagina elenco del blog","theme.blog.paginator.newerEntries":"Post pi\xf9 recenti","theme.blog.paginator.olderEntries":"Post pi\xf9 vecchi","theme.blog.post.paginator.navAriaLabel":"Navigazione della pagina dei post del blog","theme.blog.post.paginator.newerPost":"Post pi\xf9 recente","theme.blog.post.paginator.olderPost":"Post pi\xf9 vecchio","theme.blog.post.plurals":"Un post|{count} post","theme.blog.post.readMore":"Continua A Leggere","theme.blog.post.readMoreLabel":"Leggi tutto il post {title}","theme.blog.post.readingTime.plurals":"Lettura di 1 minuto|{readingTime} minuti di lettura","theme.blog.sidebar.navAriaLabel":"Navigazione dei post recenti del blog","theme.blog.tagTitle":"{nPosts} etichettati con \\"{tagName}\\"","theme.colorToggle.ariaLabel":"Cambia modalit\xe0 (scura o chiara, attualmente {mode})","theme.colorToggle.ariaLabel.mode.dark":"modalit\xe0 scura","theme.colorToggle.ariaLabel.mode.light":"modalit\xe0 chiara","theme.common.editThisPage":"Modifica questa pagina","theme.common.headingLinkTitle":"Link diretto all\'intestazione","theme.common.skipToMainContent":"Passa al contenuto principale","theme.docs.DocCard.categoryDescription":"{count} elementi","theme.docs.breadcrumbs.home":"Pagina iniziale","theme.docs.breadcrumbs.navAriaLabel":"Breadcrumbs","theme.docs.paginator.navAriaLabel":"Navigazione delle pagine di documentazione","theme.docs.paginator.next":"Avanti","theme.docs.paginator.previous":"Indietro","theme.docs.sidebar.closeSidebarButtonAriaLabel":"Close navigation bar","theme.docs.sidebar.collapseButtonAriaLabel":"Nascondi la barra laterale","theme.docs.sidebar.collapseButtonTitle":"Nascondi la barra laterale","theme.docs.sidebar.expandButtonAriaLabel":"Espandi la barra laterale","theme.docs.sidebar.expandButtonTitle":"Espandi la barra laterale","theme.docs.sidebar.navAriaLabel":"Docs sidebar","theme.docs.sidebar.toggleSidebarButtonAriaLabel":"Toggle navigation bar","theme.docs.tagDocListPageTitle":"{nDocsTagged} etichettati con \\"{tagName}\\"","theme.docs.tagDocListPageTitle.nDocsTagged":"Un documento etichettato|{count} documenti etichettati","theme.docs.versionBadge.label":"Versione: {versionLabel}","theme.docs.versions.latestVersionLinkLabel":"ultima versione","theme.docs.versions.latestVersionSuggestionLabel":"Per documentazione aggiornata, vedi {latestVersionLink} ({versionLabel}).","theme.docs.versions.unmaintainedVersionLabel":"Questa \xe8 ls documentazione per {siteTitle} versione {versionLabel}, che non \xe8 pi\xf9 attivamente mantenuta.","theme.docs.versions.unreleasedVersionLabel":"Questa \xe8 una documentazione non pubblicata ufficialmente per {siteTitle} versione {versionLabel}.","theme.lastUpdated.atDate":" il {date}","theme.lastUpdated.byUser":" da {user}","theme.lastUpdated.lastUpdatedAtBy":"Ultimo aggiornamento{atDate}{byUser}","theme.navbar.mobileLanguageDropdown.label":"Lingue","theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel":"\u2190 Torna al men\xf9 principale","theme.navbar.mobileVersionsDropdown.label":"Versioni","theme.tags.tagsListLabel":"Etichette:","theme.tags.tagsPageLink":"Visualizza tutte le etichette","theme.tags.tagsPageTitle":"Tags","Get Started With Cwtch":"Get Started With Cwtch","The Cwtch Handbook":"The Cwtch Handbook","Your Guide to setting up, and using, Surveillance Resistant Infrastructure":"Your Guide to setting up, and using, Surveillance Resistant Infrastructure"}')},6887:e=>{"use strict";e.exports=JSON.parse('{"/it/blog-779":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"metadata":"f4279852"},"/it/blog/archive-da9":{"__comp":"9e4087bc","__context":{"plugin":"c94c4dfb"},"archive":"0a2b8ac2"},"/it/blog/autobindings-2f1":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9dd8190d"},"/it/blog/autobindings-ii-291":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"8fe7a387"},"/it/blog/availability-status-profile-attributes-1ab":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6a78f460"},"/it/blog/cwtch-android-reproducibility-526":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9b12a270"},"/it/blog/cwtch-bindings-reproducible-879":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"0d64c1d9"},"/it/blog/cwtch-developer-documentation-22a":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a65a3c47"},"/it/blog/cwtch-documentation-129":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"6275ceb4"},"/it/blog/cwtch-nightly-1-11-781":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"c96c5262"},"/it/blog/cwtch-nightly-1-12-9d1":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"a02b4022"},"/it/blog/cwtch-nightly-v.11-74-491":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5beee875"},"/it/blog/cwtch-platform-support-164":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"5e5faacc"},"/it/blog/cwtch-stable-api-design-6c8":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9e2a7473"},"/it/blog/cwtch-stable-roadmap-update-794":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"af23c5f9"},"/it/blog/cwtch-stable-roadmap-update-june-8cc":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"61794344"},"/it/blog/cwtch-testing-i-c23":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"43b107c1"},"/it/blog/cwtch-testing-ii-d98":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"9f1c7621"},"/it/blog/page/2-dbd":{"__comp":"a6aa9e1f","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"metadata":"5ae3487b"},"/it/blog/path-to-cwtch-stable-b83":{"__comp":"ccc49370","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","content":"b0404c31"},"/it/blog/tags-c5b":{"__comp":"01a85c17","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","tags":"794fc1e8"},"/it/blog/tags/api-e1b":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"a79c88c2"}],"tag":"2c901dd2","listMetadata":"7f5e9c41"},"/it/blog/tags/autobindings-642":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"fad3d52b","listMetadata":"c3b86ae0"},"/it/blog/tags/bindings-ebf":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"},{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"a7e50e09","listMetadata":"c5a58ca1"},"/it/blog/tags/cwtch-a84":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"b51a5363","listMetadata":"7246b934"},"/it/blog/tags/cwtch-stable-c87":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"4aa555c3"},{"content":"fe1dd7ae"},{"content":"5cb298ca"},{"content":"141cdfa9"},{"content":"f041e880"},{"content":"89f86a37"},{"content":"3a109bd3"},{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"6b44a42a","listMetadata":"0bb12077"},"/it/blog/tags/cwtch-stable/page/2-1e4":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"3e80d710","listMetadata":"b331d16d"},"/it/blog/tags/cwtch/page/2-54a":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"bf059cf9"},{"content":"53cc4802"},{"content":"ef78badf"},{"content":"4d27f429"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"8a8a5858","listMetadata":"8051e978"},"/it/blog/tags/developer-documentation-c25":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"fe1dd7ae"},{"content":"5cb298ca"}],"tag":"8e8114dc","listMetadata":"d228e678"},"/it/blog/tags/documentation-897":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"209bdfc3","listMetadata":"d634637f"},"/it/blog/tags/libcwtch-74c":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"c747432f"},{"content":"1ebd8798"}],"tag":"3b7b256a","listMetadata":"9034063a"},"/it/blog/tags/nightly-f8e":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"141cdfa9"}],"tag":"dfb11b4d","listMetadata":"f9cff38b"},"/it/blog/tags/planning-918":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"b125d866"},{"content":"f041e880"},{"content":"a79c88c2"},{"content":"1a25c548"}],"tag":"937969ee","listMetadata":"9009e554"},"/it/blog/tags/release-a5e":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"4aa555c3"},{"content":"89f86a37"}],"tag":"11796dfe","listMetadata":"1cbfc7c5"},"/it/blog/tags/repliqate-967":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"0999b6aa","listMetadata":"98bd2791"},"/it/blog/tags/reproducible-builds-f52":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"bf059cf9"},{"content":"4d27f429"}],"tag":"ba6ec3d2","listMetadata":"247a7af4"},"/it/blog/tags/security-handbook-036":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"3a109bd3"}],"tag":"2c10bcf6","listMetadata":"6c4339db"},"/it/blog/tags/support-872":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"},{"content":"ef78badf"}],"tag":"ecbb35df","listMetadata":"b979d7e4"},"/it/blog/tags/testing-479":{"__comp":"6875c492","__context":{"plugin":"c94c4dfb"},"sidebar":"814f3328","items":[{"content":"f76a3b8e"},{"content":"53cc4802"}],"tag":"59e122e4","listMetadata":"fccc5d20"},"/it/developing-724":{"__comp":"1be78505","__context":{"plugin":"d5f314f9"},"versionMetadata":"f928e8d9"},"/it/developing/building-a-cwtch-app/building-an-echobot-923":{"__comp":"17896441","content":"fd27e325"},"/it/developing/building-a-cwtch-app/core-concepts-a62":{"__comp":"17896441","content":"c14f15fd"},"/it/developing/building-a-cwtch-app/intro-702":{"__comp":"17896441","content":"824a28c6"},"/it/developing/category/building-a-cwtch-app-2e1":{"__comp":"14eb3368","categoryGeneratedIndex":"8d811565"},"/it/developing/intro-040":{"__comp":"17896441","content":"fb3c1916"},"/it/developing/release-429":{"__comp":"17896441","content":"5dc151e9"},"/it/docs-969":{"__comp":"1be78505","__context":{"plugin":"3db42865"},"versionMetadata":"935f2afb"},"/it/docs/category/appearance-225":{"__comp":"14eb3368","categoryGeneratedIndex":"876f085b"},"/it/docs/category/behaviour-638":{"__comp":"14eb3368","categoryGeneratedIndex":"ae271b89"},"/it/docs/category/contribute-8ef":{"__comp":"14eb3368","categoryGeneratedIndex":"3d43f565"},"/it/docs/category/conversations-c6e":{"__comp":"14eb3368","categoryGeneratedIndex":"6648656d"},"/it/docs/category/experiments-1ac":{"__comp":"14eb3368","categoryGeneratedIndex":"7a06dbff"},"/it/docs/category/getting-started-643":{"__comp":"14eb3368","categoryGeneratedIndex":"66f0cf59"},"/it/docs/category/groups-71d":{"__comp":"14eb3368","categoryGeneratedIndex":"83643414"},"/it/docs/category/platforms-725":{"__comp":"14eb3368","categoryGeneratedIndex":"08c34551"},"/it/docs/category/profiles-e2c":{"__comp":"14eb3368","categoryGeneratedIndex":"b11de5d5"},"/it/docs/category/servers-465":{"__comp":"14eb3368","categoryGeneratedIndex":"fc999220"},"/it/docs/category/settings-1de":{"__comp":"14eb3368","categoryGeneratedIndex":"8838b5d9"},"/it/docs/chat/accept-deny-new-conversation-7f0":{"__comp":"17896441","content":"e2032214"},"/it/docs/chat/add-contact-a11":{"__comp":"17896441","content":"18b4904d"},"/it/docs/chat/block-contact-5d2":{"__comp":"17896441","content":"56ee2ea4"},"/it/docs/chat/conversation-settings-3a2":{"__comp":"17896441","content":"1d0a8d89"},"/it/docs/chat/delete-contact-072":{"__comp":"17896441","content":"ddf22f37"},"/it/docs/chat/introduction-b74":{"__comp":"17896441","content":"b74cf248"},"/it/docs/chat/message-formatting-354":{"__comp":"17896441","content":"f04f0ec9"},"/it/docs/chat/reply-to-message-3d0":{"__comp":"17896441","content":"c9f9ad20"},"/it/docs/chat/save-conversation-history-d56":{"__comp":"17896441","content":"b58c7628"},"/it/docs/chat/share-address-with-friends-d95":{"__comp":"17896441","content":"bc51653d"},"/it/docs/chat/share-file-482":{"__comp":"17896441","content":"231a229c"},"/it/docs/chat/unblock-contact-1dd":{"__comp":"17896441","content":"29659bc8"},"/it/docs/contribute/developing-d9f":{"__comp":"17896441","content":"21d06810"},"/it/docs/contribute/documentation-fc4":{"__comp":"17896441","content":"a8875a35"},"/it/docs/contribute/stickers-ac2":{"__comp":"17896441","content":"f7ca86a6"},"/it/docs/contribute/testing-57e":{"__comp":"17896441","content":"d1fa313c"},"/it/docs/contribute/translate-402":{"__comp":"17896441","content":"298daba3"},"/it/docs/getting-started/supported_platforms-d14":{"__comp":"17896441","content":"f894db60"},"/it/docs/groups/accept-group-invite-c81":{"__comp":"17896441","content":"a4396826"},"/it/docs/groups/create-group-50a":{"__comp":"17896441","content":"ef02fbbd"},"/it/docs/groups/edit-group-name-7a8":{"__comp":"17896441","content":"adfd2a96"},"/it/docs/groups/introduction-7f0":{"__comp":"17896441","content":"f9b019e0"},"/it/docs/groups/leave-group-490":{"__comp":"17896441","content":"19cde8ec"},"/it/docs/groups/manage-known-servers-704":{"__comp":"17896441","content":"010d07c1"},"/it/docs/groups/send-invite-8ec":{"__comp":"17896441","content":"2887095c"},"/it/docs/intro-bda":{"__comp":"17896441","content":"49b07f50"},"/it/docs/platforms/tails-264":{"__comp":"17896441","content":"0fb199c9"},"/it/docs/profiles/availability-status-dd7":{"__comp":"17896441","content":"46b0c109"},"/it/docs/profiles/change-name-6c6":{"__comp":"17896441","content":"fe910059"},"/it/docs/profiles/change-password-8fa":{"__comp":"17896441","content":"b29d9412"},"/it/docs/profiles/change-profile-image-c17":{"__comp":"17896441","content":"e31178cb"},"/it/docs/profiles/create-a-profile-1c8":{"__comp":"17896441","content":"f748f255"},"/it/docs/profiles/delete-profile-c89":{"__comp":"17896441","content":"3bf8c048"},"/it/docs/profiles/exporting-profile-6d7":{"__comp":"17896441","content":"3bf835b2"},"/it/docs/profiles/importing-a-profile-6ec":{"__comp":"17896441","content":"508409b4"},"/it/docs/profiles/introduction-55f":{"__comp":"17896441","content":"08c3bd78"},"/it/docs/profiles/profile-info-d3a":{"__comp":"17896441","content":"0b5b83c5"},"/it/docs/profiles/unlock-profile-bc1":{"__comp":"17896441","content":"5e9927d2"},"/it/docs/servers/create-server-7cf":{"__comp":"17896441","content":"b8ae7715"},"/it/docs/servers/delete-server-cea":{"__comp":"17896441","content":"e759f958"},"/it/docs/servers/edit-server-ae8":{"__comp":"17896441","content":"115541e2"},"/it/docs/servers/introduction-271":{"__comp":"17896441","content":"d78ab406"},"/it/docs/servers/share-key-f89":{"__comp":"17896441","content":"97ac6d59"},"/it/docs/servers/unlock-server-252":{"__comp":"17896441","content":"8e3a693e"},"/it/docs/settings/appearance/change-language-102":{"__comp":"17896441","content":"8281c315"},"/it/docs/settings/appearance/light-dark-mode-05f":{"__comp":"17896441","content":"68c206b4"},"/it/docs/settings/appearance/streamer-mode-4af":{"__comp":"17896441","content":"47db09cd"},"/it/docs/settings/appearance/ui-columns-f68":{"__comp":"17896441","content":"9148c1ad"},"/it/docs/settings/behaviour/block-unknown-connections-7f7":{"__comp":"17896441","content":"3bc00383"},"/it/docs/settings/behaviour/notification-content-eec":{"__comp":"17896441","content":"e83cebc7"},"/it/docs/settings/behaviour/notification-policy-c4a":{"__comp":"17896441","content":"13965eb4"},"/it/docs/settings/experiments/clickable-links-dc3":{"__comp":"17896441","content":"f2d017e0"},"/it/docs/settings/experiments/file-sharing-52a":{"__comp":"17896441","content":"cbb0e45e"},"/it/docs/settings/experiments/group-experiment-b2e":{"__comp":"17896441","content":"2ffad701"},"/it/docs/settings/experiments/image-previews-and-profile-pictures-1e9":{"__comp":"17896441","content":"73c8cde5"},"/it/docs/settings/experiments/message-formatting-86c":{"__comp":"17896441","content":"8918cacc"},"/it/docs/settings/experiments/qrcodes-537":{"__comp":"17896441","content":"fa088e0f"},"/it/docs/settings/experiments/server-hosting-358":{"__comp":"17896441","content":"45a7c7c6"},"/it/docs/settings/introduction-219":{"__comp":"17896441","content":"02cf6bb5"},"/it/docs/tor-960":{"__comp":"17896441","content":"6e2435dc"},"/it/security-2ae":{"__comp":"1be78505","__context":{"plugin":"4f68bcc6"},"versionMetadata":"a8c7fdc6"},"/it/security/category/connectivity--tor-5fe":{"__comp":"14eb3368","categoryGeneratedIndex":"0d59ece6"},"/it/security/category/cwtch-301":{"__comp":"14eb3368","categoryGeneratedIndex":"043d4691"},"/it/security/category/cwtch-components-3bc":{"__comp":"14eb3368","categoryGeneratedIndex":"34843fbe"},"/it/security/category/cwtch-ui-de2":{"__comp":"14eb3368","categoryGeneratedIndex":"1578504c"},"/it/security/category/tapir-c7d":{"__comp":"14eb3368","categoryGeneratedIndex":"3b87f7a6"},"/it/security/components/connectivity/intro-30f":{"__comp":"17896441","content":"b2a64359"},"/it/security/components/cwtch/groups-ca5":{"__comp":"17896441","content":"f21fe67f"},"/it/security/components/cwtch/key_bundles-8c3":{"__comp":"17896441","content":"af2ce9b1"},"/it/security/components/cwtch/message_formats-711":{"__comp":"17896441","content":"553c6794"},"/it/security/components/cwtch/server-645":{"__comp":"17896441","content":"8aa5d230"},"/it/security/components/ecosystem-overview-fdd":{"__comp":"17896441","content":"ef6f692b"},"/it/security/components/intro-b59":{"__comp":"17896441","content":"7c6e9bc2"},"/it/security/components/tapir/authentication_protocol-189":{"__comp":"17896441","content":"917f768f"},"/it/security/components/tapir/packet_format-3b0":{"__comp":"17896441","content":"c50453d6"},"/it/security/components/ui/android-906":{"__comp":"17896441","content":"dabb1858"},"/it/security/components/ui/image_previews-a95":{"__comp":"17896441","content":"644e0e81"},"/it/security/components/ui/input-53e":{"__comp":"17896441","content":"9947de33"},"/it/security/components/ui/overlays-b2a":{"__comp":"17896441","content":"07eed749"},"/it/security/deployment-291":{"__comp":"17896441","content":"57d795a6"},"/it/security/development-04c":{"__comp":"17896441","content":"ef71f686"},"/it/security/intro-e21":{"__comp":"17896441","content":"88d0c547"},"/it/security/references-889":{"__comp":"17896441","content":"19563afa"},"/it/security/risk-bcb":{"__comp":"17896441","content":"9944c673"},"/it/-e32":{"__comp":"c4f5d8e4","__context":{"plugin":"e88d32a9"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[532],(()=>{return t=9383,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/build-staging/it/assets/js/main.d3acbaba.js.LICENSE.txt b/build-staging/it/assets/js/main.d3acbaba.js.LICENSE.txt new file mode 100644 index 00000000..eb75d691 --- /dev/null +++ b/build-staging/it/assets/js/main.d3acbaba.js.LICENSE.txt @@ -0,0 +1,63 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/** + * @license React + * use-sync-external-store-shim.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + */ + +/** @license React v0.20.2 + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** @license React v17.0.2 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/build-staging/it/assets/js/runtime~main.6bf0509f.js b/build-staging/it/assets/js/runtime~main.6bf0509f.js new file mode 100644 index 00000000..5fb6847d --- /dev/null +++ b/build-staging/it/assets/js/runtime~main.6bf0509f.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,c,f,a,b,d={},t={};function r(e){var c=t[e];if(void 0!==c)return c.exports;var f=t[e]={id:e,loaded:!1,exports:{}};return d[e].call(f.exports,f,f.exports,r),f.loaded=!0,f.exports}r.m=d,r.c=t,e=[],r.O=(c,f,a,b)=>{if(!f){var d=1/0;for(i=0;i<e.length;i++){f=e[i][0],a=e[i][1],b=e[i][2];for(var t=!0,o=0;o<f.length;o++)(!1&b||d>=b)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,b<d&&(d=b));if(t){e.splice(i--,1);var n=a();void 0!==n&&(c=n)}}return c}b=b||0;for(var i=e.length;i>0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[f,a,b]},r.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return r.d(c,{a:c}),c},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var d={};c=c||[null,f({}),f([]),f(f)];for(var t=2&a&&e;"object"==typeof t&&!~c.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((c=>d[c]=()=>e[c]));return d.default=()=>e,r.d(b,d),b},r.d=(e,c)=>{for(var f in c)r.o(c,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:c[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((c,f)=>(r.f[f](e,c),c)),[])),r.u=e=>"assets/js/"+({27:"fe910059",48:"f21fe67f",53:"935f2afb",80:"13965eb4",225:"f9b019e0",276:"fb3c1916",360:"b979d7e4",439:"6a78f460",621:"2887095c",785:"2ffad701",788:"4d27f429",818:"bc51653d",854:"937969ee",877:"dabb1858",923:"5dc151e9",981:"f2d017e0",1006:"b2a64359",1155:"ddf22f37",1199:"fd27e325",1210:"917f768f",1258:"9e2a7473",1312:"9f1c7621",1322:"18b4904d",1384:"e759f958",1602:"9034063a",1739:"8a8a5858",1814:"b51a5363",1871:"9009e554",1932:"f9cff38b",1950:"ef6f692b",1979:"fe1dd7ae",2033:"11796dfe",2081:"88d0c547",2111:"794fc1e8",2135:"3b87f7a6",2184:"f76a3b8e",2234:"7f5e9c41",2348:"231a229c",2397:"2c10bcf6",2411:"e2032214",2436:"f894db60",2450:"115541e2",2469:"ecbb35df",2481:"ef71f686",2535:"814f3328",2537:"209bdfc3",2605:"73c8cde5",2688:"9dd8190d",2723:"3e80d710",2861:"8281c315",2909:"5cb298ca",3007:"c3b86ae0",3026:"6648656d",3056:"fccc5d20",3089:"a6aa9e1f",3171:"508409b4",3185:"19563afa",3218:"af23c5f9",3224:"fc999220",3319:"b74cf248",3417:"b11de5d5",3492:"a02b4022",3516:"4f68bcc6",3587:"8d811565",3588:"66f0cf59",3608:"9e4087bc",3674:"0a2b8ac2",3693:"1578504c",3712:"1cbfc7c5",3761:"c96c5262",3763:"a7e50e09",3905:"7a06dbff",3936:"68c206b4",3949:"0999b6aa",4013:"01a85c17",4071:"6b44a42a",4108:"a8c7fdc6",4195:"c4f5d8e4",4239:"3d43f565",4268:"adfd2a96",4508:"f04f0ec9",4561:"644e0e81",4612:"f7ca86a6",4788:"1ebd8798",4862:"3bf835b2",4867:"3b7b256a",4986:"08c3bd78",5003:"fad3d52b",5089:"a4396826",5194:"c5a58ca1",5221:"0fb199c9",5226:"f041e880",5233:"8fe7a387",5273:"bf059cf9",5314:"2c901dd2",5391:"af2ce9b1",5398:"5e9927d2",5490:"0d59ece6",5532:"ef78badf",5540:"c9f9ad20",5552:"19cde8ec",5583:"46b0c109",5732:"1a25c548",5861:"6e2435dc",5869:"d5f314f9",5905:"824a28c6",6098:"83643414",6103:"ccc49370",6232:"61794344",6266:"29659bc8",6299:"59e122e4",6318:"49b07f50",6325:"8051e978",6457:"9944c673",6555:"6275ceb4",6585:"e88d32a9",6711:"1d0a8d89",6730:"7246b934",6735:"57d795a6",6758:"97ac6d59",6891:"47db09cd",6940:"34843fbe",7139:"3db42865",7241:"d634637f",7275:"043d4691",7293:"141cdfa9",7430:"dfb11b4d",7541:"e83cebc7",7591:"a65a3c47",7594:"53cc4802",7621:"21d06810",7649:"c14f15fd",7782:"3a109bd3",7797:"4aa555c3",7860:"b0404c31",7918:"17896441",7970:"8e3a693e",7977:"ae271b89",8070:"247a7af4",8098:"9947de33",8181:"f748f255",8185:"553c6794",8192:"5e5faacc",8237:"b331d16d",8239:"b8ae7715",8254:"7c6e9bc2",8371:"3bf8c048",8573:"298daba3",8590:"b58c7628",8610:"6875c492",8697:"0bb12077",8710:"0d64c1d9",8786:"f928e8d9",8789:"cbb0e45e",8795:"6c4339db",8799:"b125d866",8801:"a8875a35",8835:"c747432f",8838:"010d07c1",8848:"b29d9412",8907:"8918cacc",8909:"98bd2791",9010:"07eed749",9051:"02cf6bb5",9146:"c94c4dfb",9195:"56ee2ea4",9200:"43b107c1",9207:"0b5b83c5",9239:"8838b5d9",9249:"9b12a270",9251:"45a7c7c6",9284:"c50453d6",9399:"fa088e0f",9427:"d1fa313c",9444:"5beee875",9477:"9148c1ad",9481:"3bc00383",9506:"d78ab406",9507:"5ae3487b",9514:"1be78505",9516:"8aa5d230",9565:"ef02fbbd",9645:"876f085b",9661:"e31178cb",9717:"08c34551",9737:"ba6ec3d2",9759:"89f86a37",9798:"d228e678",9817:"14eb3368",9902:"f4279852",9923:"8e8114dc",9976:"a79c88c2"}[e]||e)+"."+{27:"ad535d04",48:"4708943f",53:"9e813847",80:"7c9d96d5",225:"b5b4a856",276:"37c9304f",360:"b414f5c1",439:"0e1fdfda",621:"3218a046",785:"d61d2196",788:"e6e4fc99",818:"e2e0d594",854:"9ce0fad1",877:"b567202d",923:"1beabf93",981:"bf63989d",1006:"46032bc4",1155:"5e3032eb",1199:"a240efeb",1210:"e40a65e1",1258:"b225b622",1312:"b2660e0a",1322:"fd5db813",1384:"17eb6149",1602:"b3f2b831",1739:"2b7a17f7",1814:"a6ebdb13",1871:"cdd0c2e4",1932:"63dfbda8",1950:"fa621589",1979:"158f4574",2033:"c8f1e93b",2081:"9912f681",2111:"a5dabfce",2135:"e4176764",2184:"d87fb81c",2234:"f850b1e9",2348:"9ecf60b7",2397:"fe137241",2411:"c3c30dff",2436:"de13cf40",2450:"64566ecd",2469:"f50bac3d",2481:"ec798b10",2535:"134511a1",2537:"e88f9793",2605:"b5747b40",2688:"904f5daf",2723:"98dc1d51",2861:"b32fff9f",2909:"f94bfc38",3007:"8788091c",3026:"67321fde",3056:"09b8e29a",3089:"8ac198c5",3171:"0048c1c5",3185:"3086b02e",3218:"b63a4e5e",3224:"ea2cb007",3319:"76183dc6",3417:"978db84c",3492:"36668ac2",3516:"d9b156bf",3587:"c9c12fe6",3588:"0da7321c",3608:"582408aa",3674:"a299c07b",3693:"2df26b14",3712:"b1788676",3761:"48df994f",3763:"7b745cd8",3905:"706e10d2",3936:"e35aacf5",3949:"c4cb2bce",4013:"fbcc85f1",4071:"1528fa0c",4108:"455cd2f8",4195:"ea3b76f3",4239:"27cb38fe",4268:"2bed8868",4508:"67327fd7",4561:"b5ab2ba3",4612:"973d26c1",4788:"efaa5cf8",4862:"df84e28a",4867:"61f28f34",4972:"486cf118",4986:"e7043240",5003:"713a3fa8",5089:"a9e17b33",5194:"a0b86038",5221:"6c1937b9",5226:"8b186783",5233:"ed7b87ab",5273:"2818d042",5314:"29005498",5391:"6fa59457",5398:"f2fc59f6",5490:"08931564",5532:"25d419d6",5540:"c11c18c5",5552:"3738013a",5583:"e289bdf1",5732:"9e772eca",5861:"3f74bf5b",5869:"1dc05f26",5905:"c282e634",6048:"e7c7c18a",6098:"f98f85cb",6103:"a9ca1f91",6232:"d52d09f1",6266:"6aaa4109",6299:"b1557b13",6318:"aea03bee",6325:"10d89153",6457:"96d5ab3f",6555:"3ba97e15",6585:"ff20b8ba",6711:"a73fb03b",6730:"ae40e115",6735:"5de42757",6758:"270edd8e",6891:"872c613a",6940:"da3b7d88",7139:"27ab3fca",7241:"1a735df4",7275:"ff8e86cc",7293:"d8dc748d",7430:"cca8a468",7541:"0d3d23db",7591:"547749ae",7594:"a67d245e",7621:"9f9af253",7649:"05646011",7782:"e8f7d386",7797:"65cc139a",7860:"04c08dcd",7918:"27340309",7970:"956fc1bf",7977:"fa96b586",8070:"e3a62790",8098:"8f316599",8181:"06c1bb18",8185:"bb21a347",8192:"07853952",8237:"6d1e6fa1",8239:"9962717d",8254:"e7ec1ee4",8371:"fc0d4ec1",8573:"cc57f664",8590:"8d84bd8d",8610:"a3d95c11",8697:"7852f71b",8710:"640c15f3",8786:"9677409e",8789:"4f1fe907",8795:"4177106d",8799:"05751358",8801:"968c4441",8835:"a76bb1c0",8838:"ea72f1c9",8848:"0ca2217e",8907:"c76c44c5",8909:"74ddfe18",9010:"e6de9ce0",9051:"883205f6",9146:"5e3bcaf2",9195:"e554caa6",9200:"87b92c1b",9207:"62502289",9239:"2f73078b",9249:"6003290e",9251:"49c7af0e",9284:"bf72966c",9399:"7d5235c3",9427:"f05028e7",9444:"1a7eefd7",9477:"a9bddf70",9481:"ea404c51",9506:"8962f566",9507:"c6fc1894",9514:"c2da882e",9516:"868664e0",9565:"0acf98a3",9645:"d32dc0bc",9661:"4e22fdc9",9717:"c234e086",9737:"25fb6655",9759:"6c1214b1",9785:"e0c467d7",9798:"59d2d9e1",9817:"5ac78d9e",9902:"ca90fc1f",9923:"d55afec6",9976:"7b161edf"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),a={},b="user-handbook:",r.l=(e,c,f,d)=>{if(a[e])a[e].push(c);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==b+f){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",b+f),t.src=e),a[e]=[c];var l=(c,f)=>{t.onerror=t.onload=null,clearTimeout(s);var b=a[e];if(delete a[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(f))),c)return c(f)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/it/",r.gca=function(e){return e={17896441:"7918",61794344:"6232",83643414:"6098",fe910059:"27",f21fe67f:"48","935f2afb":"53","13965eb4":"80",f9b019e0:"225",fb3c1916:"276",b979d7e4:"360","6a78f460":"439","2887095c":"621","2ffad701":"785","4d27f429":"788",bc51653d:"818","937969ee":"854",dabb1858:"877","5dc151e9":"923",f2d017e0:"981",b2a64359:"1006",ddf22f37:"1155",fd27e325:"1199","917f768f":"1210","9e2a7473":"1258","9f1c7621":"1312","18b4904d":"1322",e759f958:"1384","9034063a":"1602","8a8a5858":"1739",b51a5363:"1814","9009e554":"1871",f9cff38b:"1932",ef6f692b:"1950",fe1dd7ae:"1979","11796dfe":"2033","88d0c547":"2081","794fc1e8":"2111","3b87f7a6":"2135",f76a3b8e:"2184","7f5e9c41":"2234","231a229c":"2348","2c10bcf6":"2397",e2032214:"2411",f894db60:"2436","115541e2":"2450",ecbb35df:"2469",ef71f686:"2481","814f3328":"2535","209bdfc3":"2537","73c8cde5":"2605","9dd8190d":"2688","3e80d710":"2723","8281c315":"2861","5cb298ca":"2909",c3b86ae0:"3007","6648656d":"3026",fccc5d20:"3056",a6aa9e1f:"3089","508409b4":"3171","19563afa":"3185",af23c5f9:"3218",fc999220:"3224",b74cf248:"3319",b11de5d5:"3417",a02b4022:"3492","4f68bcc6":"3516","8d811565":"3587","66f0cf59":"3588","9e4087bc":"3608","0a2b8ac2":"3674","1578504c":"3693","1cbfc7c5":"3712",c96c5262:"3761",a7e50e09:"3763","7a06dbff":"3905","68c206b4":"3936","0999b6aa":"3949","01a85c17":"4013","6b44a42a":"4071",a8c7fdc6:"4108",c4f5d8e4:"4195","3d43f565":"4239",adfd2a96:"4268",f04f0ec9:"4508","644e0e81":"4561",f7ca86a6:"4612","1ebd8798":"4788","3bf835b2":"4862","3b7b256a":"4867","08c3bd78":"4986",fad3d52b:"5003",a4396826:"5089",c5a58ca1:"5194","0fb199c9":"5221",f041e880:"5226","8fe7a387":"5233",bf059cf9:"5273","2c901dd2":"5314",af2ce9b1:"5391","5e9927d2":"5398","0d59ece6":"5490",ef78badf:"5532",c9f9ad20:"5540","19cde8ec":"5552","46b0c109":"5583","1a25c548":"5732","6e2435dc":"5861",d5f314f9:"5869","824a28c6":"5905",ccc49370:"6103","29659bc8":"6266","59e122e4":"6299","49b07f50":"6318","8051e978":"6325","9944c673":"6457","6275ceb4":"6555",e88d32a9:"6585","1d0a8d89":"6711","7246b934":"6730","57d795a6":"6735","97ac6d59":"6758","47db09cd":"6891","34843fbe":"6940","3db42865":"7139",d634637f:"7241","043d4691":"7275","141cdfa9":"7293",dfb11b4d:"7430",e83cebc7:"7541",a65a3c47:"7591","53cc4802":"7594","21d06810":"7621",c14f15fd:"7649","3a109bd3":"7782","4aa555c3":"7797",b0404c31:"7860","8e3a693e":"7970",ae271b89:"7977","247a7af4":"8070","9947de33":"8098",f748f255:"8181","553c6794":"8185","5e5faacc":"8192",b331d16d:"8237",b8ae7715:"8239","7c6e9bc2":"8254","3bf8c048":"8371","298daba3":"8573",b58c7628:"8590","6875c492":"8610","0bb12077":"8697","0d64c1d9":"8710",f928e8d9:"8786",cbb0e45e:"8789","6c4339db":"8795",b125d866:"8799",a8875a35:"8801",c747432f:"8835","010d07c1":"8838",b29d9412:"8848","8918cacc":"8907","98bd2791":"8909","07eed749":"9010","02cf6bb5":"9051",c94c4dfb:"9146","56ee2ea4":"9195","43b107c1":"9200","0b5b83c5":"9207","8838b5d9":"9239","9b12a270":"9249","45a7c7c6":"9251",c50453d6:"9284",fa088e0f:"9399",d1fa313c:"9427","5beee875":"9444","9148c1ad":"9477","3bc00383":"9481",d78ab406:"9506","5ae3487b":"9507","1be78505":"9514","8aa5d230":"9516",ef02fbbd:"9565","876f085b":"9645",e31178cb:"9661","08c34551":"9717",ba6ec3d2:"9737","89f86a37":"9759",d228e678:"9798","14eb3368":"9817",f4279852:"9902","8e8114dc":"9923",a79c88c2:"9976"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(c,f)=>{var a=r.o(e,c)?e[c]:void 0;if(0!==a)if(a)f.push(a[2]);else if(/^(1303|532)$/.test(c))e[c]=0;else{var b=new Promise(((f,b)=>a=e[c]=[f,b]));f.push(a[2]=b);var d=r.p+r.u(c),t=new Error;r.l(d,(f=>{if(r.o(e,c)&&(0!==(a=e[c])&&(e[c]=void 0),a)){var b=f&&("load"===f.type?"missing":f.type),d=f&&f.target&&f.target.src;t.message="Loading chunk "+c+" failed.\n("+b+": "+d+")",t.name="ChunkLoadError",t.type=b,t.request=d,a[1](t)}}),"chunk-"+c,c)}},r.O.j=c=>0===e[c];var c=(c,f)=>{var a,b,d=f[0],t=f[1],o=f[2],n=0;if(d.some((c=>0!==e[c]))){for(a in t)r.o(t,a)&&(r.m[a]=t[a]);if(o)var i=o(r)}for(c&&c(f);n<d.length;n++)b=d[n],r.o(e,b)&&e[b]&&e[b][0](),e[b]=0;return r.O(i)},f=self.webpackChunkuser_handbook=self.webpackChunkuser_handbook||[];f.forEach(c.bind(null,0)),f.push=c.bind(null,f.push.bind(f))})()})(); \ No newline at end of file diff --git a/build-staging/it/blog/archive/index.html b/build-staging/it/blog/archive/index.html new file mode 100644 index 00000000..caa020e1 --- /dev/null +++ b/build-staging/it/blog/archive/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html lang="it" dir="ltr" class="plugin-blog plugin-id-default"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v2.4.1"> +<title data-rh="true">Archivio | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/blog/atom.xml b/build-staging/it/blog/atom.xml new file mode 100644 index 00000000..f90de2a0 --- /dev/null +++ b/build-staging/it/blog/atom.xml @@ -0,0 +1,276 @@ + + + https://docs.cwtch.im/it/blog + Cwtch Development Log + 2023-06-30T00:00:00.000Z + https://github.com/jpmonette/feed + + The latest insight into Cwtch Development and what the Cwtch team are working on + https://docs.cwtch.im/it/img/favicon.png + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update-june + + 2023-06-30T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/it/blog/cwtch-nightly-1-12 + + 2023-06-16T00:00:00.000Z + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/it/blog/cwtch-nightly-v.11-74 + + 2023-06-07T00:00:00.000Z + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/it/blog/cwtch-developer-documentation + + 2023-04-28T00:00:00.000Z + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/it/blog/availability-status-profile-attributes + + 2023-04-06T00:00:00.000Z + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update + + 2023-03-31T00:00:00.000Z + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/it/blog/cwtch-nightly-1-11 + + 2023-03-29T00:00:00.000Z + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/it/blog/cwtch-documentation + + 2023-03-10T00:00:00.000Z + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/it/blog/autobindings-ii + + 2023-03-03T00:00:00.000Z + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/it/blog/autobindings + + 2023-02-24T00:00:00.000Z + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/it/blog/cwtch-testing-ii + + 2023-02-17T00:00:00.000Z + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/it/blog/cwtch-android-reproducibility + + 2023-02-10T00:00:00.000Z + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/it/blog/cwtch-testing-i + + 2023-02-03T00:00:00.000Z + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/it/blog/cwtch-platform-support + + 2023-01-27T00:00:00.000Z + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/it/blog/cwtch-bindings-reproducible + + 2023-01-20T00:00:00.000Z + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + + + +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/it/blog/cwtch-stable-api-design + + 2023-01-13T00:00:00.000Z + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ + Sarah Jamie Lewis + + + + + +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/it/blog/path-to-cwtch-stable + + 2023-01-06T00:00:00.000Z + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ + Sarah Jamie Lewis + + + + +
+
\ No newline at end of file diff --git a/build-staging/it/blog/autobindings-ii/index.html b/build-staging/it/blog/autobindings-ii/index.html new file mode 100644 index 00000000..dfc0e4b5 --- /dev/null +++ b/build-staging/it/blog/autobindings-ii/index.html @@ -0,0 +1,33 @@ + + + + + +Compile-time Optional Application Experiments (Autobindings) | The Cwtch Handbook + + + + + + + + + + + + +
+

Compile-time Optional Application Experiments (Autobindings)

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/autobindings/index.html b/build-staging/it/blog/autobindings/index.html new file mode 100644 index 00000000..b275f13c --- /dev/null +++ b/build-staging/it/blog/autobindings/index.html @@ -0,0 +1,26 @@ + + + + + +Autogenerating Cwtch Bindings | The Cwtch Handbook + + + + + + + + + + + + +
+

Autogenerating Cwtch Bindings

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/availability-status-profile-attributes/index.html b/build-staging/it/blog/availability-status-profile-attributes/index.html new file mode 100644 index 00000000..bdc2c455 --- /dev/null +++ b/build-staging/it/blog/availability-status-profile-attributes/index.html @@ -0,0 +1,25 @@ + + + + + +Availability Status and Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Availability Status and Profile Attributes

· 2 minuti di lettura
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-android-reproducibility/index.html b/build-staging/it/blog/cwtch-android-reproducibility/index.html new file mode 100644 index 00000000..cfc8d52d --- /dev/null +++ b/build-staging/it/blog/cwtch-android-reproducibility/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Android Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Android Bindings Reproducible

· 3 minuti di lettura
Sarah Jamie Lewis

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-bindings-reproducible/index.html b/build-staging/it/blog/cwtch-bindings-reproducible/index.html new file mode 100644 index 00000000..fee14450 --- /dev/null +++ b/build-staging/it/blog/cwtch-bindings-reproducible/index.html @@ -0,0 +1,24 @@ + + + + + +Making Cwtch Bindings Reproducible | The Cwtch Handbook + + + + + + + + + + + + +
+

Making Cwtch Bindings Reproducible

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-developer-documentation/index.html b/build-staging/it/blog/cwtch-developer-documentation/index.html new file mode 100644 index 00000000..6df11cfb --- /dev/null +++ b/build-staging/it/blog/cwtch-developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly. | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.

· 3 minuti di lettura
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-documentation/index.html b/build-staging/it/blog/cwtch-documentation/index.html new file mode 100644 index 00000000..c2b519c6 --- /dev/null +++ b/build-staging/it/blog/cwtch-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Updates to Cwtch Documentation | The Cwtch Handbook + + + + + + + + + + + + +
+

Updates to Cwtch Documentation

· 3 minuti di lettura
Sarah Jamie Lewis

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-nightly-1-11/index.html b/build-staging/it/blog/cwtch-nightly-1-11/index.html new file mode 100644 index 00000000..b11672db --- /dev/null +++ b/build-staging/it/blog/cwtch-nightly-1-11/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.11 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.11

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-nightly-1-12/index.html b/build-staging/it/blog/cwtch-nightly-1-12/index.html new file mode 100644 index 00000000..ef00eea9 --- /dev/null +++ b/build-staging/it/blog/cwtch-nightly-1-12/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Beta 1.12 | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Beta 1.12

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-nightly-v.11-74/index.html b/build-staging/it/blog/cwtch-nightly-v.11-74/index.html new file mode 100644 index 00000000..285defe9 --- /dev/null +++ b/build-staging/it/blog/cwtch-nightly-v.11-74/index.html @@ -0,0 +1,24 @@ + + + + + +New Cwtch Nightly (v1.11.0-74-g0406) | The Cwtch Handbook + + + + + + + + + + + + +
+

New Cwtch Nightly (v1.11.0-74-g0406)

· 2 minuti di lettura
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-platform-support/index.html b/build-staging/it/blog/cwtch-platform-support/index.html new file mode 100644 index 00000000..b62e19f5 --- /dev/null +++ b/build-staging/it/blog/cwtch-platform-support/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI Platform Support | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch UI Platform Support

· 11 minuti di lettura
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-stable-api-design/index.html b/build-staging/it/blog/cwtch-stable-api-design/index.html new file mode 100644 index 00000000..f99ac966 --- /dev/null +++ b/build-staging/it/blog/cwtch-stable-api-design/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable API Design | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable API Design

· 18 minuti di lettura
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-stable-roadmap-update-june/index.html b/build-staging/it/blog/cwtch-stable-roadmap-update-june/index.html new file mode 100644 index 00000000..11bf12ab --- /dev/null +++ b/build-staging/it/blog/cwtch-stable-roadmap-update-june/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-stable-roadmap-update/index.html b/build-staging/it/blog/cwtch-stable-roadmap-update/index.html new file mode 100644 index 00000000..76fc1fd8 --- /dev/null +++ b/build-staging/it/blog/cwtch-stable-roadmap-update/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Stable Roadmap Update | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Stable Roadmap Update

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-testing-i/index.html b/build-staging/it/blog/cwtch-testing-i/index.html new file mode 100644 index 00000000..60ccf4b3 --- /dev/null +++ b/build-staging/it/blog/cwtch-testing-i/index.html @@ -0,0 +1,25 @@ + + + + + +Notes on Cwtch UI Testing | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing

· 5 minuti di lettura
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/cwtch-testing-ii/index.html b/build-staging/it/blog/cwtch-testing-ii/index.html new file mode 100644 index 00000000..cf53a5ab --- /dev/null +++ b/build-staging/it/blog/cwtch-testing-ii/index.html @@ -0,0 +1,26 @@ + + + + + +Notes on Cwtch UI Testing (II) | The Cwtch Handbook + + + + + + + + + + + + +
+

Notes on Cwtch UI Testing (II)

· 2 minuti di lettura
Sarah Jamie Lewis

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/feed.json b/build-staging/it/blog/feed.json new file mode 100644 index 00000000..39e376a2 --- /dev/null +++ b/build-staging/it/blog/feed.json @@ -0,0 +1,292 @@ +{ + "version": "https://jsonfeed.org/version/1", + "title": "Cwtch Development Log", + "home_page_url": "https://docs.cwtch.im/it/blog", + "description": "The latest insight into Cwtch Development and what the Cwtch team are working on", + "items": [ + { + "id": "https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update-june", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update-june", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in March we provided an update on several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we provide a new update on those goals", + "date_modified": "2023-06-30T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-nightly-1-12", + "content_html": "

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-nightly-1-12", + "title": "Cwtch Beta 1.12", + "summary": "Cwtch Beta 1.12 is now available for download", + "date_modified": "2023-06-16T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-nightly-v.11-74", + "content_html": "

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-nightly-v.11-74", + "title": "New Cwtch Nightly (v1.11.0-74-g0406)", + "summary": "In this development log we take a look at the new Cwtch Nightly", + "date_modified": "2023-06-07T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-developer-documentation", + "content_html": "

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-developer-documentation", + "title": "Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.", + "summary": "In this development log we take a look at the new Cwtch developer docs!", + "date_modified": "2023-04-28T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "developer-documentation" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/availability-status-profile-attributes", + "content_html": "

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like\nours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are \"Away\" or \"Busy\".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/availability-status-profile-attributes", + "title": "Availability Status and Profile Attributes", + "summary": "Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.", + "date_modified": "2023-04-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "nightly" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update", + "content_html": "

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update", + "title": "Cwtch Stable Roadmap Update", + "summary": "Back in january we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines to hit them. In this post we revisit those and announce some more", + "date_modified": "2023-03-31T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-nightly-1-11", + "content_html": "

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-nightly-1-11", + "title": "Cwtch Beta 1.11", + "summary": "Cwtch Beta 1.11 is now available for download", + "date_modified": "2023-03-29T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "release" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-documentation", + "content_html": "

One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-documentation", + "title": "Updates to Cwtch Documentation", + "summary": " In this development log we will highlight some of the major documentation updates over the last few weeks.", + "date_modified": "2023-03-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "documentation", + "security-handbook" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/autobindings-ii", + "content_html": "

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are\nchanged (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead\nof on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an\ninitialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can\npass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new\ntemplating option exp which will call the function on the configured experiment, and global to allow the setting up\nof a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import \"git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers\"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on\ngeneration of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the\nfeature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced\nin the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/autobindings-ii", + "title": "Compile-time Optional Application Experiments (Autobindings)", + "summary": "In this development log we document how we added compile-time optional application-level experiments to Cwtch autobindings.", + "date_modified": "2023-03-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/autobindings", + "content_html": "

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of\nwhat the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous\ncrash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/autobindings", + "title": "Autogenerating Cwtch Bindings", + "summary": "In this development log we describe a first-cut of a workflow to automatically generate Cwtch C and Java bindings from a high-level specification.", + "date_modified": "2023-02-24T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "bindings", + "autobindings", + "libcwtch" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-testing-ii", + "content_html": "

In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this\ndoesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic\nwithout an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-testing-ii", + "title": "Notes on Cwtch UI Testing (II)", + "summary": "In this development log we provide more updates on automated UI integration testing!", + "date_modified": "2023-02-17T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-android-reproducibility", + "content_html": "

In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-android-reproducibility", + "title": "Making Cwtch Android Bindings Reproducible", + "summary": "In this devlog we revisit reproducible builds and make Cwtch Android bindings reproducible", + "date_modified": "2023-02-10T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-testing-i", + "content_html": "

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like \"take a screenshot\" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on\ndevelopment environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-testing-i", + "title": "Notes on Cwtch UI Testing", + "summary": "In this development log we provide an update on automated UI integration testing!", + "date_modified": "2023-02-03T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support", + "testing" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-platform-support", + "content_html": "

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

\"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.\"

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

\"🟡\" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-platform-support", + "title": "Cwtch UI Platform Support", + "summary": "This development log captures the current state of Cwtch platform support, and how we plan to make platform support decisions going forward are we move towards Cwtch Stable.", + "date_modified": "2023-01-27T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "support" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-bindings-reproducible", + "content_html": "

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/cwtch-bindings-reproducible", + "title": "Making Cwtch Bindings Reproducible", + "summary": "How Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible.", + "date_modified": "2023-01-20T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "reproducible-builds", + "bindings", + "repliqate" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/cwtch-stable-api-design", + "content_html": "

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • \"Unencrypted\" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated \"unencrypted\".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
", + "url": "https://docs.cwtch.im/it/blog/cwtch-stable-api-design", + "title": "Cwtch Stable API Design", + "summary": "The post outlines the technical changes we are planning on making to the core Cwtch API in preparation for Cwtch Stable ", + "date_modified": "2023-01-13T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning", + "api" + ] + }, + { + "id": "https://docs.cwtch.im/it/blog/path-to-cwtch-stable", + "content_html": "

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

\"A

", + "url": "https://docs.cwtch.im/it/blog/path-to-cwtch-stable", + "title": "Path to Cwtch Stable", + "summary": "The post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview the next steps and a timeline to tackle them.", + "date_modified": "2023-01-06T00:00:00.000Z", + "author": { + "name": "Sarah Jamie Lewis" + }, + "tags": [ + "cwtch", + "cwtch-stable", + "planning" + ] + } + ] +} \ No newline at end of file diff --git a/build-staging/it/blog/index.html b/build-staging/it/blog/index.html new file mode 100644 index 00000000..0e00fc3e --- /dev/null +++ b/build-staging/it/blog/index.html @@ -0,0 +1,26 @@ + + + + + +Development Log | The Cwtch Handbook + + + + + + + + + + + + +
+

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 2 minuti di lettura
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 minuti di lettura
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 minuti di lettura
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/page/2/index.html b/build-staging/it/blog/page/2/index.html new file mode 100644 index 00000000..4659984d --- /dev/null +++ b/build-staging/it/blog/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +Development Log | The Cwtch Handbook + + + + + + + + + + + + +
+

· 5 minuti di lettura
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 minuti di lettura
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 minuti di lettura
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 minuti di lettura
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/path-to-cwtch-stable/index.html b/build-staging/it/blog/path-to-cwtch-stable/index.html new file mode 100644 index 00000000..3d9b4471 --- /dev/null +++ b/build-staging/it/blog/path-to-cwtch-stable/index.html @@ -0,0 +1,24 @@ + + + + + +Path to Cwtch Stable | The Cwtch Handbook + + + + + + + + + + + + +
+

Path to Cwtch Stable

· 10 minuti di lettura
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/rss.xml b/build-staging/it/blog/rss.xml new file mode 100644 index 00000000..e6f3fcce --- /dev/null +++ b/build-staging/it/blog/rss.xml @@ -0,0 +1,227 @@ + + + + Cwtch Development Log + https://docs.cwtch.im/it/blog + The latest insight into Cwtch Development and what the Cwtch team are working on + Fri, 30 Jun 2023 00:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + it + Copyright © ${new Date().getFullYear()} Open Privacy Research Society + + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update-june + https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update-june + Fri, 30 Jun 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the Cwtch Stable Roadmap

Back in March we extended and updated several goals from our January roadmap that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of many of these goals, we can look back and see how work is progressing.

(✅ means complete, 🟡 means in-progress, 🕒 reprioritized)

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document ✅ - Release Process
    • A Cwtch Packaging Document ✅ - Packaging Documentation
    • Completion of documentation of existing Cwtch features, including relevant screenshots. 🟡 - new features are documented to the standards outlined in new documentation style guide, and many older feature documentation features have been updated to that standard. Work is ongoing to refine the standard.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries ✅ - Building a Cwtch App
    • Automatically generated API documentation for libCwtch 🕒 - this effort has been delayed pending other higher priority work.
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist. 🟡 - we have recently made a few updates to Repliqate to support this work, and expect to begin in-depth examination of build artifacts in the next couple of weeks.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team 🕒 - after some initial explorations into new Go fuzzing tools we reached the conclusion that it would be better to replace this effort with other assurance work (see below).
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems 🟡 - we have already launched an environment for testing Tails. Other platforms are underway.
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labeled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

Next Steps, Refinements, Additional Work

As you may have noticed above we have reprioritized some work after initial investigations forced us to reevaluate the expected cost/benefit trade-off. This has allowed us to move up timelines for tasks e.g. reproducible UI builds and testing environments.

Other work has been reprioritized due to developer availability. Documentation work in particular has not progressed as fast as we would like.

However, Cwtch Beta 1.12 featured many new features alongside improved performance, more robust packaging, and several fixes impacting experimental features like file sharing.

The work that we have done on reproducible and automatically generated bindings has considerably reduced the maintenance burden associated with updates and adding new features, and has allowed us to also tackle long standing issues related to Tor process managements and Cwtch startup.

We are still on track for releasing a Cwtch Stable release candidate in August 2023, with an official Cwtch Stable release expected shortly afterwards.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.12]]> + https://docs.cwtch.im/it/blog/cwtch-nightly-1-12 + https://docs.cwtch.im/it/blog/cwtch-nightly-1-12 + Fri, 16 Jun 2023 00:00:00 GMT + + Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

In This Release

A screenshot of Cwtch 1.12

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
    • Profile Attributes - profiles can now be augmented with additional public information
    • Availability Status - you can now notify contacts that you are away or busy
    • Five New Supported Localizations: Japanese, Korean, Slovak, Swahili and Swedish
    • Support for Tails - adds an OnionGrater configuration and a new CWTCH_TAILS environment variable that enables special Tor behaviour.
  • Bug Fixes / Improvements:
    • Based on Flutter 3.10
    • Inter is now the main UI font
    • New Font Scaling setting
    • New Network Management code to better manage Tor on unstable networks
    • File Sharing Experiment Fixes
      • Fix performance issues for file bubble
      • Allow restarting of file shares that have timed out
      • Fix NPE in FileBubble caused by deleting the underlying file
      • Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
    • Updates to Linux install scripts to support more distributions
    • Add a Retry Peer connection to prioritize connection attempts for certain conversations
    • Updates to _FlDartProject to allow custom setting of Flutter asset paths
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Slovak, Spanish, Swahili, Swedish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Japanese (29%), Korean (23%), Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.12 is based on libCwtch version libCwtch-autobindings-2023-06-13-10-50-v0.0.5. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.5

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[New Cwtch Nightly (v1.11.0-74-g0406)]]> + https://docs.cwtch.im/it/blog/cwtch-nightly-v.11-74 + https://docs.cwtch.im/it/blog/cwtch-nightly-v.11-74 + Wed, 07 Jun 2023 00:00:00 GMT + + We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-06-05-17-36-v1.11.0-74-g0406.

This version has a large number of improvements and bug fixes including:

  • A new Font Scaling setting
  • Several networking and connection management improvements including automatic detection and response to network changes, and several bug fixes that impacted time-to-connection after a resetting Tor.
  • Updated UI font styles
  • Dependency updates, including a new base of Flutter 3.10.
  • A fix for stuck file downloading notifications on Android
  • A fix for missing profile images in certain edge cases on Android
  • Japanese, Swedish, and Swahili translation options
  • A new retry peer connection button for prompting Cwtch to prioritize specific connections
  • Tails support

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Cwtch Developer Documentation, Cwtchbot v0.1.0 and New Nightly.]]> + https://docs.cwtch.im/it/blog/cwtch-developer-documentation + https://docs.cwtch.im/it/blog/cwtch-developer-documentation + Fri, 28 Apr 2023 00:00:00 GMT + + One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

Cwtch Development Handbook

We have created a new documentation section, the developers handbook. This new section is targeted towards to people working on Cwtch projects (e.g. the official Cwtch library or the Cwtch UI), as well as people who want to build new Cwtch applications (e.g. chat bots or custom clients).

Release and Packaging Process

The new handbook features a breakdown of Cwtch release processes - describing what, and how, build artifacts are created; the difference between nightly and official builds; how the official release process works; and how reproducible build scripts are created.

Cwtch Application Development and Cwtchbot v0.1.0!

For the first time ever we now have comprehensive documentation on how to build a Cwtch Application. This section of the development handbook covers everything from choosing a Cwtch library, to building your first application.

Together with this new documentation we have also released version 0.1 of the Cwtchbot framework, updating calls to use the new Cwtch Stable API.

New Nightly

There is a new Nightly build are available from our build server. The latest nightly we recommend testing is 2023-04-26-20-57-v1.11.0-33-gb4371.

This version has a number of fixes and updates to the file sharing and image previews/profile pictures experiment, and an update to the in-development Tails support.

In addition, this nightly also includes a number of performance improvements that should fix reported rendering issues on less powerful devices.

Please see the contribution documentation for advice on submitting feedback

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + developer-documentation +
+ + <![CDATA[Availability Status and Profile Attributes]]> + https://docs.cwtch.im/it/blog/availability-status-profile-attributes + https://docs.cwtch.im/it/blog/availability-status-profile-attributes + Thu, 06 Apr 2023 00:00:00 GMT + + Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

Availability Status

New in this nightly is the ability to notify your conversations that you are "Away" or "Busy".

Read more: Availability Status

Profile Attributes

Also new is the ability to augment your profile with a few small pieces of public information.

Read more: Profile Information

Downloading the Nightly

Nightly builds are available from our build server. Download links for 2023-04-05-18-28-v1.11.0-7-g0290 are available below.

Please see the contribution documentation for advice on submitting feedback

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + nightly +
+ + <![CDATA[Cwtch Stable Roadmap Update]]> + https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update + https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update + Fri, 31 Mar 2023 00:00:00 GMT + + The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

Update on the January Roadmap

Back in January we outlined several goals that we would have to hit on our way to Cwtch Stable, and the timelines for achieving them. Now that we have reached target date of the last of these goals, we can look back and see how we did:

(✅ means complete, 🟡 means in-progress, ❌ not started.)

  • By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases). ✅
  • By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases. ✅
  • By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for:
  • By 31st March 2023, the Cwtch team will have created:
    • a style guide for documentation, and ✅
    • have used it to ensure that all Cwtch features have consistent documentation available, 🟡
    • with at least one screenshot (where applicable). 🟡
  • By 31st March 2023 the Cwtch team will have published:
  • By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository. ✅
  • By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team ❌
  • By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable ✅ (this post!)

While we didn't hit all of our goals, we did make progress on nearly all of them, and in addition also made progress in a few other key areas:

A Timeline for Cwtch Stable

Now for the big news, we plan on releasing a candidate Cwtch Stable release during Summer 2023. Here is our plan for getting there:

  • By 30th April 2023 the Cwtch team will have written the remaining outstanding documentation from the January roadmap including:
    • A Cwtch Release Process Document
    • A Cwtch Packaging Document
    • Completion of documentation of existing Cwtch features, including relevant screenshots.
  • By 30th April 2023 the Cwtch team will have also released developer-centric documentation including:
    • A guide to building Cwtch-apps using official libraries
    • Automatically generated API documentation for libCwtch
  • By 30th June 2023 the Cwtch team will have released new Cwtch Beta releases (1.12+) featuring:
  • By 31st July 2023 the Cwtch team will have completed several infrastructure upgrades including:
    • Extended reproducible builds to cover the Cwtch UI, or document where the blockers to achieving this exist.
    • Integration of automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team
    • New testing environments for F-droid, Whonix, Raspberry Pi and other partially supported systems
  • By 31st August 2023 the Cwtch team will have a released Cwtch Stable Release Candidate:
    • At this point we expect that the Cwtch application and existing documentation will be robust and complete enough to be labelled as stable.
    • Along with this label comes a higher standard for how we consider all aspects of Cwtch development. The work we have done up to this point reflects a much stronger development pipeline, and an ongoing commitment to security.
    • This does not mark an end to Cwtch development, or new Cwtch features. But it does denote the point at which we consider Cwtch to be appropriate for wider use.

This is not all we have planned for the upcoming months. Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Get Involved

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+ + <![CDATA[Cwtch Beta 1.11]]> + https://docs.cwtch.im/it/blog/cwtch-nightly-1-11 + https://docs.cwtch.im/it/blog/cwtch-nightly-1-11 + Wed, 29 Mar 2023 00:00:00 GMT + + Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

In This Release

A screenshot of Cwtch 1.11

A special thanks to the amazing volunteer translators and testers who made this release possible.

  • New Features:
  • Bug Fixes / Improvements:
    • When preserving a message draft, quoted messages are now also saved
    • Layout issues caused by pathological unicode are now prevented
    • Improved performance of message row rendering
    • Clickable Links: Links in replies are now selectable
    • Clickable Links: Fixed error when highlighting certain URIs
    • File Downloading: Fixes for file downloading and exporting on 32bit Android devices
    • Server Hosting: Fixes for several layout issues
    • Build pipeline now runs automated UI tests
    • Fix issues caused by scrollbar controller overriding
    • Initial support for the Blodeuwedd Assistant (currently compile-time disabled)
    • Cwtch Library:
  • Accessibility / UX:
    • Full translations for Brazilian Portuguese, Dutch, French, German, Italian, Russian, Polish, Spanish, Turkish, and Welsh
    • Core translations for Danish (75%), Norwegian (76%), and Romanian (75%)
    • Partial translations for Luxembourgish (22%), Greek (16%), and Portuguese (6%)

Reproducible Bindings

Cwtch 1.11 is based on libCwtch version 2023-03-16-15-07-v0.0.3-1-g50c853a. The repliqate scripts to reproduce these bindings from source can be found at https://git.openprivacy.ca/cwtch.im/repliqate-scripts/src/branch/main/cwtch-autobindings-v0.0.3-1-g50c853a

Download the New Version

You can download Cwtch from https://cwtch.im/download.

Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Alternatively we also provide a releases-only RSS feed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + release +
+ + <![CDATA[Updates to Cwtch Documentation]]> + https://docs.cwtch.im/it/blog/cwtch-documentation + https://docs.cwtch.im/it/blog/cwtch-documentation + Fri, 10 Mar 2023 00:00:00 GMT + + One of the main streams of work in the lead up to Cwtch Stable has been improving all aspects of Cwtch Documentation. In this development log we will highlight some of the major updates over the last few weeks.

Cwtch Secure Development Handbook

One of the earliest compendiums of Cwtch documentation was the Cwtch Secure Development Handbook. This handbook provided an overview of the various parts of the Cwtch ecosystem, the known risks, and any existing mitigations. The handbook was designed to serve as a guide to developers who were building or extending Cwtch, and over the years it also served as a permanent home for documenting long-standing design decisions.

We have now ported the the handbook to this documentation site, along with updating some of the contents. Over the next few months we will be expanding this section to include new sections on fuzzing, plugins, and client implementation.

Volunteer Development

We have noticed an uptick in the number of people reaching out interested in contributing to Cwtch development. In order to help people get acclimated to our development flow we have created a new section on the main documentation site called Developing Cwtch - there you will find a collection of useful links and information about how to get started with Cwtch development, what libraries and tools we use, how pull requests are validated and verified, and how to choose an issue to work on.

We also also updated our guides on Translating Cwtch and Testing Cwtch.

If you are interested in getting started with Cwtch development then please check it out, and feel free to reach out to team@cwtch.im (or open an issue) with any questions. All types of contributions are eligible for stickers.

Next Steps

We still have more work to do on the documentation front:

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all aspects of Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + documentation + security-handbook +
+ + <![CDATA[Compile-time Optional Application Experiments (Autobindings)]]> + https://docs.cwtch.im/it/blog/autobindings-ii + https://docs.cwtch.im/it/blog/autobindings-ii + Fri, 03 Mar 2023 00:00:00 GMT + + Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

The Structure of an Application Experiment

An application-level experiment consists of:

  1. A set of top-level APIs, e.g. CreateServer, LoadServer, DeleteServer - these are the APIs that we want to expose to calling applications.
  2. An encapsulating structure for the set of APIs, e.g. ServersFunctionality - it is much easy to manage a cohesive set of functionality if it is wrapped up in a single entity.
  3. A global variable that exists at the top level of libCwtch, e.g. var serverExperiment *servers.ServersFunctionality servers - our single pointer to the underlying functionality.
  4. A set of management-related APIs, e.g. Init, UpdateSettings, OnACNEvent - in the case of the server hosting experiment we need to perform specific actions when we start up (e.g. loading unencrypted hosted servers), and when settings are +changed (e.g. if the server hosting experiment is disabled we need to tear down all active servers).
  5. Management code within _startCwtch and _reconnectCwtch that calls the management APIs on the global variable.

From a code generation perspective we already have most of the functionality is place to support (1) - the one major difference being that we need to wrap function calls on the global variable associated with the experiment, instead +of on application or a specific profile.

Most of the effort required to support optional experiments was focused on optionally weaving experiment management code within the template.

New Required Management APIs

To achieve this weaving, we now require application-level experiments to implement an EventHandlerInterface interface and expose itself via an +initialize constructor Init(acn, appDir) -> EventHandlerInterface, and Enable(app, acn).

For now this interface is rather minimal, and has been mapped almost exactly to how the server hosting experiment already worked. If, or when, a new application experiment is required we will likely revisit this interface.

We can then generate, and optionally include blocks of code like:

    <experimentGlobal> = <experimentPackage>.Init(&globalACN, appDir)
eventHandler.AddModule(<experimentGlobal>)
<experimentGlobal>.Enable(application, &globalACN)

and place them at specific points in the code. EventHandler has also been extended to maintain a collection of modules so that it can +pass on interesting events.

Adding Support for Application Experiments in the Spec File

We have introduced a new ! operator which can be used to gate APIs behind a configured experiment. Along with a new +templating option exp which will call the function on the configured experiment, and global to allow the setting up +of a global functionality within the library.

    # Server Hosting Experiment
!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers"
!serverExperiment global serverExperiment *servers.ServersFunctionality servers
!serverExperiment exp CreateServer application password string:description bool:autostart
!serverExperiment exp SetServerAttribute application string:handle string:key string:val
!serverExperiment exp LoadServers application acn password
!serverExperiment exp LaunchServers application acn
!serverExperiment exp LaunchServer application string:handle
!serverExperiment exp StopServer application string:handle
!serverExperiment exp StopServers application
!serverExperiment exp DestroyServers
!serverExperiment exp DeleteServer application string:handle password

Generation-Time Inclusion

Without any arguments provided generate-bindings will not generate code for any experiments.

In order to determine what experimental code to generate, generate-bindings now interprets arguments as enabled compile time experiments, e.g. generate-bindings serverExperiment will turn on +generation of server hosting code, per the spec file above.

Cwtch UI Integration

The UI, and other downstream applications, can now check for support for server hosting by simply checking if the loaded library provides the expected symbols, e.g. c_LoadServers - if it doesn't then the UI is safe to assume the +feature is not available.

A screenshot of the Cwtch UI Settings Pane demonstrating how the Server Hosting experiment option looks when the UI is pointed to a libCwtch compiled without server hosting support.

Nightlies & Next Steps

We are now publishing nightlies of autobinding derived libCwtch-go, along with Repliqate scripts for reproducibility.

With application experiments supported, this phase of autobindings comes to a close. The immediate next steps involve extensive testing and release candidates proving out the new bindings to ensure that no bugs have been introduced +in the migration from libCwtch-go. These candidates will form the basis for Cwtch Beta 1.11.

However, there is still more work to do, and we expect to make progress on a few areas over the next few months, including:

  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface, e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces, e.g. libcwtch-rs.
  • Documentation generation: as another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Autogenerating Cwtch Bindings]]> + https://docs.cwtch.im/it/blog/autobindings + https://docs.cwtch.im/it/blog/autobindings + Fri, 24 Feb 2023 00:00:00 GMT + + The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

A Brief History of Cwtch Bindings

Prior to the modern Flutter-based UI application, the first Cwtch UI prototype was based on Qt, with the bindings automatically generated by therecipe/qt. However, after encountering numerous +crash-bugs on the compiled Arm version for Android, and a few weeks of prototyping different approaches, we settled on Flutter as a replacement UI framework.

As part of early prototyping efforts for Flutter we built out a first version of libCwtch-go, and over the two years of beta development we have evolved that prototype into a functional set of Cwtch bindings.

This approach has not been without side effects. There is still code from those early prototypes floating around in libCwtch-go, inconsistencies in how functions - in particular experimental features - handle settings, duplication of logic between Cwtch and libCwtch-go, and special behaviour in libCwtch-go that better belongs in the core Cwtch library.

As part of a broader effort to refine the Cwtch API in preparation for Cwtch Stable we have taken the opportunity to fix many of these problems.

Cwtch Autobindings

The current lib.go file that encapsulates the vast majority of libCwtch-go currently sits at 1500+ lines of code. However, much of that code is boilerplate calling conventions e.g. the BlockContact API implementation is:

//export c_BlockContact
func c_BlockContact(profilePtr *C.char, profileLen C.int, conversation_id C.int) {
BlockContact(C.GoStringN(profilePtr, profileLen), int(conversation_id))
}

func BlockContact(profileOnion string, conversationID int) {
profile := application.GetPeer(profileOnion)
if profile != nil {
profile.BlockConversation(conversationID)
}
}

All that code is doing is defining a C-compatible API, performing some basic checking of parameters, and passing the result into the core Cwtch library. The two functions themselves support the C-bindings and Java-bindings respectively.

In the new cwtch-autobindings we reduce these multiple lines to a single one:

profile BlockConversation conversation

Defining a profile-level function, called BlockConversation which takes in a single parameter of type conversation.

Using a similar boilerplate-reduction for the reset of lib.go yields 5-basic function prototypes:

  • Application-level functions e.g. CreateProfile
  • Profile-level functions e.g. BlockConversation
  • Profile-level functions that return data e.g. GetMessage
  • Experimental Profile-level feature functions e.g. DownloadFile
  • Experimental Profile-level feature functions that return data e.g. ShareFile

Once aggregated and itemized the full set of bindings for Cwtch applications, profile interactions, and experiments can be described in fewer than 50 lines, including comments. Even including the code necessary to generate the bindings from this specification file (~400 lines), and the code needed to initialize the bindings themselves (~300 lines). This cuts the amount of coded needed by 60%, and eliminates many classes of error and inconsistencies associated with maintaining bindings (e.g. regularizing function calls / checking experiment status / handling error conditions etc.).

Next Steps

Cwtch autobindings work today, are API-compatible with the existing libCwtch-go implements, and can be fully integrated into an existing Cwtch application with minimal effort. However, there are a few areas which need to be addressed prior to a full rollout:

  • Application-level experiments (of which there is only one: Desktop Server Hosting) are not currently supported. This functionality is only tangentially related to the rest of the Cwtch bindings, and necessarily introduces additional dependencies (e.g. on cwtch-server). In the coming weeks we will allow optional application experiments to be enabled at compile time, to allow us to produce smaller bindings for platforms that don't support the experiment, and to allow us to build new kinds of platform-targeted experiments that can take advantage of platform specific features.
  • Dart Library generation: since we now have a formal description of the bindings interface, we can move ahead with also autogenerating the Dart-side of the bindings interface, giving a boost to UI integration of new features, and allowing us to generate tailored versions of the UI interface e.g. one compiled without experiment support. We can also extend the same logic to other downstream interfaces e.g. libcwtch-rs
  • Documentation generation: another benefit of a formal description of the bindings interface, we can easily generate documentation compatible with docs.cwtch.im.
  • Cwtch API: This first cut of autobindings is based on an unreleased version of the core Cwtch library that implements much of the Cwtch Stable API redesign. In a short while we will be merging these features into Cwtch, in preparation for Cwtch 1.11, and beyond.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + bindings + autobindings + libcwtch +
+ + <![CDATA[Notes on Cwtch UI Testing (II)]]> + https://docs.cwtch.im/it/blog/cwtch-testing-ii + https://docs.cwtch.im/it/blog/cwtch-testing-ii + Fri, 17 Feb 2023 00:00:00 GMT + + In this development log, we investigate some text-based UI bugs encountered by Fuzzbot, add more automated UI tests to the pipeline, and announce a new release of the Cwtchbot library.

Constraining Cwtch UI Fields

Fuzzbot identified a few bugs relating to UI layout and text clipping. Certain strings would violate the bounds of their containers and overlap with other UI elements. While this +doesn't pose a safety issue, it is unsightly.

Screenshot demonstrating how certain strings would violate the bounds of their containers.

These cases were fixed by parenting impacted elements in a Container with clip: hardEdge and decoration:BoxDecoration() (note that both of these are required as Container widgets in Flutter cannot set clipping logic +without an associated decoration).

Now these clipped strings are tightly constrained to their container bounds.

These fixes are available in the latest Cwtch Nightly, and will be officially released in Cwtch 1.11.

More Automated UI Tests

We have added two new sets of automated UI tests to our pipeline:

  • 02: Global Settings - these tests check that certain global settings like languages, theme, unknown contacts blocking, and streamer mode work as expected. (PR: 628)
  • 04: Profile Management - these tests check that creating, unlocking, and deleting a profile work as expected. (PR: 632)

New Release of Cwtchbot

Cwtchbot has been updated to use the latest Cwtch 0.18.10 API.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Making Cwtch Android Bindings Reproducible]]> + https://docs.cwtch.im/it/blog/cwtch-android-reproducibility + https://docs.cwtch.im/it/blog/cwtch-android-reproducibility + Fri, 10 Feb 2023 00:00:00 GMT + + In this development log, we continue our previous work on reproducible Cwtch bindings, uncovering the final few sources of variation between our Repliqate scripts and our docker/drone builds, leading to fully reproducible builds for Cwtch Android bindings!

Changes Necessary for Reproducible Android Bindings

After a thorough investigation of the build artifacts produced by Repliqate and Drone we uncovered three additional sources of variation:

  • Insufficient path stripping introduced by Android NDK tools - it turns out that Android builds using NDK versions below 22 are not reproducible as they produce randomized artifacts (through unstripped temporary directory paths appearing in compiled binares). NDK 22 changed the binutils and default linker to versions that correctly strip such paths from build artifacts. As such it was necessary for us to update the NDK version we used. We chose the technically outdated NDK 22 rather than the more modern NDK 25 to minimize Android OS compatibility changes during this switch. However, per our long term support plan, we will be moving towards adopting the latest NDK in the future.
  • Paths in DWARF entries - while we have been unable to track down exactly where these are being introduced, we did track the final difference in the produced bindings to DWARF debug lines embedded in compiled ELF binaries. These entries encoded the actual location of the NDK on the disk of the build machine, instead of the symbolic link that we believed should have been followed. By physically placing the NDK at same location in repliqate as in our Docker container we were able to get these entries to be consistent - however there is still work to do to understand exactly why they are being introduced at all.

Vimdiff comparing the decoded (readelf --debug-dump=line) DWARF debug section of Drone-produced Android bindings v.s. Repliqate-produced. The difference in paths is highlighted.
  • Go Compiler Acquisition - our Docker container was compiling the Go compiler from source, while Repliqate was downloading a pre-compiled version. During debugging we changed the Dockerfile to also download the pre-compiled version in order to eliminate the difference as a potential reproducibility issue. Our tests indicated that there was a difference between artifacts produced by the precompiled compiler v.s. one built from source - this is likely explained by introduced environmental differences caused by the compilation of the compiler itself e.g. the contents/versions of modules in the Go package cache which we have seen as having an impact on other produced binaries.

Repliqate Scripts

With those issues now fixed, Cwtch Android bindings are officially reproducible! The first version that officially met this requirement was 1.10.5, and you can find the Repliqate script under cwtch-bindings-v1.10.5/libcwtch.v1.10.5-android.script in the Cwtch Repliqate scripts repository.

This is another big milestone towards our ultimate goal of full reproducibility for Cwtch releases.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Notes on Cwtch UI Testing]]> + https://docs.cwtch.im/it/blog/cwtch-testing-i + https://docs.cwtch.im/it/blog/cwtch-testing-i + Fri, 03 Feb 2023 00:00:00 GMT + + We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

Current Limitations of Flutter Gherkin

The original flutter_gherkin is under semi-active development; however, the latest published versions don't support using it with flutter test.

  • Flutter Test was originally intended to run single widget/unit tests for a Flutter project.
  • Flutter Drive was originally intended to run integration tests on a device or an emulator.

However, in recent releases these lines have become blurred. The new integration_test package that comes built into newer Flutter releases has support for both flutter drive and flutter test. This was a great change because it decreases the required overhead to run larger integration tests (flutter drive sets up a host-controller model that requires a dedicated control channel to be setup, whereas flutter test can take advantage of the knowledge that it is being run in the same process, and is noticeably faster - very important when the goal is to run tests as often as possible).

There is thankfully code in the flutter_gherkin repository that supports running tests with flutter test, however this code currently has a few issues:

  • The test code generation produces code that doesn't compile without minor changes.
  • Certain functionality like "take a screenshot" does not work on desktop.

Additionally, there are a few limitations in built-in flutter_gherkin steps that we noticed our tests running into:

  • Certain tests that fail with async timeouts will cause Flutter exceptions instead of a failed test.
  • Certain Flutter widgets like DropdownButton are not compatible with built-in steps like tap because they internally contain multiple copies of the same widget.

Because of the above issues we have chosen to fork flutter_gherkin to fix some of these issues, with the intent of contributing significant fixes upstream, while allowing us to iterate faster on Flutter UI testing.

Integrating Tests into the Pipeline

One of the major limitations of flutter test is the lack of a headless mode. In order to successfully run tests in our pipeline we need a headless mode, as most of the containers we use do not have any kind of active display.

Thankfully it is possible to use Xfvb to create a virtual framebuffer, and set DISPLAY to render to that buffer:

export DISPLAY=:99
Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &

This allows us to neutralize our main issue with flutter test, and efficiently run tests in our pipeline.

Catching Bugs!

This small amount of integration work has already caught its first bug.

Once we had fixed most of the issues outlined above, we were still seeing failures on what should have been a very basic scenario. 02_save_load.feature simply turns a set of experiments on and checks that the state is saved. This test runs perfectly fine on +development environments, but when uploaded to our build pipeline it always failed in the same place - turning on the file sharing experiment.

The cause of this was an actual bug in Cwtch UI. The file sharing experiment failed to turn on if the directory $USER_HOME/Downloads didn't exist. This is rarely the case on most real world systems, but is the case in our build pipelines. We have since fixed this behaviour to allow file sharing to be turned on even if the usual Download directories are not available.

As we enable more of our UI tests in our pipeline, and across more platforms, we expect to catch more subtle issues like the above - a big win for people who use Cwtch!

Next Steps

  • More automated tests: We have a nice collection of pre-written tests that we can begin to automatically run within pipelines. We have already begun this work, and anticipate finishing it before Cwtch 1.11.

  • More platforms: Right now UI tests only run on Linux. In order to fully take advantage of these tests we need to be able to run them across our target platforms. We expect to start this work soon; expect more news in a future Cwtch Testing update!

  • More steps: One of our longer-term goals with UI testing was to produce a language around Cwtch testing that went beyond widgets. We had begun to explore this last year with the expect to see the message step. As we grow our test library we will be looking for opportunities to build out additional higher-level and Cwtch-specific constructs, e.g. send a file or set profile picture.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support + testing +
+ + <![CDATA[Cwtch UI Platform Support]]> + https://docs.cwtch.im/it/blog/cwtch-platform-support + https://docs.cwtch.im/it/blog/cwtch-platform-support + Fri, 27 Jan 2023 00:00:00 GMT + + One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

Constraints on support

From CPU architecture, to app store policies, there are a large number of constraints that restrict what platforms Cwtch can target, and how usable Cwtch may be on those systems.

In this section we will highlight the restrictions that we are aware of, and provide a summary of the major external forces that impact our ability to support Cwtch across various platforms.

Limitations on general-purpose computing

In order for Cwtch to work, and be useful, it needs the ability to launch and manage long-lived onion services (in addition to Tor connections to other onion services).

On desktop platforms this is usually a given, but the ability to do that kind of activity on mobile operating systems is severely limited or, in many cases, blocked entirely.

This is the core reason why Cwtch is not available on iOS, and the main reason why Android support often lags behind.

While we expect that Arti will improve the management of onion services and connections, there is no way around the need to have an active process managing such services.

As Appstore restrictions are tightened, and mobile operating systems are likewise restricted, we expect that Cwtch on mobile will have to move to a light-client model, requiring the aid of a companion desktop application to be usable.

We encourage you to support mobile operating system vendors who understand the value of general purpose computing, and who don't place restrictions on what you can do with your own device.

Constraints introduced by the Flutter SDK

The Cwtch UI is based on Flutter, and as such we have some hard boundaries driven by platforms that are supported by the Flutter SDK.

To summarize, as of writing this document those platforms are:

  • Android API 16 and above (arm, arm64, and amd64)
  • Debian-based Linux Distributions (64-bit only)
  • macOS El Capitan (10.11) and above
  • Windows 7 & above (64-bit only)

To put it plainly, without porting Cwtch UI to a different UI platform we cannot support a 32-bit desktop version.

Constraints introduced by Appstore Policy

As of writing, Google is pushing applications to target API 31 or above. This target API version is increased on a regular cadence and usually packaged with greater restrictions on what applications can do. To put it another way, even if our minimum theoretical supported Android version is 16, we are practically limited to a subset of tolerated functionality.

CPU Architecture and Cwtch Bindings

We currently build the Cwtch UI and Cwtch Bindings for a wide variety of platform/architecture combinations (see the table below). Our ability to support a given architecture is driven primarily by the overlap of Go Compiler support, Flutter SDK support, and what architectures the underling operating system is available for.

It is worth noting that there is an explicit dependency between the Bindings and the UI. If we cannot build Cwtch Bindings for a given architecture (i.e. if the Go Compiler does not support a given architectures), then we also cannot offer the Cwtch UI for that architecture.

Architecture / PlatformWindowsLinuxmacOSAndroid
arm✅️
arm64🟡✅️
x86-64 / amd64✅️✅️

"🟡" - indicates that support is possible, but not yet official e.g. arm64 linux (Raspberry Pi).

Testing and official support

As a non-profit, and an open source software project, we are limited in the resources we have to invest. We rely on the Cwtch Release Candidate Testers to do much of the heavy lifting when it comes to Cwtch support on various platforms. This is especially true when it comes to Android variants where, even after testing across the spread of devices available to the Cwtch team, testers still encounter major issues.

We officially only perform full scale automated tests on Linux. With minimal platform regression tests on Windows, Android and OSX. Prior to Cwtch Stable we plan to have support for running automated regression tests across Linux, Windows and Android instances.

End-of-life platforms

Operating Systems are never supported indefinitely. The Flutter SDK may allow support for Windows 7, but Microsoft no longer does. Windows 7 fell out of support on January 14, 2020, Windows 8 followed early this month, on January 10th. 2023. Windows 10 will no longer be support after October 14, 2025.

Likewise, while the Flutter SDK official supports OSX versions back to El Capitan (version 10.11), the oldest OSX version currently supported by Apple is Big Sur (version 11). While it may be possible for us to build different versions of Cwtch targeting different OSX versions, we would be doing so against unsupported SDK versions - incurring not only a support cost, but a possible security one also.

The same fundamental restrictions also impact Linux based distributions. While Flutter supports Ubuntu 18.04, and the platform still receiving updates until April 2023, the Cwtch team does not, because of the outdated version of libc installed on the platform would require a distinct build process. Cwtch currently requires libc 2.31+.

Android versions prior to Android 10 are no longer officially support, and the requirement to target the most recent versions of Android for inclusion on the Google Playstore mean that long term support for Android versions is driven almost entirely by Google. While Flutter technically has support for Android 16 and above (and we target that as a minimum SDK version), because we have to target the most recent SDK for inclusion on Google Playstore, we cannot make guarantees that these SDKs are fully backwards compatible. We encourage volunteers interested in Cwtch Android to join our Cwtch Release Candidate Testers groups to help us understand the limitations of Android support across different API versions.

How we decide to officially support a platform

To help make decisions on what platforms we target for official builds, the Cwtch team have developed four key tenets:

  1. The target platform needs to be officially supported by our development tools - We do not have the resources to maintain forks of the Go compiler or the Flutter SDK that target other operating systems or architectures. The one exception to this rule are non-Debian Linux distributions which while not officially supported by Flutter, are unlikely to have major blockers to official support.
  2. The target operating system needs to be supported by the Vendor - We cannot support a platform that is no longer receiving security updates. Nor do we have the resources to maintain distinct build environments that target out-of-support operating systems. While Cwtch may run on these platforms without additional assistance, we will not schedule work to fix broken support on such platforms. (We may, however, accept Pull Requests from volunteers).
  3. The target platform must be backwards compatible with the most recent version in general use - Even if a system is technically supported by our development tools, and still receives security updates from the vendor, we may still be unbale to officially support it if doing so requires maintaining a separate build environment (because SDK or APIs of dependent libraries are no longer backwards compatible). Like above, Cwtch may run on these platforms without additional assistance, but we will not schedule work to fix broken support on such platforms. (we may, however, accept Pull Requests from volunteers).
  4. People want to use Cwtch on that platform - We will generally only consider new platform support if people ask us about it. If Cwtch isn't available for a platform you want to use it on, then please get in touch and ask us about it!

Summary of official support

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. A version of this table will be maintained as part of the Cwtch Handbook.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOS🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Other Android Distributions🟡🟡Testing Needed.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + support +
+ + <![CDATA[Making Cwtch Bindings Reproducible]]> + https://docs.cwtch.im/it/blog/cwtch-bindings-reproducible + https://docs.cwtch.im/it/blog/cwtch-bindings-reproducible + Fri, 20 Jan 2023 00:00:00 GMT + + From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

How Cwtch Bindings are Built

Since we launched Cwtch Beta we have used Docker containers as part of our continuous build process.

When a new change is merged into the repository it kicks off the Cwtch bindings build pipeline which result in the new source tree being downloaded, inspected, compiled, tested, and eventually packaged for different platforms.

The Cwtch Bindings build pipeline results in four compiled libraries:

These compiled libraries eventually make their way into Cwtch-based applications, like the Cwtch UI.

Making libCwtch Reproducible

Docker containers alone aren't enough to guarantee reproducibility. On inspection of several builds of the same source tree, we noticed a few elements that were distinct to each build:

  • Go Build ID: By default, Go includes a build ID as part of compiled binaries. When using CGO this build ID is non-deterministic and differs for every build. We made the decision to override this build ID for all outputs, setting it to the version of the code being built.
  • Build Paths and Go Environment Variables: By default, Go includes full filesystem paths, and many Go-specific environment variables in the compiled binary – ostensibly to aid with debugging. These can be removed using the trimPath option, which we now specify for all bindings builds.

Linux Specific Considerations

After the general fixes for Go builds are applied, the main variable input that impacts reproducibility is the version of libc that the bindings are compiled against.

Our Drone/Docker build environments are based on Debian Bullseye which provides libc6-dev version 2.31. Other development setups will likely link libc-dev 2.34+.

libc6-dev 2.34 is notable because it removed dependencies on libpthread and libdl – neither are used in libCwtch, but they are currently referenced – which increases the number of sections (and thus the virtual addresses of those sections) defined in the produced ELF file.

This means that in order to reproduce libCwtch Linux bindings it is necessary to have a development environment that will link libc 2.31. We have provided a small, standalone environment which can be used for this purpose (see the section on Next Steps for more information).

Windows Specific Considerations

The headers of PE files technically contain a timestamp field. In recent years an effort has been made to use this field for other purposes, but by default go build will still include the timestamp of the file when producing a DLL file (at least when using CGO).

Fortunately this field can be zeroed out through passing -Xlinker –no-insert-timestamp into the mingw32-gcc process.

With that, and the universal Go fixes outlined above, Windows bindings are now reproducible using the same standalone Linux environment.

Android Specific Considerations

With the above universal Go fixes, Android build artifacts become almost repeatable. And on certain setups they appear to be reproducible. However,achieving full reproducibility for Android builds requires a number of specific environment dependencies, and considerations:

  • Cwtch makes use of GoMobile for compiling Android libraries. We pin to a specific version 43a0384520996c8376bfb8637390f12b44773e65 in our Docker containers. Unlike go build, the trimpPath parameter passed to GoMobile does not strip all development environment paths. This means that the build environment needs consistent directory structures. We have noticed inconsistencies in the detail stripped between setups e.g. cwtch.aar files build by our Docker and Repliqate builds still contain randomized /tmp/go-build* references that developer builds do not. We are still in the process of tracking down how these inconsistencies are introduced.
  • We still use sdk-tools instead of the new commandline-tools. The latest version of sdk-tools is 4333796 and available from: https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip. As part of our plans for Cwtch Stable we will be updating this dependency.
  • Cwtch Android builds currently use OpenJDK 8, unchanged from the earliest prototypes when Android development required Java 8. There is no nice way of obtaining this JDK version anymore, our Docker Containers are based on the now deprecated openjdk:8 image. As with sdk-tooks, as part of our plans for Cwtch Stable we will be updating this dependency.

All of the above mean that we cannot consider Android builds to be reproducible yet, but we believe this is an achievable goal within the next couple of release cycles.

OSX Specific Considerations

Perhaps surprisingly, OSX builds present the biggest reproducibility challenge. Unlike Linux, Windows, and Android builds we do not have a Dockerized build environment for OSX builds - relying instead on a dedicated machine to perform the builds.

As with Linux above, the general fixes for setting Go build id and trimming paths are enough to ensure repeatability on the same machine.

In order to fully guarantee reproducibility, OSX libraries need to be built on the same version of OSX with the same version of Xcode. For reference our current build system uses: Big Sur 11.6.1 with Xcode version 13.2.1.

In an ideal world we would be able to cross-compile OSX libraries on Linux the same way we do for Windows and Android. While there are no technical limits, compiling for OSX is dependent on a proprietary SDK. There is no way to trustfully obtain this SDK from anyone except Apple, and the license appears to strictly prohibit transferring the SDK to non-Apple hardware.

Because of these limitations we cannot yet offer a way to automatically verify OSX builds, in the same way that we can for Linux, Windows, and Android. We will continue to look for ways to bring OSX builds to the same level as the rest of our Windows and Linux distributions.

Introducing Repliqate!

With all the above changes, Cwtch Bindings for Linux and Windows are fully reproducible!

That alone is great, but we also want to make it easier for you to check the reproducibility of our builds yourself! As we noted in the introduction, the whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team.

To make this process accessible we are releasing a new tool called repliqate.

Repliqate makes it easy to construct isolated build environments, powered by Qemu and a standard Debian Cloud Image distribution.

Repliqate runs build-scripts to perform actions like downloading the specific versions of Go used in Cwtch official builds, grabbing a copy of the source code for Cwtch bindings, compiling the latest tagged version, and checking the hash against the same version that is available from builds.openprivacy.ca.

We now provide Repliqate build-scripts for reproducible both Linux libCwtch.so builds, Windows libCwtch.dll builds!

We also have a partially repeatable Android cwtch.aar build script that reproduces the official build environment, which we will be using to complete Android reproducible builds as detailed in the last section.

You can (and I want to highly encourage you to) perform all these steps yourself (either via Repliqate, or a setup with the same specifications) and report back. We want to know if there are any other barriers to reproducing Cwtch bindings, and anything that we can do to make the process easier.

Next Steps

Reproducible bindings are a big achievement, but there is obviously much more to do. In the coming weeks we are committed to undertaking the same process with our Cwtch UI builds to determine what needs to be done to make this as reproducible as bindings.

As we go through this process we also expect to add additional functionality to Repliqate. If you have any feedback or would like to contribute to Repliqate development then please get in touch!

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + reproducible-builds + bindings + repliqate +
+ + <![CDATA[Cwtch Stable API Design]]> + https://docs.cwtch.im/it/blog/cwtch-stable-api-design + https://docs.cwtch.im/it/blog/cwtch-stable-api-design + Fri, 13 Jan 2023 00:00:00 GMT + + Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

Clarifying Terminology

Over the years we have evolved how we talk about the various parts of the Cwtch ecosystem. To make this document clear we have revised and clarified some terms:

  • Cwtch refers to the overall ecosystem including all the component libraries, bindings, and the flagship Cwtch application.
  • Cwtchlib refers to the reference implementation of the Cwtch Protocol / Application framework, currently written in Go.
  • Bindings refers to C/Java/Kotlin/Rust bindings (primarily libcwtch-go) that act as an interface between Cwtchlib and downstream applications.
  • CwtchPeer is where the reference Cwtch API is defined. It is responsible for managing the state of a single Cwtch Profile, persistence (e.g. storing messages), and automatically reacting to certain messages like message acknowledgements and providing public profile attributes (e.g. profile display name).
  • ProtocolEngine is responsible for maintaining networking resources like listening threads, peer connections, ephemeral server connections. At present, ProtocolEngine is also responsible for automatically responding to certain kinds of messages like providing file chunks for shared files.

Tenets of the Cwtch API Design

Based on the tenets we have laid out for the Path to Cwtch Stable, we have adopted the following guiding principles for a new API design:

  • Robustness - new features and functionality can be implemented in Cwtch without adding new functions or dependencies to existing Cwtch interfaces.
  • Completeness - all behaviour is either defined in the official library, or explicitly deferred to applications, no special behaviour is implemented by intermediate wrappers.
  • Security – experiments should not compromise existing Cwtch functionality - and should be able to be turned on/off at any time without issue.

The Cwtch Experiment Landscape

A summary of the experiments that are currently implements or in design, and the changes to the code that were required to support them.

  • Groups – the very first prototypes of Cwtch were designed around group messaging and, as such, multi-party chats are the most integrated experiment within Cwtch sharing interfaces with P2P chat and requiring specialized ProtocolEngine functionality to manage ephemeral connections and antispam tokens, including the introduction of new peer events like NewMessageFromGroup.
    • Hybrid Groups - we have plans to upgrade the Groups experience to a more flexible “hybrid-groups” protocol which requires additional custom hook-response that needs to be tightly controlled and isolated from other parts of the system.
  • Filesharing – like Groups, Filesharing is a cross-cutting feature that required new APIs, new Hooks into Peer Events, and additional capability in ProtocolEngine.
  • Profile Images – based on Filesharing and the core get/val functionality, there are only a few small parts of the codebase that are explicitly dedicated to profile images, and these are all event-based reactions that currently reside in the event-decoration module of licwtch-go, but could easily be moved to a standalone module if a hook-based API was available.
  • Server Hosting – the only example of an Application-level experiment in Cwch at present. This functionality requires no changes to the cwtchlib module, but is mainly implemented in the libcwtch-go bindings themselves. Ideally this functionality would be moved into a standalone package.
  • Message Formatting – notable as the the main example of a former experimental-functionality that was promoted to an optional feature, but because it is entirely UI based in implementation there are few insights that can be gained from its history
  • Search / Microblogging – proposed features that would require database access/changes in order to implement fully and efficiently, any proposed changes to the Cwtch API should allow for the possibility of new functionality at all layers of the Cwtch stack, including storage.
  • Status / Profile Metadata – proposed features that only require specific APIs / hooks for saving requested information for the purposes of caching.

The Problem with Experiments

We have done some work in past to limit the impact an experimental feature can have on the rest of Cwtch, mainly through providing restricted sets of public Cwtch APIs e.g. the SendMessages interface that only allows callers to send messages.

We have also worked to package experimental functionality into so-called Gated Functionalities that are only available if a given experiment is turned on.

Together, these form the current basis for implementing to Cwtch features in the official libraries, but they are not without problems:

  • The scope of a functionality is rather broad, and can only be passed a complete Cwtch profile or a denoted subset of functionality e.g. SendMessages – there is no current way to scope a function to a specific conversation, or to a given zone (e.g. filesharing code is technically able to update attributes unrelated to filesharing).
  • The implementation of experiments has mostly been delegated to bindings and, as such, the gating inside CwtchLib is limited, often relying on state to be passed into it by the bindings, or relying on the bindings explicitly disable the functionality.
  • This lack of ownership over experiments by the official CwtchLib means that libraries based on CwtchLib instead of bindings do not have access to the safeguards provided by the bindings.

Restricting Powerful Cwtch APIs

To carefully expand Cwtch out using additional experimental APIs we must work to limit the impact further e.g. restricting actions to a given type of conversation, or only executing actions at registered times. To do this we require three separate but related strands of work:

  • Assume responsibility for experiments and features in Cwtch itself so that Cwtchlib has direct access to which experiments are enabled at any given time. Doing this allows changes to settings to always flow through Application and, (as currently happens with Anonymous Communication Network (ACN) state), provides a natural point at which to interface those changes into a Cwtch Profile.
  • Finer-grained Interfaces that allow restricting actions to preregistered conversation types e.g. a RestrictedCwtchConversationInterface which decorates a Cwtch Profile interface such that it can only interact with a single conversation – these can then be passed into hooks and interface functions to limit their impact.
  • Registered Hooks at pre-specified points with restricted capabilities – to allow experimental functionality to register interest in certain events, and act on them at the correct time, and to allow CwtchPeer to control which experiments get access to which events at a given time.

Pre-Registered Hooks

In order to implement certain functionality actions need to take place in-between events handled by CwtchPeer. As a motivating example consider a new group membership protocol overlayed above the existing messages. Such a protocol may require checking against group permission settings after receiving a new message, but before inserting it into into the database (e.g. the message author needs to be confirmed against the list of current members authorized to post to the group).

This is currently only possible with invasive changes to the CwtchPeer interface, explicitly inserting a hook point and acting on it. In an ideal design we would be able to register such hooks for most likely events without additional development effort.

We are introducing a new set of Cwtch APIs designed for this purpose:

  • OnNewPeerMessage - hooked prior to inserting the message into the database.
  • OnPeerMessageConfirmed – hooked after a peer message has been inserted into the database.
  • OnEncryptedGroupMessage – hooked after receiving an encrypted message from a group server.
  • OnGroupMessageReceived – hooked after a successful decryption of a group message, but before inserting it into the database.
  • OnContactRequestValue – hooked on request of a scoped (the permission level of the attribute e.g. public or conversation level attributes), zoned ( relating to a specific feature e.g. filesharing or chat), and keyed (the name of the attribute e.g. name or manifest) value from a contact.
  • OnContactReceiveValue – hooked on receipt of a requested scoped,zoned, and keyed value from a contact.

Including the following APIs for managing hooked functionality:

  • RegisterEvents - returns a set of events that the extension is interested processing.
  • RegisterExperiments - returns a set of experiments that the extension is interested in being notified about
  • OnEvent - to be called by CwtchPeer whenever an event registered with RegisterEvents is called (assuming all experiments registered through RegisterExperiments is active)

ProtocolEngine Subsystems

As mentioned in our experiment summary, some functionality needs to be implemented directly in the ProtocolEngine. The ProtocolEngine is responsible for managing networking clients, and sending/receiving packets from those clients to/from a CwtchPeer (via the event bus).

Some types of data are too costly to send over the event bus e.g. requested chunks from shared files, and as such we need to delegate the handling of such data to a ProtocolEngine.

At the moment is this done through the concept of informal “subsystems”, modular add-ons to ProtocolEngine that process certain events. The current informal nature of this design means that there are not hard-and-fast rules regarding what functionality lives in a subsystem, and how subsystems interact with the wider ProtocolEngine ecosystem.

We are formalizing this subsystem into an interface, similar to the hooked functionality in CwtchPeer:

  • RegisterEvents - returns a set of events that the subsystem needs to consume to operate.
  • OnEvent – to be called by ProtocolEngine whenever an event registered with RegisterEvents is called (when all the experiments registered through RegisterExperiments are active)
  • RegisterContexts - returns the set of contexts that the subsystem implements e.g. im.cwtch.filesharing

This also requires a formalization of two engine specific events (for use on the event bus):

  • SendCwtchMessage – encapsulating the existing CwtchPeerMessage that is used internally in ProtocolEngine for messages between subsystems.
  • CwtchMessageReceived – encapsulating the existing handlePeerMessage function which effectively already serves this purpose, but instead of using an Observer pattern, is implemented as an increasingly unwieldy set of if/else blocks.

And the introduction of three additional ProtocolEnine specific events:

  • StartEngineSubsystem – replaces subsystem specific start event, can be driven by functionalities to (re)start protocol specific handling.
  • StopEngineSubsystem – replaces subsystem specific stop event mechanisms, can be driven by functionalities to stop all protocol specific handling.
  • SubsystemStatus – a generic event that can be published by subsystems with a collection of fields useful for debugging

This will allow us to move the following functionality, currently part of ProtocolEngine itself, into generic subsystems:

  • Attribute Lookup Handling - this functionality is currently part of the overloaded handlePeerMessage function, filtered using the Context parameter of the CwtchPeerMessage. As such it can be entirely delegated to a subsystem.
  • Filesharing Chunk Request Handling – this is also part of handlePeerMessage, also filtered using the Context parameter, and is already almost entirely implementing in a standalone subsystem (only routing is handled by handlePeerMessage)
  • Filesharing Start File Share/Stop File Share – this is currently part of the handleEvent behaviour of ProtocolEngine and can be moved into an OnEvent handler of the file sharing subsystem (where such events are already processed).

The introduction of pre-registered hooks in combination with the formalizations of ProtocolEngine subsystems will allow the follow functionality, currently implemented in CwtchPeer or libcwtch-go to be moved to standalone packages:

  • Filesharing makes heavy use of the getval/retval functionality, we can move all of this into a hooked-based functionality extension.
    • Filesharing also depends on the file sharing subsystem to be enabled in a ProtocolEngine. This subsystem is responsible for processing chunk requests.
  • Profile Images – we treat profile images as a specialization of the file sharing function, as such the experiment can operate entirely over apis provided by the filesharing experiment. (Right now this specialization lives in libcwtch-go as hooks into the relevant functions)
  • Legacy Groups – while groups themselves are a first-class consideration for Cwtch, the actual process of constructing and receiving group messages relies heavily on processing of events, or interpreting generic conversation attributes, and as such this functionality can be moved entirely to hooked-based functionality. By doing this we also open the path towards introducing new group protocols based on the same interface.
  • Status/Profile Metadata – status depends entirely on OnPeerRequestValue / OnPeerReceiveValue and requires little Cwtch Peer interaction other than saving the result.

Impact on Enabling (Powerful) New Functionality

None of the above restricts our ability to introduce new functionality in to Cwtch that is dependent on more invasive changes (e.g. direct database access / updates), but they do allow us to structure such changes into discrete modules:

  • Search – a fulltext search feature requires new indexes to be created in Cwtch Storage (likely using the sqlite FT5 module). As an experiment SearchFunctionality would need access to a hook after database setup in order to create and populate those indexes. This is a far more powerful feature than most as it requires direct database access.
  • Non Chat Conversation Contexts - the storage backend work we implemented last year had a long-term goal of enabling non-chat contexts like microblogging. Like search, these kinds of experiments will require deeply integrated access to the Cwtch database.

Application Experiments

One kind of experiment we haven’t touched on yet is additional application functionality, at present we have one main example: Embedded Server Hosting – this allows a Cwtch desktop client to setup and manage Cwtch Servers.

This kind of functionality doesn’t belong in Cwtchlib – as it would necessarily introduce unrelated dependencies into the core library.

This functionality also doesn’t belong in the bindings either. They should be as minimal as possible. To that end, we will be moving this functionality out of the bindings and into dedicated repositories which can be managed via an Application Experiment interface.

Bindings

The last problem to be solved is how to interface experiments with the bindings (libcwtch-go) and ultimately downstream applications.

We can split the bindings into four core areas:

  • Application Management - functionality necessary to manage the core Cwtch application e.g. StartCwtch, ReconnectCwtchForeground, Shutdown, CreateProfile etc. This category also include FreePointer which is necessary for safe memory management.
  • Application Experiments - auxiliary functionality that augments the Cwtch application with new features e.g. Server Hosting etc.
  • Core Profile Management - core non-experimental functionality that requires a profile e.g. ImportBundle, SendMessage etc. These apis take a handle in addition to the parameters needed to call the underlying function.
  • Experimental Profile Features – auxiliary functionality that augments profiles with additional features e.g. ShareFile, SetProfileImage etc. These apis also take a handle.

The flip side of the bindings is the event bus handing which is responsible for maintaining a queue for the downstream application. This queue provides some filtering and enhancement of events to improve performance. This queue can be moved entirely into Application with only GetAppBusEvent defined and exposed in the bindings.

In an ideal future, all of these bindings could be generated automatically from the Cwtchlib interface definitions i.e. there should be no special functionality in the bindings themselves. The generation would need to include C bindings (untyped with automatic checks) and the Dart library calling convention (type safe)

We can define three types of C/Java/Kotlin interface function templates:

  • ProfileMethodName(profilehandle String, args...) – which directly resolves the Cwtch Profile and calls the function.
  • ProfileExperimentalMethodName(profilehandle String, args...) – which checks the current application settings to see if the experiment is enabled, and then resolves the CwtchProfile and calls the function - else errors.
  • ApplicationExperimentalMethodName(args...) – which checks the current application settings to see if the experiment is enabled, and if so, calls the experimental application functionality.

All we need to know from CwtchLib is what methods to export to C bindings, and what template they should use. This can be automatically derived from the context ProfileInterface for the first, exported methods of the various Functionalities for the second, and ApplicationExperiment definitions for the third.

Timelines and Next Actions

  • Freeze any changes to the bindings interface - we have made minimal changes to the bindings in the Cwtch 1.9 and 1.10 – until we have implemented the proposed changes into cwtchlib.
  • As part of Cwtch 1.11 and 1.12 Release Cycles
    • Implement the ProtocolEngine Subsystem Design as outlined above.
    • Implement the Hooks API.
    • Move all special behaviour / extra functionalities in the libcwtch-go bindings into cwtchlib – with the exception of behaviour related to Application Experiments (i.e. Server Hosting).
    • Move event handling from the bindings into Application.
    • Move Application Experiments defined in bindings into their own libraries (or integrate them into existing libraries like cwtch-server) – keeping the existing interface definitions.
  • Once Automated UI Tests have been integrated into the Cwtch UI Repository:
    • Write a generate-cwtch-bindings tool that auto generates the libcwtch-go C/Android bindings and a dart calling convention library from cwtchlib and any configured application experiments libraries
    • Port the existing UI app to use the newly generated dart Cwtch library (this must wait until we have automated UI testing as part of the build process to ensure that there are no regressions during this process).
    • At this point the bindings are based off of the generated library and libcwtch-go is deprecated / replaced with automatically generated and versioned bindings.

As these changes are made, and these goals met we will be posting about them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, all Cwtch development.

Help us go further!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position to, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

Appendix A: Special Behaviour Defined by libcwtch-go

The following is an exhaustive list of functionality currently provided by libcwtch-go bindings instead of the cwtchlib:

  • Application Settings
    • Including Enabling / Disabling Experiment
  • ACN Process Management - starting/stopping/restarting/configuring Tor.
  • Notification Handling - augmenting/suppressing/augmenting interesting event notifications (primarily for Android)
  • Logging Levels - configuring appropriate logging levels (e.g. INFO or DEBUG)
  • Profile Images Helper Functions - handling default profile images for contacts and groups, in addition to looking up custom profile images if the experiment is enabled.
  • UI Contact Structures - aggregating contact information for the main Cwtch UI.
  • Group Experiment Functionality
    • Experiment Gating
    • GetServerInfoList
    • GetServerInfo
    • UI Server Struct Definition
  • Server Hosting Experiment Functionality - creating/deleting/managing the server hosting experiment for desktop Cwtch clients.
  • "Unencrypted" Profile Handling - replacing a blank password with a default password where the underlying API expects a password but the profile has been designated "unencrypted".
  • Image Previews Experiment Handling - automatically starting the downloading of certain file types (when the experiment is enabled).
  • Cwtch UI Reconnection Handling (for Android) - restarting various Cwtch subsystems when the UI attempts to reconnect in circumstances where the Android kernel has killed the underlying process.
  • Cwtch Profile Engine Activation - starting/stopping a ProtocolEngine when requested by the UI, or in response to changes in ACN state.
  • UI Profile Aggregation - aggregating information related to Profiles for the UI (e.g. network connection status / unread messages) into a single event.
  • File sharing restarts
  • UI Event Augmentation - augmenting various internal Cwtch events with information that the UI needs but that isn't directly embedded within the event (e.g. converting handle to a conversation id). Much of this augmentation is legacy, implemented before recent changes to internal Cwtch structs, and likely can either be removed entirely, or delegated into Cwtch itself.
  • Debug Information - special information available to Cwtch debug builds (memory use / active goroutines etc.)
]]>
+ cwtch + cwtch-stable + planning + api +
+ + <![CDATA[Path to Cwtch Stable]]> + https://docs.cwtch.im/it/blog/path-to-cwtch-stable + https://docs.cwtch.im/it/blog/path-to-cwtch-stable + Fri, 06 Jan 2023 00:00:00 GMT + + As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

Tenets of Cwtch Stable

It is important to state that Cwtch Stable does not mean an end to Cwtch development. Rather, it establishes a baseline at which point Cwtch is considered to be a fully supported project. The Cwtch Team have set the following tenets that guide our decision-making and priorities:

  1. Consistent Interface – each new Cwtch release should be accompanied by consistent releases to all support libraries. This requires a stable and documented API so that we can be clear when upgrading a library will result in breaking change for downstream projects. We should not, as a general rule, have to make breaking changes to this API interface in order to support new experimental features.
  2. Universal Availability and Cohesive Support – people who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch.
  3. Reproducible Builds – Cwtch builds should be trivially reproducible, including the ability to reproduce all bundled assets. Reproducibility should not rely on containerization, but all containers used in our build process should be reproducible.
  4. Proven Security – we can demonstrate that Cwtch provides first class security through well documented design, testing, and audit procedures. We should be able to do this for Cwtch in addition to all functional dependencies.

Known Problems

To begin, let's outline the current state of Cwtch and lay out the issues that stand in the way of Cwtch Stable.

  1. Lack of a Stable API for future feature development – while the core Cwtch API has remained fairly unchanged in recent releases we understand that the addition of new features e.g. cohesive group support likely requires new API hooks that allow safe manipulation of Cwtch Profile (transactional semantics and post-event hooks). Before we can even consider a stable release we need to define what this API should look like, and implement it. (Tenet 1)
  2. Special functionality in libCwtch-go – our C-API bridge (libCwtch-go) currently implements a lot of special functionality in support for both experimental features (e.g. profile images) and UI settings. This special behaviour makes it difficult to track feature responsibility. This behaviour must either be pushed back into the main Cwtch library, or defined to be the responsibility of a downstream application e.g. Cwtch UI. (Tenet 1)
  3. libCwtch-rs partial support - we currently do not officially consider libCwtch-rs when updating libCwtch-go as part of our release schedule. Before we can consider a Cwtch Stable release we should have multiple beta releases where libCwtch-rs has full support for any and all new Cwtch features. (Tenet 1, Tenet 2)
  4. Lack of Reproducible Pipelines - while the vast majority of our build pipeline is automated, containerized, and reproducible, there remain bundled assets that cannot be trivially constructed, and assets that have non-reproducible elements (e.g. build-time injected via git tags, and go binaries including build user information). (Tenet 3)
  5. Lack of up to date, and translated, Security Documentation – the Cwtch security handbook is currently isolated from the rest of our documentation and doesn’t benefit from cross-linking, or translations. (Tenet 4)
  6. No Automated UI Tests – we put a lot of work into building out a testing framework for the UI, but it currently sits mostly unused, and unexercised in our build pipelines. We should revisit that work. (Tenet 4)
  7. Code Signing Provider – our previous code signing certificate provider had support issues, and we have not yet decided on a replacement. ( Tenet 4)
  8. Second-class Android Support - while we have put a lot of effort behind Android support across the Beta timeline, it still clearly suffers from additional issues that desktop editions do not. In order to consider Cwtch stable we must resolve all major bugs impacting Android usability. (Tenet 2)
  9. Lack of Fuzzing – while Fuzzbot sets a standard high above most other secure communication applications, we can and should do better. Fuzzbot currently only targets user-endpoint messages, which are the most likely to result in real-world risk, but we should strive to have the same coverage for internal events at both the network level, the internal Cwtch App level, and the event bus level. (Tenet 4)
  10. Lack of Formal Release Acceptance Process – currently the features and experiments that get included in each release are determined in an ad-hoc consensus. This occasionally means that some features are left unsupported on certain platforms, and bugs occasionally arise in platforms (Android in particular) due to “unrelated” changes. In order for Cwtch to be declared stable, a formal acceptance process must ensure that new changes do not break existing features, and that they work across all platforms. (Tenet2, Tenet 4)
  11. Inconsistent Cwtch Information Discovery – our current documentation is split between docs.cwtch.im, cwtch.im and docs.openprivacy.ca, in additional to blogs on Discreet Log. This makes it difficult for people to learn about Cwtch, and also means that our own explanations often must link across multiple different sites. (Tenet 2)
  12. Incomplete Documentation – docs.cwtch.im was very well received. However, it still suffers from incomplete sections, missing links, and an overall lack of screenshots. What screenshots there are lack consistency in sizing, style, and feel. (Tenet 2)

Plan of Action

Outside of the problems that have standalone solutions (e.g. find a new code signing provider, or fix all Android issues), there are a number of higher level activities that need to be completed before we can be confident in a Cwtch Stable release:

  1. Define, Publish, and Implement a Cwtch Interface Specification Documentation – this should include examples of how new (experimental) behaviour might be implemented from finer-grained composition. Must include moving all special functionality out of libCwtch-go. Should be followed up by implementing the proposed design. (Tenet 1, Tenet 4)
  2. Define, Publish, and Implement a Cwtch Release Process – this document should outline the criteria for publishing a new release, the difference between major and minor versions, how features are tested, how regressions are caught before release, and who is responsible for different parts of the process. (Tenet 2)
  3. Define, Publish, and Implement a Cwtch Support Document - including answers to the questions: what systems do we support, how do we decide what systems are supported, how do we handle new OS versions, and how does application support differ from library support. This should also include a list of blockers for systems we wish to support, but currently cannot e.g ios. (Tenet 2)
  4. Define, Publish, and Implement a Cwtch Packaging Document - as a supplement to the Support document we need to define what packaging we support, in addition to what app stores and managers for which we provide official releases. ( Tenet 2)
  5. Define, Publish, and Implement a Reproducible Builds Document – this should cover not only Cwtch binaries, but also Docker containers, and included assets (e.g. Tor binaries). Followed up by implementing the plan into our build pipeline. ( Tenet 3)
  6. Expand the Cwtch Documentation Site – to include the Security Handbook, development blogs, design documentation, and support plans. This should be our only publishing platform, outside of a landing page, and downloads on cwtch.im. This expansion should include a style guide for documentation and screenshots to ensure that we maintain consistent language and visuals when talking about a feature (e.g. we should use the same profile image style, theme, profile names, message style etc.) (Tenet 1, Tenet 2, Tenet 3, Tenet 4)
  7. Expand our Automated Testing to include UI and Fuzzing - integrate UI automated tests into our build pipeline. Expand our fuzzing to include the event bus, and PeerApp packets. Finally, integrate automated fuzzing into the build pipeline, so that all new features are fuzzed to the same level. (Tenet 4)
  8. Re-evaluate all Issues across all Cwtch related repositories – issues are either bugs that need to be fixed before stable (i.e. they are in service of one of the Tenets), new feature ideas that should be scheduled around stable work (i.e. they don’t align with a specific Tenet), or support requests for systems that need input from the Support and Packaging Plans.
  9. Define a Stable Feature Set – there are still a few features which do not exist in Cwtch Beta which would be required for a stable release, such as chat search. Following on from the Cwtch Interface Specification Document, the team should decide what features Cwtch Stable will target, and these features should be prioritized for inclusion in Cwtch 1.11, Cwtch 1.12 and any future Beta releases. (Tenet 1)

Goals and Timelines

With all of that laid out, we are now ready to introduce a timeline for resolving some of these problems, and moving us towards a state where we can launch Cwtch Stable:

  1. By 1st February 2023, the Cwtch team will have reviewed all existing Cwtch issues in line with this document, and established a timeline for including them in upcoming releases (or specifically commit to not including them in upcoming releases).
  2. By 1st February 2023, the Cwtch team will have finalized a feature set that defines Cwtch Stable and established a timeline for including these features in upcoming Cwtch Beta releases.
  3. By 1st February 2023, the Cwtch team will have expanded the Cwtch Documentation website to include a section for Security, Design Documents, Infrastructure and Support, in addition to a new development blog.
  4. By 31st March 2023, the Cwtch team will have created a style guide for documentation and have used it to ensure that all Cwtch features have consistent documentation available, with at least one screenshot (where applicable).
  5. By 31st March 2023 the Cwtch team will have published a Cwtch Interface Specification Document, a Cwtch Release Process Document, a Cwtch Support Plan document, a Cwtch Packaging Document, and a document describing the Reproducible Builds Process. These documents will be available on the newly expanded Cwtch Documentation website.
  6. By 31st March 2023 the Cwtch team will have integrated automated UI tests into the build pipeline for the cwtch-ui repository.
  7. By 31st March 2023 the Cwtch team will have integrated automated fuzzing into the build pipeline for all Cwtch dependencies maintained by the Cwtch team.
  8. By 31st March 2023 the Cwtch team will have committed to a date, timeline, and roadmap for launching Cwtch Stable.

As these documents are written, and these goals met we will be posting them here! Subscribe to our RSS feed, Atom feed, or JSON feed to stay up to date, and get the latest on, Cwtch development.

Help us get there!

We couldn't do what we do without all the wonderful community support we get, from one-off donations to recurring support via Patreon.

If you want to see us move faster on some of these goals and are in a position, please donate. If you happen to be at a company that wants to do more for the community and this aligns, please consider donating or sponsoring a developer.

Donations of $5 or more can opt to receive stickers as a thank-you gift!

For more information about donating to Open Privacy and claiming a thank you gift please visit the Open Privacy Donate page.

A Photo of Cwtch Stickers

]]>
+ cwtch + cwtch-stable + planning +
+
+
\ No newline at end of file diff --git a/build-staging/it/blog/tags/api/index.html b/build-staging/it/blog/tags/api/index.html new file mode 100644 index 00000000..0db9ff96 --- /dev/null +++ b/build-staging/it/blog/tags/api/index.html @@ -0,0 +1,24 @@ + + + + + +Un post etichettati con "api" | The Cwtch Handbook + + + + + + + + + + + + +
+

Un post etichettati con "api"

Visualizza tutte le etichette

· 18 minuti di lettura
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/autobindings/index.html b/build-staging/it/blog/tags/autobindings/index.html new file mode 100644 index 00000000..bf0486d1 --- /dev/null +++ b/build-staging/it/blog/tags/autobindings/index.html @@ -0,0 +1,25 @@ + + + + + +2 post etichettati con "autobindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "autobindings"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/bindings/index.html b/build-staging/it/blog/tags/bindings/index.html new file mode 100644 index 00000000..608466b8 --- /dev/null +++ b/build-staging/it/blog/tags/bindings/index.html @@ -0,0 +1,25 @@ + + + + + +4 post etichettati con "bindings" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 post etichettati con "bindings"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/cwtch-stable/index.html b/build-staging/it/blog/tags/cwtch-stable/index.html new file mode 100644 index 00000000..a5fd5d2f --- /dev/null +++ b/build-staging/it/blog/tags/cwtch-stable/index.html @@ -0,0 +1,26 @@ + + + + + +17 post etichettati con "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 post etichettati con "cwtch-stable"

Visualizza tutte le etichette

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 2 minuti di lettura
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 minuti di lettura
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 minuti di lettura
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/cwtch-stable/page/2/index.html b/build-staging/it/blog/tags/cwtch-stable/page/2/index.html new file mode 100644 index 00000000..5f0d2b0e --- /dev/null +++ b/build-staging/it/blog/tags/cwtch-stable/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 post etichettati con "cwtch-stable" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 post etichettati con "cwtch-stable"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 minuti di lettura
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 minuti di lettura
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 minuti di lettura
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/cwtch/index.html b/build-staging/it/blog/tags/cwtch/index.html new file mode 100644 index 00000000..9cf2e3d2 --- /dev/null +++ b/build-staging/it/blog/tags/cwtch/index.html @@ -0,0 +1,26 @@ + + + + + +17 post etichettati con "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 post etichettati con "cwtch"

Visualizza tutte le etichette

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 2 minuti di lettura
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 minuti di lettura
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 2 minuti di lettura
Sarah Jamie Lewis

Two new Cwtch features are now available to test in nightly: Availability Status and Profile Information.

Additionally, we have also published draft guidance on running Cwtch on Tails that we would like volunteers to test and report back on.

The Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like +ours with a one-off donations or recurring support via Patreon.

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/cwtch/page/2/index.html b/build-staging/it/blog/tags/cwtch/page/2/index.html new file mode 100644 index 00000000..1bcf0b87 --- /dev/null +++ b/build-staging/it/blog/tags/cwtch/page/2/index.html @@ -0,0 +1,24 @@ + + + + + +17 post etichettati con "cwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

17 post etichettati con "cwtch"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 minuti di lettura
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

· 18 minuti di lettura
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 minuti di lettura
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/developer-documentation/index.html b/build-staging/it/blog/tags/developer-documentation/index.html new file mode 100644 index 00000000..b3a67c49 --- /dev/null +++ b/build-staging/it/blog/tags/developer-documentation/index.html @@ -0,0 +1,24 @@ + + + + + +2 post etichettati con "developer-documentation" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "developer-documentation"

Visualizza tutte le etichette

· 2 minuti di lettura
Sarah Jamie Lewis

We are getting close to a 1.12 release. This week we are drawing attention to the latest Cwtch Nightly (2023-06-05-17-36-v1.11.0-74-g0406) that is now available for wider testing.

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

· 3 minuti di lettura
Sarah Jamie Lewis

One of the larger remaining goals outlined in our Cwtch Stable roadmap update is comprehensive developer documentation. We have recently spent some time writing the foundation for these documents.

In this devlog we will introduce some of them, and outline the next steps. We also have a new nightly Cwtch release available for testing!

We are very interested in getting feedback on these documents, and we encourage anyone who is excited to build a Cwtch Bot, or even an alternative UI, to read them over and reach out to us with comments, questions, and suggestions!

As a reminder, the Open Privacy Research Society have also announced they are want to raise $60,000 in 2023 to help move forward projects like Cwtch. Please help support projects like ours with a one-off donations or recurring support via Patreon.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/documentation/index.html b/build-staging/it/blog/tags/documentation/index.html new file mode 100644 index 00000000..12f75c06 --- /dev/null +++ b/build-staging/it/blog/tags/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Un post etichettati con "documentation" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/index.html b/build-staging/it/blog/tags/index.html new file mode 100644 index 00000000..c91e8016 --- /dev/null +++ b/build-staging/it/blog/tags/index.html @@ -0,0 +1,24 @@ + + + + + +Tags | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/libcwtch/index.html b/build-staging/it/blog/tags/libcwtch/index.html new file mode 100644 index 00000000..d7cf7175 --- /dev/null +++ b/build-staging/it/blog/tags/libcwtch/index.html @@ -0,0 +1,25 @@ + + + + + +2 post etichettati con "libcwtch" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "libcwtch"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

Last time we looked at autobindings we mentioned that one of the next steps was introducing support for Application-level experiments. In this development log we will explore what application-level experiments are (technically), and how we added (optional) autobindings support for them.

· 5 minuti di lettura
Sarah Jamie Lewis

The C-bindings for Cwtch evolved as part of Cwtch UI development. After two years of prototyping, development, new features, and revisiting first-implementations we have reached the point where we have a good understanding of +what the bindings need to do, and how they should do it. To that end we have produced a first-cut of a workflow to automatically generate these bindings: cwtch-autobindings.

This this development log we will introduced autobindings, the motivation behind them, and how we plan to use them on the path to Cwtch Stable.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/nightly/index.html b/build-staging/it/blog/tags/nightly/index.html new file mode 100644 index 00000000..b41fcd97 --- /dev/null +++ b/build-staging/it/blog/tags/nightly/index.html @@ -0,0 +1,25 @@ + + + + + +Un post etichettati con "nightly" | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/planning/index.html b/build-staging/it/blog/tags/planning/index.html new file mode 100644 index 00000000..ff1b5aa9 --- /dev/null +++ b/build-staging/it/blog/tags/planning/index.html @@ -0,0 +1,24 @@ + + + + + +4 post etichettati con "planning" | The Cwtch Handbook + + + + + + + + + + + + +
+

4 post etichettati con "planning"

Visualizza tutte le etichette

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap update we provided back in March, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 6 minuti di lettura
Sarah Jamie Lewis

The next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable. We have been working hard towards that goal over the last few months.

This post revisits the Cwtch Stable roadmap we introduced at the start of the year, and provides an overview of the next steps on our journey towards Cwtch Stable.

· 18 minuti di lettura
Sarah Jamie Lewis

Cwtch grew out of a prototype and has been allowed to evolve over time as we discovered better ways of implementing safe and secure metadata resistant communications.

As we grew, we inserted experimental functionality where it was most accessible to place - not, necessarily, where it was ultimately best to place it - this has led to some degree of overlapping, and inconsistent, responsibilities across Cwtch software packages.

As we move out of Beta and towards Cwtch Stable it is time to revisit these previous decisions with both the benefit of hindsight, and years of real-world testing.

In this post we will outline our plans for the Cwtch API that realign responsibilities, and explicitly enable new functionality to be built in a modular, controlled, and secure way. In preparation for Cwtch Stable, and beyond.

· 10 minuti di lettura
Sarah Jamie Lewis

As of December 2022 we have released 10 versions of Cwtch Beta since the initial launch, 18 months ago, in June 2021.

There is a consensus among the team that the next large step for the Cwtch project to take is a move from public Beta to Stable – marking a point at which we consider Cwtch to be secure and usable.

This post outlines the general principles that are guiding the development of Cwtch Stable, the obstacles that prevent a stable Cwtch release, and closes with an overview of the next steps and our timeline for tackling them.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/release/index.html b/build-staging/it/blog/tags/release/index.html new file mode 100644 index 00000000..9534e75a --- /dev/null +++ b/build-staging/it/blog/tags/release/index.html @@ -0,0 +1,24 @@ + + + + + +2 post etichettati con "release" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "release"

Visualizza tutte le etichette

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.12 is now available for download!

Cwtch 1.12 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new features like profile attributes, support for new platforms like Tails, and multiple improvements to performance and stability.

· 3 minuti di lettura
Sarah Jamie Lewis

Cwtch 1.11 is now available for download!

Cwtch 1.11 is the culmination of the last few months of effort by the Cwtch team, and includes many foundational changes that pave the way for Cwtch Stable including new reproducible and automatically generated bindings, as well as support for two new languages (Slovak and Korean), in addition to several performance improvements and bug fixes.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/repliqate/index.html b/build-staging/it/blog/tags/repliqate/index.html new file mode 100644 index 00000000..4e567544 --- /dev/null +++ b/build-staging/it/blog/tags/repliqate/index.html @@ -0,0 +1,24 @@ + + + + + +2 post etichettati con "repliqate" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "repliqate"

Visualizza tutte le etichette

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/reproducible-builds/index.html b/build-staging/it/blog/tags/reproducible-builds/index.html new file mode 100644 index 00000000..d205ac32 --- /dev/null +++ b/build-staging/it/blog/tags/reproducible-builds/index.html @@ -0,0 +1,24 @@ + + + + + +2 post etichettati con "reproducible-builds" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "reproducible-builds"

Visualizza tutte le etichette

· 8 minuti di lettura
Sarah Jamie Lewis

From the start of the Cwtch project, the source code for all components making up Cwtch has been freely available for anyone to inspect, use, and modify.

But open source code is only one defense against malicious actors who might seek to undermine your privacy and security. This is why, as part of our ongoing Cwtch Stable work, we are working towards making all parts of the Cwtch chain reproducible and verifiable.

The whole point of reproducible builds is that you no longer have to trust binaries provided by the Cwtch Team because you can independently verify that the binaries we release are built from the Cwtch source code.

In this devlog we will talk about how Cwtch bindings are currently built, the changes we have made to Cwtch bindings to make future distributions verifiable, and the next steps we will be taking to make all Cwtch builds reproducible. This will be useful to anyone who is looking to reproduce Cwtch bindings specifically, and to anyone who wants to start implementing reproducible builds in their own project.

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/security-handbook/index.html b/build-staging/it/blog/tags/security-handbook/index.html new file mode 100644 index 00000000..71077a18 --- /dev/null +++ b/build-staging/it/blog/tags/security-handbook/index.html @@ -0,0 +1,24 @@ + + + + + +Un post etichettati con "security-handbook" | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/support/index.html b/build-staging/it/blog/tags/support/index.html new file mode 100644 index 00000000..4b686191 --- /dev/null +++ b/build-staging/it/blog/tags/support/index.html @@ -0,0 +1,24 @@ + + + + + +3 post etichettati con "support" | The Cwtch Handbook + + + + + + + + + + + + +
+

3 post etichettati con "support"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

· 11 minuti di lettura
Sarah Jamie Lewis

One of the tenets for Cwtch Stable is Universal Availability and Cohesive Support:

"People who use Cwtch understand that if Cwtch is available for a platform then that means all features will work as expected, that there are no surprise limitations, and any differences are well documented. People should not have to go out of their way to install Cwtch."

This development log seeks to capture the current state of Cwtch platform support, and how we plan to make platform support decisions going forward as we move towards Cwtch Stable.

The questions we aim to answer in this post are:

  • What systems do we currently support?
  • How do we decide what systems are supported?
  • How do we handle new OS versions?
  • How does application support differ from library support?
  • What blockers exist for systems we wish to support, but currently cannot e.g ios?

+ + + + \ No newline at end of file diff --git a/build-staging/it/blog/tags/testing/index.html b/build-staging/it/blog/tags/testing/index.html new file mode 100644 index 00000000..58ba42f4 --- /dev/null +++ b/build-staging/it/blog/tags/testing/index.html @@ -0,0 +1,24 @@ + + + + + +2 post etichettati con "testing" | The Cwtch Handbook + + + + + + + + + + + + +
+

2 post etichettati con "testing"

Visualizza tutte le etichette

· 5 minuti di lettura
Sarah Jamie Lewis

We first introduced UI tests last January. At the time we had developed a suite of UI tests that could be run manually in a development environment. However, we faced a number of issues consistently running these tests in our automated pipelines.

One of the main threads of work that needs to be complete early in the Cwtch Stable roadmap is integrating UI tests into our CI pipelines, in addition to expanding their scope. Now that Flutter 3 has stabilized desktop support, and we have invested effort in improving Cwtch performance, it is time to ensure these tests are running on every build.

+ + + + \ No newline at end of file diff --git a/build-staging/it/developing/building-a-cwtch-app/building-an-echobot/index.html b/build-staging/it/developing/building-a-cwtch-app/building-an-echobot/index.html new file mode 100644 index 00000000..c8eecd01 --- /dev/null +++ b/build-staging/it/developing/building-a-cwtch-app/building-an-echobot/index.html @@ -0,0 +1,25 @@ + + + + + +Building a Cwtch Echobot | The Cwtch Handbook + + + + + + + + + + + + +
+

Building a Cwtch Echobot

In this tutorial we will walk through building a simple Cwtch Echobot. A bot that, when messaged, simply responds with the message it was sent.

For completeness, we will build an Echobot in multiple difference Cwtch frameworks to get a feel for the different levels of functionality offered by each library or +framework.

Using CwtchBot (Go)

CwtchBot Framework

This tutorial uses the CwtchBot framework.

Start by creating a new Go project, and a file main.go. In the main function:

package main

import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
"fmt"
"git.openprivacy.ca/sarah/cwtchbot"
_ "github.com/mutecomm/go-sqlcipher/v4"
"os/user"
"path"
)

func main() {
user, _ := user.Current()
cwtchbot := bot.NewCwtchBot(path.Join(user.HomeDir, "/.echobot/"), "echobot")
cwtchbot.Launch()

// Set Some Profile Information
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "echobot2")
cwtchbot.Peer.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileAttribute1, "A Cwtchbot Echobot")

fmt.Printf("echobot address: %v\n", cwtchbot.Peer.GetOnion())

for {
message := cwtchbot.Queue.Next()
cid, _ := cwtchbot.Peer.FetchConversationInfo(message.Data[event.RemotePeer])
switch message.EventType {
case event.NewMessageFromPeer:
msg := cwtchbot.UnpackMessage(message.Data[event.Data])
fmt.Printf("Message: %v\n", msg)
reply := string(cwtchbot.PackMessage(msg.Overlay, msg.Data))
cwtchbot.Peer.SendMessage(cid.ID, reply)
case event.ContactCreated:
fmt.Printf("Auto approving stranger %v %v\n", cid, message.Data[event.RemotePeer])
// accept the stranger as a new contact
cwtchbot.Peer.AcceptConversation(cid.ID)
// Send Hello...
reply := string(cwtchbot.PackMessage(model.OverlayChat, "Hello!"))
cwtchbot.Peer.SendMessage(cid.ID, reply)
}
}
}

Using Imp (Rust)

Imp (Rust) Bot Framework

This tutorial uses the Imp Cwtch Bot framework (Rust). This framework is currently a work-in-progress and the API design is subject to change. IMP is also based on libcwtch-rs which is currently based on an older pre-stable API version of Cwtch. We are planning in updating libcwtch-rs in Summer 2023.

use std::borrow::BorrowMut;
use std::thread;
use chrono::{DateTime, FixedOffset};
use libcwtch;
use libcwtch::CwtchLib;
use libcwtch::structs::*;
use libcwtch::event::*;
use cwtch_imp::imp;
use cwtch_imp::behaviour::*;
use cwtch_imp::imp::Imp;

const BOT_HOME: &str = "~/.cwtch/bots/echobot";
const BOT_NAME: &str = "echobot";

struct Echobot {}

fn main() {
let behaviour: Behaviour = BehaviourBuilder::new().name(BOT_NAME.to_string()).new_contact_policy(NewContactPolicy::Accept).build();
let event_loop_handle = thread::spawn(move || {
let mut echobot = Echobot {};
let mut bot = Imp::spawn(behaviour,String::new(), BOT_HOME.to_string());
bot.event_loop::<Echobot>(echobot.borrow_mut());
});
event_loop_handle.join().expect("Error running event loop");
}

impl imp::EventHandler for Echobot {
fn on_new_message_from_contact(&self, cwtch: &dyn libcwtch::CwtchLib, profile: &Profile, conversation_id: ConversationID, handle: String, timestamp_received: DateTime<FixedOffset>, message: Message) {
let response = Message {
o: MessageType::TextMessage,
d: message.d,
};
cwtch.send_message(&profile.profile_id, conversation_id, &response);
}

fn handle(&mut self, cwtch: &dyn CwtchLib, profile_opt: Option<&Profile>, event: &Event) {
match event {
Event::NewPeer { profile_id, tag, created, name, default_picture, picture, online, profile_data } => {
println!(
"\n***** {} at {} *****\n",
name, profile_id.as_str()
);
}
_ => (),
};
}
}
+ + + + \ No newline at end of file diff --git a/build-staging/it/developing/building-a-cwtch-app/core-concepts/index.html b/build-staging/it/developing/building-a-cwtch-app/core-concepts/index.html new file mode 100644 index 00000000..0f03ef57 --- /dev/null +++ b/build-staging/it/developing/building-a-cwtch-app/core-concepts/index.html @@ -0,0 +1,24 @@ + + + + + +Core Concepts | The Cwtch Handbook + + + + + + + + + + + + +
+

Core Concepts

This page documents the core concepts that you, as a Cwtch App Developer, will encounter fairly frequently.

Cwtch Home Directory

Often referred to as $CWTCH_HOME, the Cwtch application home directory is the location where Cwtch stores all information from a Cwtch application.

Profiles

Cwtch profiles are saved as encrypted sqlite3 databases. You will rarely/never have to interact directly with the database. Instead each library provides a set of interfaces to interact with the Cwtch App, create profiles, manage profiles, and engage in conversations.

The Event Bus

Regardless of which library you end up choosing, the one constant interface you will have to get used to is the EventBus. Cwtch handles all asynchronous tasks (e.g. receiving a message from a peer) automatically, eventually placing a message on the EventBus. Application can subscribe to certain kinds of messages e.g. NewMessageFromPeer and setup an event handler to run code in response to such a message.

For an example see the Echo Bot tutorial.

Settings

Most Cwtch settings (with the exception of experiments) are designed for downstream graphical user interfaces e.g. themes / column layouts - in particular the Cwtch UI. As such these settings are not used at all by Cwtch libraries, and are only intended as a convenient storage place for UI configuration.

Experiments

Certain Cwtch features are gated behind experiments. These experiments need to be enabled before functionality related to them will activate. Different libraries may expose different experiments, and some libraries may not support certain experiments at all.

+ + + + \ No newline at end of file diff --git a/build-staging/it/developing/building-a-cwtch-app/intro/index.html b/build-staging/it/developing/building-a-cwtch-app/intro/index.html new file mode 100644 index 00000000..1d55add8 --- /dev/null +++ b/build-staging/it/developing/building-a-cwtch-app/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Getting Started | The Cwtch Handbook + + + + + + + + + + + + +
+

Getting Started

Choosing A Cwtch Library

Cwtch Go Lib

The official Cwtch library is written in Go and can be found at https://git.openprivacy.ca/cwtch.im/cwtch. This library allows access to all Cwtch functionality.

CwtchBot

We also provide a specialized Cwtch Bot framework in Go that provides a more lightweight and tailored approach to building chat bots. For an introduction to building chatbots with the CwtchBot framework check out the building an echobot tutorial.

Autobindings (C-bindings)

The official c-bindings for Cwtch are automatically generated from the Cwtch Go Library. The API is limited compared to accessing the Cwtch Go Library directly, and is explicitly tailored towards building the Cwtch UI.

libCwtch-rs (Rust)

An experimental rust-fied version of Cwtch Autobindings is available in libCwtch-rs. While we have plans to officially adopt rust bindings in the future, right now Rust support lags behind the rest of the Cwtch ecosystem.

+ + + + \ No newline at end of file diff --git a/build-staging/it/developing/category/building-a-cwtch-app/index.html b/build-staging/it/developing/category/building-a-cwtch-app/index.html new file mode 100644 index 00000000..70a73ccf --- /dev/null +++ b/build-staging/it/developing/category/building-a-cwtch-app/index.html @@ -0,0 +1,24 @@ + + + + + +Building a Cwtch App | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/developing/intro/index.html b/build-staging/it/developing/intro/index.html new file mode 100644 index 00000000..160f7ec6 --- /dev/null +++ b/build-staging/it/developing/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Introduction to Cwtch Development | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/developing/release/index.html b/build-staging/it/developing/release/index.html new file mode 100644 index 00000000..be4c8c5c --- /dev/null +++ b/build-staging/it/developing/release/index.html @@ -0,0 +1,24 @@ + + + + + +Release and Packaging Process | The Cwtch Handbook + + + + + + + + + + + + +
+

Release and Packaging Process

Cwtch builds are automatically constructed via Drone. In order to be built the tasks must be approved by a project team member.

Automated Testing

Drone carries out a suite of automated tests at various stages of the release pipeline.

Test SuiteRepositoryNotes
Integration Testcwtch.im/cwtchA full exercise of peer-to-peer and group messaging
File Sharing Testcwtch.im/cwtchTests that file sharing and image downloading work as expected
Automated Download Testcwtch.im/cwtchTests that automated image downloading (e.g. profile pictures) work as expected
UI Integration Testcwtch.im/cwtch-uiA suite of Gherkin tests to exercise various UI flows like Creating / Deleting profiles and changing settings

Cwtch Autobindings

Drone produces the following build artifacts for all Cwtch autobindings builds.

Build ArtifactPlatformNotes
android/cwtch-sources.jarAndroidgomobile derived source code for the Android Cwtch library
android/cwtch.aarAndroidAndroid Cwtch library. Supports arm, arm64, and amd64.
linux/libCwtch.hLinuxC header file
linux/libCwtch.soLinuxx64 shared library
windows/libCwtch.hWindowsC header file
windows/libCwtch.dllWindowsx64 bit shared library
macos/libCwtch.arm64.dylibMacOSArm64 shared library
macos/libCwtch.x64.dylibMacOSx64 shared library

UI Nightly Builds

We make unreleased versions of Cwtch available for testing as Cwtch Nightlies.

Each nightly build folder contains a collection of build artifacts e.g. (APK files for Android, installer executables for Android) in single convenient folder. A full list of build artifacts currently produced is as follows:

Build ArtifactPlatformNotes
cwtch-VERSION.apkAndroidSupports arm, arm64, and amd64. Can be sideloaded.
cwtch-VERSION.aabAndroidAndroid App Bundle for publishing to appstores
Cwtch-VERSION.dmgMacOS
cwtch-VERSION.tar.gzLinuxContains the code, libs, and assets in addition to install scripts for various devices
cwtch-VERSION.zipWindows
cwtch-installer-VERSION.exeWindowsNSIS powered installation wizard

Nightly builds are regularly purged from the system

Official Releases

The Cwtch Team meets on a regular basis and reaches consensus based on nightly testing feedback and project roadmaps.

When the decision is made to cut a release build, a nightly version is built with a new git tag reflecting the release version e.g. v.1.12.0. The build artifacts are then copied to the Cwtch release website to a dedicated versioned folder.

Reproducible Builds

We use repliqate to provide reproducible build scripts for Cwtch.

We update the repliqate-scripts repository with scripts for all official releases. Currently only Cwtch bindings are reproducible

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/appearance/index.html b/build-staging/it/docs/category/appearance/index.html new file mode 100644 index 00000000..f9e8ff58 --- /dev/null +++ b/build-staging/it/docs/category/appearance/index.html @@ -0,0 +1,24 @@ + + + + + +Aspetto | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/behaviour/index.html b/build-staging/it/docs/category/behaviour/index.html new file mode 100644 index 00000000..fce853cc --- /dev/null +++ b/build-staging/it/docs/category/behaviour/index.html @@ -0,0 +1,24 @@ + + + + + +Comportamento | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/contribute/index.html b/build-staging/it/docs/category/contribute/index.html new file mode 100644 index 00000000..e660696b --- /dev/null +++ b/build-staging/it/docs/category/contribute/index.html @@ -0,0 +1,24 @@ + + + + + +Contribuisci | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/conversations/index.html b/build-staging/it/docs/category/conversations/index.html new file mode 100644 index 00000000..1c1dc0c5 --- /dev/null +++ b/build-staging/it/docs/category/conversations/index.html @@ -0,0 +1,24 @@ + + + + + +Conversations | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/experiments/index.html b/build-staging/it/docs/category/experiments/index.html new file mode 100644 index 00000000..82103f9f --- /dev/null +++ b/build-staging/it/docs/category/experiments/index.html @@ -0,0 +1,24 @@ + + + + + +Experiments | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/getting-started/index.html b/build-staging/it/docs/category/getting-started/index.html new file mode 100644 index 00000000..91cf7fa4 --- /dev/null +++ b/build-staging/it/docs/category/getting-started/index.html @@ -0,0 +1,24 @@ + + + + + +Getting started | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/groups/index.html b/build-staging/it/docs/category/groups/index.html new file mode 100644 index 00000000..13b67c91 --- /dev/null +++ b/build-staging/it/docs/category/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Groups | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/platforms/index.html b/build-staging/it/docs/category/platforms/index.html new file mode 100644 index 00000000..39dd1936 --- /dev/null +++ b/build-staging/it/docs/category/platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Platforms | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/profiles/index.html b/build-staging/it/docs/category/profiles/index.html new file mode 100644 index 00000000..469df6f6 --- /dev/null +++ b/build-staging/it/docs/category/profiles/index.html @@ -0,0 +1,24 @@ + + + + + +Profili | The Cwtch Handbook + + + + + + + + + + + + +
+

Profili

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/servers/index.html b/build-staging/it/docs/category/servers/index.html new file mode 100644 index 00000000..4bc67d77 --- /dev/null +++ b/build-staging/it/docs/category/servers/index.html @@ -0,0 +1,24 @@ + + + + + +Servers | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/category/settings/index.html b/build-staging/it/docs/category/settings/index.html new file mode 100644 index 00000000..dcf99418 --- /dev/null +++ b/build-staging/it/docs/category/settings/index.html @@ -0,0 +1,24 @@ + + + + + +Impostazioni | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/accept-deny-new-conversation/index.html b/build-staging/it/docs/chat/accept-deny-new-conversation/index.html new file mode 100644 index 00000000..e936b5ec --- /dev/null +++ b/build-staging/it/docs/chat/accept-deny-new-conversation/index.html @@ -0,0 +1,24 @@ + + + + + +Accettare/Declinare nuove conversazioni | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/add-contact/index.html b/build-staging/it/docs/chat/add-contact/index.html new file mode 100644 index 00000000..136b9272 --- /dev/null +++ b/build-staging/it/docs/chat/add-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Starting a New Conversation | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/block-contact/index.html b/build-staging/it/docs/chat/block-contact/index.html new file mode 100644 index 00000000..bc9506be --- /dev/null +++ b/build-staging/it/docs/chat/block-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Bloccare un contatto | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/conversation-settings/index.html b/build-staging/it/docs/chat/conversation-settings/index.html new file mode 100644 index 00000000..92791e8e --- /dev/null +++ b/build-staging/it/docs/chat/conversation-settings/index.html @@ -0,0 +1,24 @@ + + + + + +Accessing Conversation Settings | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/delete-contact/index.html b/build-staging/it/docs/chat/delete-contact/index.html new file mode 100644 index 00000000..d5a94d71 --- /dev/null +++ b/build-staging/it/docs/chat/delete-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Removing a Conversation | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/introduction/index.html b/build-staging/it/docs/chat/introduction/index.html new file mode 100644 index 00000000..cc53dcdd --- /dev/null +++ b/build-staging/it/docs/chat/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Un'introduzione alla chat p2p di Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Un'introduzione alla chat p2p di Cwtch

Cwtch utilizza i servizi onion di Tor v3 per stabilire connessioni anonime, peer-to-peer tra profili.

Come funziona la chat p2p internamente

Per interagire con una persona tra i tuoi contatti in una conversazione peer-to-peer entrambi dovete essere online.

Dopo che la connessione ha successo, entrambe le parti sono coinvolte in un protocollo di autenticazione che:

  • Si assicura che ogni parte abbia accesso alla chiave privata associata alla propria identità pubblica.
  • Genera una chiave di sessione effimera utilizzata per cifrare tutte le comunicazioni successive durante la sessione.

Questo scambio (documentato in dettaglio nel protocollo di autenticazione) è negabile offline, ovvero è possibile per qualsiasi parte forgiare trascrizioni di questo protocollo di scambio a posteriori, e di conseguenza - a fatto avvenuto - è impossibile dimostrare definitivamente che lo scambio è avvenuto davvero.

Una volta che il processo di autenticazione è riuscito, potete comunicare con l'altra persona indisturbatamente, con la sicurezza che nessun altro può apprendere nulla sui contenuti o i metadati della conversazione.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/message-formatting/index.html b/build-staging/it/docs/chat/message-formatting/index.html new file mode 100644 index 00000000..accca004 --- /dev/null +++ b/build-staging/it/docs/chat/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Formattazione messaggio | The Cwtch Handbook + + + + + + + + + + + + +
+

Formattazione messaggio

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l'Esperimento di formattazione messaggio attivato.

Come opzione ulteriore, puoi abilitare Link cliccabili per rendere gli URL nei messaggi cliccabili in Cwtch.

:::

Cwtch attualmente supporta la seguente formattazione markdown per i messaggi:

  • **grassetto** che risulterà in grassetto
  • *corsivo* che risulterà in corsivo
  • < code > codice < /code > (senza spazi) che risulterà in codice
  • ^apice^ che risulterà in apice
  • ^pedice^ che risulterà in pedice
  • ~~barrato~~ che risulterà in barrato
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/reply-to-message/index.html b/build-staging/it/docs/chat/reply-to-message/index.html new file mode 100644 index 00000000..c16cf9dd --- /dev/null +++ b/build-staging/it/docs/chat/reply-to-message/index.html @@ -0,0 +1,24 @@ + + + + + +Rispondere a un messaggio | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/save-conversation-history/index.html b/build-staging/it/docs/chat/save-conversation-history/index.html new file mode 100644 index 00000000..f495f32a --- /dev/null +++ b/build-staging/it/docs/chat/save-conversation-history/index.html @@ -0,0 +1,24 @@ + + + + + +Salvare la cronologia delle conversazioni | The Cwtch Handbook + + + + + + + + + + + + +
+

Salvare la cronologia delle conversazioni

Come impostazione predefinita, per la privacy, Cwtch non conserva la cronologia delle conversazioni tra diverse sessioni.

Per abilitare la cronologia per una specifica conversazione:

  1. Nella finestra della conversazione vai su "Impostazioni"
  2. Vai a "Salva cronologia"
  3. Clicca sul menu a tendina
  4. Scegli "Salva cronologia"
  5. Ora la tua cronologia verrà salvata

La cronologia della conversazione può essere disattivata in qualsiasi momento selezionando "Elimina cronologia" dal menu a discesa.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/share-address-with-friends/index.html b/build-staging/it/docs/chat/share-address-with-friends/index.html new file mode 100644 index 00000000..e5ce58e2 --- /dev/null +++ b/build-staging/it/docs/chat/share-address-with-friends/index.html @@ -0,0 +1,24 @@ + + + + + +Sharing Cwtch Addresses | The Cwtch Handbook + + + + + + + + + + + + +
+

Sharing Cwtch Addresses

There are many ways to share a Cwtch address.

Sharing Your Cwtch Address

  1. Vai al tuo profilo
  2. Fare clic sull'icona della copia indirizzo

Ora è possibile condividere questo indirizzo. Le persone con questo indirizzo saranno in grado di aggiungerti come un contatto Cwtch.

Per informazioni su come bloccare connessioni da persone che non conosci vedi Impostazioni: Blocca connessioni sconosciute

Sharing A Friends Cwtch Address

Inside of Cwtch there is another mechanism for exchanging Cwtch addresses.

info

This documentation page is a stub. You can help by expanding it.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/share-file/index.html b/build-staging/it/docs/chat/share-file/index.html new file mode 100644 index 00000000..4d7eb03d --- /dev/null +++ b/build-staging/it/docs/chat/share-file/index.html @@ -0,0 +1,24 @@ + + + + + +Condividere un file | The Cwtch Handbook + + + + + + + + + + + + +
+

Condividere un file

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l'Esperimento di condivisione file attivato.

Optionally, you can enable Image Previews and Profile Pictures to see display shared image previews in the conversation window.

:::

In una conversazione,

  1. Clicca sull'icona dell'allegato
  2. Trova il file che vuoi inviare
  3. Conferma che vuoi inviarlo

Come funziona la condivisione file con i gruppi? I miei file sono salvati su un server da qualche parte?

I file vengono inviati tramite le connessioni Cwtch onion-to-onion direttamente dalla persona che offre il file alla persona che lo riceve. L'offerta iniziale per inviare un file è pubblicata come una conversazione standard in Cwtch / un normale messaggio in sovraimpressione. Per i gruppi, ciò significa che l'offerta iniziale (contenente il nome del file, la dimensione, l'hash e un nonce) è pubblicata sul server del gruppo, ma poi ogni destinatario si connette al mittente individualmente per ricevere effettivamente il contenuto del file.

Questo significa che devo essere online per inviare un file?

Si. Se la persona che offre il file va offline, dovrai aspettare che sia di nuovo online per riprendere il trasferimento del file. Il protocollo sottostante divide i file in pezzi verificabili e che possono essere richiesti individualmente, in modo tale che in un futura versione sarà possibile "riospitare" un file pubblicato in un gruppo, e anche scaricare da più host contemporaneamente (come una sorta di bittorrent).

Perché ci sono dei nuovi contatti che appaiono nella mia lista?

Ciò è dovuto al modo in cui Cwtch gestisce attualmente le connessioni da indirizzi sconosciuti. Dato che pubblicare un file in un gruppo implica che i membri del gruppo si connettono a te direttamente, alcuni di questi membri potrebbero non essere già nella tua lista contatti, e quindi la loro connessione a te per il download apparirà nella tua lista come una richiesta di contatto.

Che cosa è "SHA512"?

SHA512 è un hash crittografico che può essere utilizzato per verificare che il file scaricato sia una copia corretta del file offerto. Cwtch fa questa verifica per te automaticamente, ma puoi anche provare a fare la tua propria verifica indipendentemente! Nota che includiamo anche un nonce casuale con le offerte di file, cosicché le persone non possano semplicemente richiederti qualsiasi hash casuale che potresti avere, o file di conversazioni di cui non fanno parte.

C'è un limite alla dimensione dei file?

Il limite attuale è di 10 gigabyte per file.

Che cosa sono questi file .manifest?

I file .manifest vengono utilizzati durante il download di un file per verificare che i singoli pezzi siano ricevuti correttamente, e supportare il ripristino di trasferimenti interrotti. Essi contengono anche le informazioni provenienti dall'offerta del file originale. Puoi eliminarli senza problemi una volta completato il download. Su Android, i manifesti vengono memorizzati nella cache dell'app e possono essere cancellati attraverso le impostazioni di sistema.

E i metadati dei file?

Inviamo il nome del file come suggerimento e per aiutare a distinguerlo dalle offerte di altri file. Il percorso completo viene rimosso prima di inviare l'offerta. Bisogna fare attenzione ai metadati nascosti che potrebbero essere memorizzati nel file stesso, cosa che varia a seconda del formato del file. Ad esempio, le immagini potrebbero contenere informazioni sulla geo-localizzazione e informazioni sulla fotocamera che le ha catturate, e i file PDF sono noti per contenere informazioni nascoste come il nome dell'autore o il dispositivo su cui sono stati creati. In generale, si dovrebbe inviare/ricevere file solo a/da persone di cui ci si fida.

Posso scaricare file automaticamente?

If the Image Previews and Profile Pictures experiment is enabled then Cwtch will automatically download images from accepted conversations

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/chat/unblock-contact/index.html b/build-staging/it/docs/chat/unblock-contact/index.html new file mode 100644 index 00000000..9e55f496 --- /dev/null +++ b/build-staging/it/docs/chat/unblock-contact/index.html @@ -0,0 +1,24 @@ + + + + + +Sbloccare un contatto | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/contribute/developing/index.html b/build-staging/it/docs/contribute/developing/index.html new file mode 100644 index 00000000..0a7c565f --- /dev/null +++ b/build-staging/it/docs/contribute/developing/index.html @@ -0,0 +1,24 @@ + + + + + +Developing Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Developing Cwtch

This section documents some ways to get started with Cwtch Development.

Cwtch Issues Tracking Process

All Cwtch issues are tracked from the cwtch-ui git repository, even if the bug/feature originates in an upstream library. This allows us to keep everything in one place.

Issues are generally divided into 4 distinct categories:

  • Unprocessed - These are new issues that have not been discussed by the Cwtch team.
  • Scheduled - These issues have been planned for an upcoming release. They are usually tagged with the release they are expected to be fixed in e.g. cwtch-1.11. A core Cwtch team member is likely working on the issue, or is expecting to work on the issue in the coming weeks.
  • Desired - These are issues that we would like to fix but for some reason we are unable to schedule. This might be because the feature is large and requires a lot of effort, or because there is some blocker (e.g. a missing feature in Flutter or some other library) that prevents work on the feature.
  • Help Wanted - These are generally small issues that we would like to fix but that have been designated low priority. These are ideal first issues for volunteers.

If you would like to work on an open bug/feature, please comment on the issue and a member of the Cwtch team will follow up with advice on where to go from there. This helps us keep track of who is working on what problems, and reduces the amount of duplicate work. We aim to answer most queries within 24 hours, feel free to "bump" an issue if it takes longer than that.

note

Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)

Cwtch Pull-Request Process

All pull-requests must be reviewed and approved by a core Cwtch team member prior to merging. Sarah reviews all new and active pull requests multiple times a week.

Build Bot

All Cwtch projects are set up with automated builds and testing. Every pull request is expected to be able to pass through these pipelines prior to being merged. If buildbot reports a failure then Sarah will work with you to determine the issue, and any necessary fixes.

Buildbot can fail for reasons beyond your control e.g. many of our integration tests rely setting up Tor connections, these can be brittle on occasion and result in timeouts and failures. Always confirm the root cause of a test failure before deciding what to do next.

Useful Resources

note

All contributions are eligible for stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/contribute/documentation/index.html b/build-staging/it/docs/contribute/documentation/index.html new file mode 100644 index 00000000..3643ce32 --- /dev/null +++ b/build-staging/it/docs/contribute/documentation/index.html @@ -0,0 +1,24 @@ + + + + + +Documentation Style Guide | The Cwtch Handbook + + + + + + + + + + + + +
+

Documentation Style Guide

This section documents the expected structure and quality of Cwtch documentation.

Screenshots and Cast of Characters

Most Cwtch documentation should feature at least one screenshot or animated image. Screenshots of the Cwtch application should be focused on the feature being described by the documentation.

To ensure consistency between screenshots we suggest that the profile involved should serve particular, constant, roles.

  • Alice - used to represent the primary profile.
  • Bob - the primary contact, useful when demonstrating peer-to-peer features
  • Carol - a secondary contact, useful when demonstrating group features
  • Mallory - representing a malicious peer (to be used when demonstrating blocking functionality)

Dialogue and Content

Where screenshots and demonstrations show dialogue, conversations, and/or images please keep the conversations short, on a casual topic. Examples include:

  • Organizing a picnic
  • Sharing photos from a vacation
  • Sending a document for review

Experiments

All features that rely on an experiment being enabled should all this out prominently at the top of the page e.g.:

Experiments Required

This feature requires Experiments Enabled and the Example Experiment turned on.

Risks

If a feature might result in destruction of key material or permanent deletion of state, then these should also be called out at the top of the documentation e.g.:

danger

This feature will result in irreversible deletion of key material. This cannot be undone.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/contribute/stickers/index.html b/build-staging/it/docs/contribute/stickers/index.html new file mode 100644 index 00000000..182cbadf --- /dev/null +++ b/build-staging/it/docs/contribute/stickers/index.html @@ -0,0 +1,24 @@ + + + + + +Stickers | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/contribute/testing/index.html b/build-staging/it/docs/contribute/testing/index.html new file mode 100644 index 00000000..2a67859c --- /dev/null +++ b/build-staging/it/docs/contribute/testing/index.html @@ -0,0 +1,24 @@ + + + + + +Testare Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Testare Cwtch

Questa sezione documenta alcuni modi per iniziare a testare Cwtch.

Far girare Fuzzbot

FuzzBot è il nostro bot di test di sviluppo. Puoi aggiungere FuzzBot come contatto: cwtch:4y2hxlxqzautabituedksnh2ulcgm2coqbure6wvfpg4gi2ci25ta5ad.

:::Info Aiuto FuzzBot

L'invio a FuzzBot del messaggio aiuto lo attiverà ad inviare una risposta con tutti i comandi di test attualmente disponibili.

:::

Per maggiori informazioni su FuzzBot consulta il nostro blog sullo sviluppo Discreet Log.

Unisciti al gruppo dei tester delle versioni di Cwtch candidate alla pubblicazione ufficiale

L'invio a Fuzzbot del comando testgroup-invite farà sì che FuzzBot ti inviti al gruppo di tester di Cwtch! Lì puoi fare domande, inviare segnalazioni di bug e offrire feedback.

Cwtch Nightlies

Cwtch Nightly build sono build di sviluppo che contengono nuove funzionalità che sono pronte per essere testate.

Le versioni di sviluppo più recenti di Cwtch sono disponibili dal nostro build server.

Non raccomandiamo che i tester si tengano sempre aggiornati con l'ultimo nightly build. Invece, pubblicheremo un messaggio sul gruppo Tester di versioni di Cwtch candidate al rilascio quando sarà disponibile un nightly build significativa. Un nightly build è considerato significativo se contiene una nuova funzione o un fix a un bug serio.

note

All contributions are eligible for stickers

Submitting Feedback

There are three main ways of submitting testing feedback to the team:

  • Via Cwtch: Either via the Release Candidate Testers Group or directly to a Cwtch team member.
  • Via Gitea: Please open an issue in https://git.openprivacy.ca/cwtch.im/cwtch-ui/issues - please do not worry about duplicate issues, we will de-duplicate as part of our triage process.
  • Via Email: Email team@cwtch.im with the bug report and one of our team will look into it.
note

Due to an issue with our email provider, we are currently unable to consistently send email from our gitea instance. Please regularly check open issues / pull-requests for updates (or subscribe to the repository's RSS feeds)

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/contribute/translate/index.html b/build-staging/it/docs/contribute/translate/index.html new file mode 100644 index 00000000..619672fb --- /dev/null +++ b/build-staging/it/docs/contribute/translate/index.html @@ -0,0 +1,24 @@ + + + + + +Translating Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Translating Cwtch

Se vuoi contribuire con delle traduzioni all'applicazione di Cwtch o a questo manuale, ecco come fare

Contributing Translations to the Cwtch Application

There are two ways to contribute to Cwtch applications.

Join our Lokalise Team

We use Lokalise for managing translations for the Cwtch application.

  1. Sign up for a Lokalise account
  2. Email team@cwtch.im with the language you are interested in translating and an email we can use to invite you to our Lokalise team.

Directly via Git

For new translations, you can make a copy of https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/intl_en.arb and begin translating - you can then either submit pull requests or directly send updates to us (team@cwtch.im) and we will merge them in.

For adding to existing translations you can make pull requests directly on any file in https://git.openprivacy.ca/cwtch.im/cwtch-ui/src/branch/trunk/lib/l10n/ and we will review and merge them in.

Manuale utente di Cwtch

This handbook is translated through Crowdin.

To join our Crowdin project:

  1. Sign up for an account on Crowdin.
  2. Join the cwtch-users-handbook project.

We bundle up changes to the documentation in batches and sync them with the Crowdin project on a regular basis.

note

All contributions are eligible for stickers

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/getting-started/supported_platforms/index.html b/build-staging/it/docs/getting-started/supported_platforms/index.html new file mode 100644 index 00000000..b059090f --- /dev/null +++ b/build-staging/it/docs/getting-started/supported_platforms/index.html @@ -0,0 +1,24 @@ + + + + + +Supported Platforms | The Cwtch Handbook + + + + + + + + + + + + +
+

Supported Platforms

The table below represents our current understanding of Cwtch support across various operating systems and architectures (as of Cwtch 1.10 and January 2023).

In many cases we are looking for testers to confirm that various functionality works. If you are interested in testing Cwtch on a specific platform, or want to volunteer to help us official support a platform not listed here, then check out Contibuting to Cwtch.

Legend:

  • ✅: Officially Supported. Cwtch should work on these platforms without issue. Regressions are treated as high priority.
  • 🟡: Best Effort Support. Cwtch should work on these platforms but there may be documented or unknown issues. Testing may be needed. Some features may require additional work. Volunteer effort is appreciated.
  • ❌: Not Supported. Cwtch is unlikely to work on these systems. We will probably not accept bug reports for these systems.
PlatformOfficial Cwtch BuildsSource SupportNotes
Windows 1164-bit amd64 only.
Windows 1064-bit amd64 only. Not officially supported, but official builds may work.
Windows 8 and below🟡Not supported. Dedicated builds from source may work. Testing Needed.
OSX 10 and below🟡64-bit Only. Official builds have been reported to work on Catalina but not High Sierra
OSX 1164-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1264-bit Only. Official builds supports both arm64 and x86 architectures.
OSX 1364-bit Only. Official builds supports both arm64 and x86 architectures.
Debian 1164-bit amd64 Only.
Debian 10🟡64-bit amd64 Only.
Debian 9 and below🟡64-bit amd64 Only. Builds from source should work, but official builds may be incompatible with installed dependencies.
Ubuntu 22.0464-bit amd64 Only.
Other Ubuntu🟡64-bit Only. Testing needed. Builds from source should work, but official builds may be incompatible with installed dependencies.
CentOS🟡🟡Testing Needed.
Gentoo🟡🟡Testing Needed.
Arch🟡🟡Testing Needed.
Whonix🟡🟡Known Issues. Specific changes to Cwtch are required for support.
Raspian (arm64)🟡Builds from source work.
Other Linux Distributions🟡🟡Testing Needed.
Android 9 and below🟡🟡Official builds may work.
Android 10Official SDK supprts arm, arm64, and amd64 architectures.
Android 11Official SDK supprts arm, arm64, and amd64 architectures.
Android 12Official SDK supprts arm, arm64, and amd64 architectures.
Android 13Official SDK supprts arm, arm64, and amd64 architectures.
LineageOSOfficial SDK supprts arm, arm64, and amd64 architectures.
Other Android Distributions🟡🟡Testing Needed.
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/accept-group-invite/index.html b/build-staging/it/docs/groups/accept-group-invite/index.html new file mode 100644 index 00000000..4d3816fd --- /dev/null +++ b/build-staging/it/docs/groups/accept-group-invite/index.html @@ -0,0 +1,24 @@ + + + + + +Accettare un Invito a un gruppo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/create-group/index.html b/build-staging/it/docs/groups/create-group/index.html new file mode 100644 index 00000000..746fb772 --- /dev/null +++ b/build-staging/it/docs/groups/create-group/index.html @@ -0,0 +1,24 @@ + + + + + +Creare un nuovo gruppo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/edit-group-name/index.html b/build-staging/it/docs/groups/edit-group-name/index.html new file mode 100644 index 00000000..feb8a044 --- /dev/null +++ b/build-staging/it/docs/groups/edit-group-name/index.html @@ -0,0 +1,24 @@ + + + + + +Modificare il nome di un gruppo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/introduction/index.html b/build-staging/it/docs/groups/introduction/index.html new file mode 100644 index 00000000..5d57d5b9 --- /dev/null +++ b/build-staging/it/docs/groups/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Un'introduzione ai gruppi di Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Un'introduzione ai gruppi di Cwtch

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.

:::

Nota: la comunicazione di gruppo resistente ai metadati è ancora un'area di ricerca attiva e ciò che è documentato qui probabilmente cambierà in futuro.

Per impostazione predefinita, Cwtch supporta solo chat peer-to-peer e online. Per supportare le conversazioni con più parti e il recapito offline, è necessaria una terza parte (non fidata). Chiamiamo queste entità terze "server".

Questi server possono essere creati da chiunque e sono pensati per essere sempre online. Il punto fondamentale è che tutte le comunicazioni con un server sono progettate in modo tale che il server abbia il meno possibile informazioni sui contenuti o metadati.

Per molti aspetti la comunicazione con un server è identica a quella con un normale peer Cwtch, comprende tutti gli stessi passi, tuttavia il server agisce sempre come peer in entrata, e il peer in uscita utilizza sempre una coppia di chiavi effimera appena generata - in modo che ogni sessione del server sia disconnessa.

Di conseguenza, le conversazioni peer-server differiscono solo nei tipi di messaggi inviati tra le due parti, con il server che memorizza tutti i messaggi che riceve e quindi permette a qualsiasi client di ripescare i messaggi più vecchi.

The risk model associated with servers is more complicated that peer-to-peer communication, as such we currently require people who want to use servers within Cwtch to opt-in to the Group Chat experiment in order to add, manage and create groups on untrusted servers.

Come funzionano i gruppi sotto il coperchio

Quando una persona vuole iniziare una conversazione di gruppo, in primo luogo genera casualmente una Chiave di gruppo segreta. Tutte le comunicazioni del gruppo verranno cifrate utilizzando questa chiave.

Insieme alla Chiave di gruppo, il creatore del gruppo decide anche il Server Cwtch da utilizzare come host del gruppo. Per ulteriori informazioni su come i Server autenticano se stessi si vedano i pacchetti di chiavi.

Un Identificatore di gruppo è generato utilizzando la chiave di gruppo e il server di gruppo e questi tre elementi sono raggruppati in un invito che può essere inviato ai potenziali membri del gruppo (per esempio tramite connessioni peer-to-peer esistenti).

Per inviare un messaggio al gruppo, un profilo si collega al server che ospita il gruppo (vedi sotto), e crittografa il proprio messaggio con la Chiave di gruppo e genera una firma crittografica sotto l'Identificatore di gruppo, il Server di gruppo e il messaggio decriptato (vedi formati di trasmissione per ulteriori informazioni).

Per ricevere un messaggio dal gruppo, un profilo deve essere collegato al server che ospita il gruppo e scaricare tutti i messaggi (dall'ultima connessione precedente). I profili tentano quindi di decifrare ogni messaggio utilizzando la Chiave di gruppo e in caso di successo cercano di verificare la firma (vedi Server di Cwtch, Gruppi di Cwtch per una panoramica degli attacchi e delle mitigazioni).

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/leave-group/index.html b/build-staging/it/docs/groups/leave-group/index.html new file mode 100644 index 00000000..0ec53301 --- /dev/null +++ b/build-staging/it/docs/groups/leave-group/index.html @@ -0,0 +1,24 @@ + + + + + +Come lasciare un gruppo | The Cwtch Handbook + + + + + + + + + + + + +
+

Come lasciare un gruppo

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.

:::

:::avviso

Questa funzione comporterà la cancellazione irreversibile di materiale chiave. Non può essere annullata.

:::

  1. Nel pannello della chat vai alle impostazioni
  2. Scorri verso il basso fino alla fine del pannello
  3. Clicca su "lascia la conversazione"
  4. Conferma che vuoi lasciare
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/manage-known-servers/index.html b/build-staging/it/docs/groups/manage-known-servers/index.html new file mode 100644 index 00000000..3dc2a361 --- /dev/null +++ b/build-staging/it/docs/groups/manage-known-servers/index.html @@ -0,0 +1,24 @@ + + + + + +Gestire i server | The Cwtch Handbook + + + + + + + + + + + + +
+

Gestire i server

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l'Esperimento Gruppi attivato.

:::

I gruppi Cwtch sono ospitati da server non affidabili. Se vuoi vedere i server di cui sei a conoscenza, il loro stato e i gruppi da essi ospitati:

  1. Nel pannello dei tuoi contatti
  2. Vai all'icona di gestione dei server

Importa un server ospitato localmente

  1. Per importare un server ospitato localmente, clicca su "seleziona server locale"
  2. Seleziona il server che desideri
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/groups/send-invite/index.html b/build-staging/it/docs/groups/send-invite/index.html new file mode 100644 index 00000000..1f88b210 --- /dev/null +++ b/build-staging/it/docs/groups/send-invite/index.html @@ -0,0 +1,24 @@ + + + + + +Inviare inviti a un gruppo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/intro/index.html b/build-staging/it/docs/intro/index.html new file mode 100644 index 00000000..45944acb --- /dev/null +++ b/build-staging/it/docs/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Che cos’è Cwtch? | The Cwtch Handbook + + + + + + + + + + + + +
+

Che cos’è Cwtch?

Cwtch (/kʊtʃ/ - una parola gallese che si traduce approssimativamente in “un abbraccio che crea un luogo sicuro”) è un'applicazione di messaggistica decentralizzata, rispettosa della privacy e resistente ai metadati.

  • Decentralizzata e aperta: non c'è alcun “servizio Cwtch” o “rete Cwtch”. I partecipanti a Cwtch possono ospitare i propri spazi sicuri, o prestare la loro infrastruttura ad altri che cercano uno spazio sicuro. Il protocollo Cwtch è aperto, e chiunque è libero di creare bot, servizi e interfacce utente, e di integrare e interagire con Cwtch.
  • Rispettosa della privacy: Tutta la comunicazione in Cwtch è crittografata end-to-end e si svolge attraverso i servizi onion di Tor v3.
  • Resistente ai metadati: Cwtch è stata progettata in modo tale che nessuna informazione venga scambiata o resa disponibile a qualcuno senza il suo esplicito consenso, inclusi i messaggi on-the-wire e i metadati del protocollo.

Sicurezza e Crittografia

Per uno sguardo più approfondito alla sicurezza, alla privacy e alla sottostante tecnologia di crittografia utilizzata in Cwtch, consulta il nostro Manuale sulla sicurezza

Come iniziare

Puoi scaricare l'ultima versione di Cwtch da https://cwtch.im/download/

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/platforms/tails/index.html b/build-staging/it/docs/platforms/tails/index.html new file mode 100644 index 00000000..ee1cd9f2 --- /dev/null +++ b/build-staging/it/docs/platforms/tails/index.html @@ -0,0 +1,24 @@ + + + + + +Running Cwtch on Tails | The Cwtch Handbook + + + + + + + + + + + + +
+

Running Cwtch on Tails

Nightly Feature

This functionality is currently only available in the Nightly Release builds of Cwtch.

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

The following steps require that Tails has been launched with an Administration Password.

Tails uses Onion Grater to guard access to the control port. We have packaged an oniongrater configuration cwtch-tails.yml and setup script (install-tails.sh) with Cwtch on Linux.

The tails-specific part of the script is reproduced below:

    # Tails needs to be have been setup up with an Administration account
#
# Make Auth Cookie Readable
sudo chmod o+r /var/run/tor/control.authcookie
# Copy Onion Grater Config
sudo cp cwtch.yml /etc/onion-grater.d/cwtch.yml
# Restart Onion Grater so the Config Takes effect
sudo systemctl restart onion-grater.service

When launching, Cwtch on Tails should be passed the CWTCH_TAILS=true environment variable to automatically configure Cwtch for running in a Tails-like environment:

exec env CWTCH_TAILS=true LD_LIBRARY_PATH=~/.local/lib/cwtch/:~/.local/lib/cwtch/Tor ~/.local/lib/cwtch/cwtch

Install Location

The above command, and the below onion grater configuration assume that Cwtch was installed in ~/.local/lib/cwtch/cwtch - if Cwtch was installed somewhere else (or if you are running directly from the download folder) then you will need to adjust the commands.

Onion Grater Configuration

The oniongrater configuration cwtch-tails.yml is reproduced below. As noted this configuration is can likely be restricted much further.

    ---
# TODO: This can likely be restricted even further, especially in regards to the ADD_ONION pattern

- apparmor-profiles:
- '/home/amnesia/.local/lib/cwtch/cwtch'
users:

- 'amnesia'
commands:
AUTHCHALLENGE:

- 'SAFECOOKIE .*'
SETEVENTS:

- 'CIRC WARN ERR'
- 'CIRC ORCONN INFO NOTICE WARN ERR HS_DESC HS_DESC_CONTENT'
GETINFO:

- '.*'
GETCONF:

- 'DisableNetwork'
SETCONF:

- 'DisableNetwork.*'
ADD_ONION:

- '.*'
DEL_ONION:

- '.+'
HSFETCH:

- '.+'
events:
CIRC:
suppress: true
ORCONN:
suppress: true
INFO:
suppress: true
NOTICE:
suppress: true
WARN:
suppress: true
ERR:
suppress: true
HS_DESC:
response:

- pattern: '650 HS_DESC CREATED (\S+) (\S+) (\S+) \S+ (.+)'
replacement: '650 HS_DESC CREATED {} {} {} redacted {}'

- pattern: '650 HS_DESC UPLOAD (\S+) (\S+) .*'
replacement: '650 HS_DESC UPLOAD {} {} redacted redacted'

- pattern: '650 HS_DESC UPLOADED (\S+) (\S+) .+'
replacement: '650 HS_DESC UPLOADED {} {} redacted'

- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH'

- pattern: '650 HS_DESC REQUESTED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC REQUESTED {} NO_AUTH redacted redacted'

- pattern: '650 HS_DESC RECEIVED (\S+) NO_AUTH \S+ \S+'
replacement: '650 HS_DESC RECEIVED {} NO_AUTH redacted redacted'

- pattern: '.*'
replacement: ''
HS_DESC_CONTENT:
suppress: true

Persistence

By default, Cwtch creates $HOME/.cwtch and saves all encrypted profiles and settings files there. In order to save any profiles/conversations in Cwtch on Tails you will have to backup this folder to a non-volatile home.

See the Tails documentation for setting up persistent storage

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/availability-status/index.html b/build-staging/it/docs/profiles/availability-status/index.html new file mode 100644 index 00000000..31e2b4fa --- /dev/null +++ b/build-staging/it/docs/profiles/availability-status/index.html @@ -0,0 +1,24 @@ + + + + + +Setting Availability Status | The Cwtch Handbook + + + + + + + + + + + + +
+

Setting Availability Status

Nightly Feature

This functionality is currently only available in the Nightly Release builds of Cwtch.

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

On the conversations pane click the Status icon next to your profile picture.

A drop-down menu will appear with various options e.g. Available, Away, and Busy

When you select Away or Busy as a status the border of your profile picture will change to reflect the status

Contacts will see this change reflected in their conversations pane.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/change-name/index.html b/build-staging/it/docs/profiles/change-name/index.html new file mode 100644 index 00000000..2d412127 --- /dev/null +++ b/build-staging/it/docs/profiles/change-name/index.html @@ -0,0 +1,24 @@ + + + + + +Cambiare il tuo nome visualizzato | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/change-password/index.html b/build-staging/it/docs/profiles/change-password/index.html new file mode 100644 index 00000000..3cacf593 --- /dev/null +++ b/build-staging/it/docs/profiles/change-password/index.html @@ -0,0 +1,24 @@ + + + + + +Modificare la tua password | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/change-profile-image/index.html b/build-staging/it/docs/profiles/change-profile-image/index.html new file mode 100644 index 00000000..3cd970fe --- /dev/null +++ b/build-staging/it/docs/profiles/change-profile-image/index.html @@ -0,0 +1,24 @@ + + + + + +Modificare la tua immagine del profilo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/create-a-profile/index.html b/build-staging/it/docs/profiles/create-a-profile/index.html new file mode 100644 index 00000000..fe5aa357 --- /dev/null +++ b/build-staging/it/docs/profiles/create-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Creare un nuovo profilo | The Cwtch Handbook + + + + + + + + + + + + +
+

Creare un nuovo profilo

  1. Clicca sul pulsante di azione "+" nell'angolo in basso a destra e seleziona "Nuovo profilo"
  2. Seleziona un nome da visualizzare
  3. Seleziona se vuoi proteggere questo profilo localmente con crittografia avanzata:
    • Password: il tuo account è protetto da altre persone che potrebbero utilizzare questo dispositivo
    • Nessuna password: chiunque abbia accesso a questo dispositivo ha la possibilità di accedere a questo profilo
  4. Inserisci nuovamente la tua password
  5. Clicca su aggiungi nuovo profilo

Una nota sui profili protetti da password (crittografati)

I profili sono memorizzati localmente sul disco e crittografati utilizzando una chiave derivata dalla password conosciuta dall'utente (tramite pbkdf2).

Note that, once encrypted and stored on disk, the only way to recover a profile is by rederiving the key from the password - as such it isn't possible to provide a full list of profiles a user might have access to until they enter a password.

Vedi anche: Manuale sulla sicurezza di Cwtch: Crittografia del profilo & spazio di archiviazione

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/delete-profile/index.html b/build-staging/it/docs/profiles/delete-profile/index.html new file mode 100644 index 00000000..6252236e --- /dev/null +++ b/build-staging/it/docs/profiles/delete-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Eliminare un profilo | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/exporting-profile/index.html b/build-staging/it/docs/profiles/exporting-profile/index.html new file mode 100644 index 00000000..ff40319d --- /dev/null +++ b/build-staging/it/docs/profiles/exporting-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Backup o esportazione di un profilo | The Cwtch Handbook + + + + + + + + + + + + +
+

Backup o esportazione di un profilo

Nella schermata di Gestione del profilo:

  1. Seleziona la matita accanto al profilo che vuoi modificare
  2. Scorri verso il basso fino alla fine del menú
  3. Seleziona "Esporta profilo"
  4. Scegli una posizione e un nome per il file
  5. Conferma

Una volta confermato, Cwtch inserirà una copia del profilo alla posizione indicata. Questo file viene crittografato allo stesso livello del profilo. Vedi Una nota sui profili protetti da password (crittografati) per ulteriori informazioni sui profili crittografati.

Questo file può essere importato in un'altra istanza di Cwtch su qualsiasi dispositivo.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/importing-a-profile/index.html b/build-staging/it/docs/profiles/importing-a-profile/index.html new file mode 100644 index 00000000..3995d479 --- /dev/null +++ b/build-staging/it/docs/profiles/importing-a-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Importare un profilo | The Cwtch Handbook + + + + + + + + + + + + +
+

Importare un profilo

  1. Clicca sul pulsante di azione "+" nell'angolo in basso a destra e seleziona "Importa profilo"
  2. Seleziona il file di un profilo Cwtch esportato da importare
  3. Inserisci la password associata al profilo e conferma.

Una volta confermato, Cwtch tenterà di decifrare il file fornito utilizzando una chiave derivata dalla password fornita. Se l'operazione ha successo il profilo verrà visualizzato nella schermata Gestione profilo e sarà pronto per l'uso.

:::nota

Mentre un profilo può essere importato su più dispositivi, attualmente si puó avere una sola versione di un profilo in uso su tutti i dispositivi ad un dato momento.

Tentativi di utilizzare lo stesso profilo su più dispositivi possono causare problemi di disponibilità e errori di messaggistica.

:::

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/introduction/index.html b/build-staging/it/docs/profiles/introduction/index.html new file mode 100644 index 00000000..7fc82ca7 --- /dev/null +++ b/build-staging/it/docs/profiles/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Un'introduzione ai profili di Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Un'introduzione ai profili di Cwtch

Su Cwtch puoi creare uno o piú Profili. Ogni profilo genera una coppia di chiavi ed25519 casuale compatibile con la rete Tor.

Questo è l'identificatore che puoi fornire ad altre persone e che possono usare per contattarti tramite Cwtch.

Cwtch ti permette di creare e gestire multipli profili separati. Ogni profilo è associato a una diversa coppia di chiavi che lancia un diverso servizio "onion".

Gestire i profili

All'avvio Cwtch avvierà la schermata Gestione Profili. Da questa schermata è possibile:

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/profile-info/index.html b/build-staging/it/docs/profiles/profile-info/index.html new file mode 100644 index 00000000..f4a34aca --- /dev/null +++ b/build-staging/it/docs/profiles/profile-info/index.html @@ -0,0 +1,24 @@ + + + + + +Setting Profile Attributes | The Cwtch Handbook + + + + + + + + + + + + +
+

Setting Profile Attributes

Nightly Feature

This functionality is currently only available in the Nightly Release builds of Cwtch.

This functionality may be incomplete and/or dangerous if misused. Please help us to review, and test.

On the profile management pane there are three free-form text fields below your profile picture.

You can fill these fields with any information your would like potential contacts to know. This information is public - do not put any information in here that you do not want to share with everyone.

Contacts will be able to see this information in conversation settings

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/profiles/unlock-profile/index.html b/build-staging/it/docs/profiles/unlock-profile/index.html new file mode 100644 index 00000000..85d4817f --- /dev/null +++ b/build-staging/it/docs/profiles/unlock-profile/index.html @@ -0,0 +1,24 @@ + + + + + +Sbloccare profili crittografati | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/servers/create-server/index.html b/build-staging/it/docs/servers/create-server/index.html new file mode 100644 index 00000000..00eee97b --- /dev/null +++ b/build-staging/it/docs/servers/create-server/index.html @@ -0,0 +1,24 @@ + + + + + +Come creare un server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/servers/delete-server/index.html b/build-staging/it/docs/servers/delete-server/index.html new file mode 100644 index 00000000..3f857785 --- /dev/null +++ b/build-staging/it/docs/servers/delete-server/index.html @@ -0,0 +1,24 @@ + + + + + +Come eliminare un server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/servers/edit-server/index.html b/build-staging/it/docs/servers/edit-server/index.html new file mode 100644 index 00000000..3391e966 --- /dev/null +++ b/build-staging/it/docs/servers/edit-server/index.html @@ -0,0 +1,24 @@ + + + + + +Come modificare un server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/servers/introduction/index.html b/build-staging/it/docs/servers/introduction/index.html new file mode 100644 index 00000000..0f06a807 --- /dev/null +++ b/build-staging/it/docs/servers/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Introduzione ai server | The Cwtch Handbook + + + + + + + + + + + + +
+

Introduzione ai server

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.

:::

La chat Cwtch da contatto a contatto è completamente peer to peer, il che significa se un peer è offline, non si può chattare, e non c'è alcun meccanismo per chat tra più persone.

Per supportare la chat di gruppo (e il recapito offline) abbiamo creato server Cwtch non affidabili che possono ospitare messaggi per un gruppo. I messaggi sono cifrati con la chiave di gruppo e recuperati tramite servizi "onion" effimeri, in modo che il server non ha modo di sapere di quali messaggi per quali gruppi potrebbe essere in possesso, o chi sta accedendo.

Attualmente fare girare dei server nell'app di Cwtch è supportato solo nella versione Desktop in quanto i dispositivi di telefonia mobile hanno connessione internet e configurazione troppo instabili o inadatte ad ospitare un server.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/servers/share-key/index.html b/build-staging/it/docs/servers/share-key/index.html new file mode 100644 index 00000000..04edaaab --- /dev/null +++ b/build-staging/it/docs/servers/share-key/index.html @@ -0,0 +1,24 @@ + + + + + +Come condividere il tuo pacchetto di chiavi del server | The Cwtch Handbook + + + + + + + + + + + + +
+

Come condividere il tuo pacchetto di chiavi del server

:::attenzione Esperimenti necessari

Questa funzione richiede Esperimenti abilitati e l' Esperimento di server hosting attivato.

:::

Il pacchetto di chiavi del server è il pacchetto di dati di cui un'app Cwtch ha bisogno per poter usare un server. Se vuoi solo far conoscere agli altri utenti Cwtch il tuo server, puoi condividere questo pacchetto con loro. Chi riceve il pacchetto avrà a quel punto la capacità di creare i propri gruppi sul server.

  1. Vai all'icona del server
  2. Seleziona il server desiderato
  3. Utilizza l'icona di "copia indirizzo" per copiare le chiavi del server
  4. Non condividere le chiavi con persone di cui non ti fidi
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/servers/unlock-server/index.html b/build-staging/it/docs/servers/unlock-server/index.html new file mode 100644 index 00000000..24a15279 --- /dev/null +++ b/build-staging/it/docs/servers/unlock-server/index.html @@ -0,0 +1,24 @@ + + + + + +Come sbloccare un server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/appearance/change-language/index.html b/build-staging/it/docs/settings/appearance/change-language/index.html new file mode 100644 index 00000000..3ca09676 --- /dev/null +++ b/build-staging/it/docs/settings/appearance/change-language/index.html @@ -0,0 +1,24 @@ + + + + + +Cambia lingua | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/appearance/light-dark-mode/index.html b/build-staging/it/docs/settings/appearance/light-dark-mode/index.html new file mode 100644 index 00000000..1d226584 --- /dev/null +++ b/build-staging/it/docs/settings/appearance/light-dark-mode/index.html @@ -0,0 +1,24 @@ + + + + + +Modalità chiara/scura e scomposizione dei temi | The Cwtch Handbook + + + + + + + + + + + + +
+

Modalità chiara/scura e scomposizione dei temi

  1. Clicca sull'icona impostazione
  2. Puoi scegliere un tema chiaro o scuro interagendo con l'interruttore "usa temi chiari"
  3. Utilizzando il menu a tendina “tema colori”, scegli un tema che ti piace
    1. Cwtch: toni di viola
    2. Fantasma: toni di grigio
    3. Sirena: toni di turchese e viola
    4. Mezzanotte: toni neri e grigi
    5. Neon 1: toni viola e rosa
    6. Neon 2: toni viola e turchese
    7. Zucca: toni viola e arancione
    8. Strega: toni verdi e rosa
    9. Vampiro: toni viola e rossi
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/appearance/streamer-mode/index.html b/build-staging/it/docs/settings/appearance/streamer-mode/index.html new file mode 100644 index 00000000..7ee27efd --- /dev/null +++ b/build-staging/it/docs/settings/appearance/streamer-mode/index.html @@ -0,0 +1,24 @@ + + + + + +Modalità Streamer/Presentazione | The Cwtch Handbook + + + + + + + + + + + + +
+

Modalità Streamer/Presentazione

La modalità Streamer/Presentazione rende l'applicazione visivamente più privata. In this mode, Cwtch will not display auxiliary information like Cwtch addresses and other sensitive information on the main screens.

Questo è utile quando si catturano screenshot o in altro modo si mostra Cwtch più "pubblicamente".

  1. Clicca sull'icona impostazione
  2. Imposta la "Modalità Streamer" su On
  3. Controlla che funzioni guardando il tuo profilo la tua lista di contatti
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/appearance/ui-columns/index.html b/build-staging/it/docs/settings/appearance/ui-columns/index.html new file mode 100644 index 00000000..7e5064ee --- /dev/null +++ b/build-staging/it/docs/settings/appearance/ui-columns/index.html @@ -0,0 +1,24 @@ + + + + + +Colonne dell' IU (Interfaccia Utente) | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/behaviour/block-unknown-connections/index.html b/build-staging/it/docs/settings/behaviour/block-unknown-connections/index.html new file mode 100644 index 00000000..2f3ec44f --- /dev/null +++ b/build-staging/it/docs/settings/behaviour/block-unknown-connections/index.html @@ -0,0 +1,24 @@ + + + + + +Blocca connessioni sconosciute | The Cwtch Handbook + + + + + + + + + + + + +
+

Blocca connessioni sconosciute

By default, Cwtch interprets connections from unknown Cwtch addresses as Contact Requests. È possibile modificare questo comportamento tramite l'impostazione "Blocco connessioni sconosciute".

Se abilitata, Cwtch chiuderà automaticamente tutte le connessioni dagli indirizzi Cwtch che non hai aggiunto al tuo elenco delle conversazioni. This will prevent people who have your Cwtch address from contacting you unless you also add them.

Per abilitare:

  1. Vai su "Impostazioni"
  2. Attiva/Disattiva "Blocco contatti sconosciuti"
+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/behaviour/notification-content/index.html b/build-staging/it/docs/settings/behaviour/notification-content/index.html new file mode 100644 index 00000000..db2e5f7a --- /dev/null +++ b/build-staging/it/docs/settings/behaviour/notification-content/index.html @@ -0,0 +1,24 @@ + + + + + +Contenuto notifica | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/behaviour/notification-policy/index.html b/build-staging/it/docs/settings/behaviour/notification-policy/index.html new file mode 100644 index 00000000..1709733d --- /dev/null +++ b/build-staging/it/docs/settings/behaviour/notification-policy/index.html @@ -0,0 +1,24 @@ + + + + + +Policy di notifica | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/clickable-links/index.html b/build-staging/it/docs/settings/experiments/clickable-links/index.html new file mode 100644 index 00000000..ec32102d --- /dev/null +++ b/build-staging/it/docs/settings/experiments/clickable-links/index.html @@ -0,0 +1,24 @@ + + + + + +Esperimento Link cliccabili | The Cwtch Handbook + + + + + + + + + + + + +
+

Esperimento Link cliccabili

:::pericolo

Questa funzione, se abilitata, presenta un rischio di deanonimizzazione.

Non aprire URL provenienti da persone di cui non ti fidi. I link inviati tramite Cwtch vengono aperti tramite il browser predefinito del sistema. La maggior parte dei browser non può fornire anonimato.

:::

Abilita l'Esperimento Link cliccabili

I link cliccabili non sono abilitati come impostazione predefinita. Per consentire a Cwtch di aprire i link nei messaggi:

  1. Vai su "Impostazioni"
  2. Abilita "Esperimenti"
  3. Abilita l'Esperimento Link cliccabili

Rischi

Avere link cliccabili nei messaggi é molto utile, tuttavia ci sono rischi di cui devi essere consapevole se scegli di abilitare questa funzione.

Per evitare l'attivazione accidentale, dopo aver cliccato su un link in un messaggio, Cwtch aprirà prima un prompt aggiuntivo con due opzioni:

  1. Copia l'URL negli appunti
  2. Apri l'URL nel web browser predefinito

È possibile utilizzare il pulsante indietro sul dispositivo, o cliccare fuori da questo prompt per evitare di selezionare una delle due opzioni.

Cwtch non può proteggerti se apri link maligni.

L'URL viene aperto nel web browser predefinito che probabilmente, come minimo, esporrá il tuo indirizzo IP al server che ospita l'URL. Le pagine web possono anche utilizzare altre vulnerabilità del browser per raccogliere altre informazioni, o attaccare il tuo computer con ulteriori exploit.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/file-sharing/index.html b/build-staging/it/docs/settings/experiments/file-sharing/index.html new file mode 100644 index 00000000..880114b3 --- /dev/null +++ b/build-staging/it/docs/settings/experiments/file-sharing/index.html @@ -0,0 +1,24 @@ + + + + + +Condivisione file | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/group-experiment/index.html b/build-staging/it/docs/settings/experiments/group-experiment/index.html new file mode 100644 index 00000000..b4eca17c --- /dev/null +++ b/build-staging/it/docs/settings/experiments/group-experiment/index.html @@ -0,0 +1,24 @@ + + + + + +Groups Experiment | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/image-previews-and-profile-pictures/index.html b/build-staging/it/docs/settings/experiments/image-previews-and-profile-pictures/index.html new file mode 100644 index 00000000..8bd4465b --- /dev/null +++ b/build-staging/it/docs/settings/experiments/image-previews-and-profile-pictures/index.html @@ -0,0 +1,24 @@ + + + + + +Anteprime immagine e immagini del profilo | The Cwtch Handbook + + + + + + + + + + + + +
+

Anteprime immagine e immagini del profilo

caution

This experiment requires the File Sharing experiment enabled.

When enabled, Cwtch will download image files automatically, display image previews in the conversation window, and enable the Profile Pictures feature;

On Desktop, enabling this experiment will allow access to an additional setting "Download Folder` which can be changed to tell Cwtch where to (automatically) download pictures.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/message-formatting/index.html b/build-staging/it/docs/settings/experiments/message-formatting/index.html new file mode 100644 index 00000000..06d8ad25 --- /dev/null +++ b/build-staging/it/docs/settings/experiments/message-formatting/index.html @@ -0,0 +1,24 @@ + + + + + +Formattazione messaggio | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/qrcodes/index.html b/build-staging/it/docs/settings/experiments/qrcodes/index.html new file mode 100644 index 00000000..6f2a331b --- /dev/null +++ b/build-staging/it/docs/settings/experiments/qrcodes/index.html @@ -0,0 +1,24 @@ + + + + + +QR Codes | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/experiments/server-hosting/index.html b/build-staging/it/docs/settings/experiments/server-hosting/index.html new file mode 100644 index 00000000..843e7c3d --- /dev/null +++ b/build-staging/it/docs/settings/experiments/server-hosting/index.html @@ -0,0 +1,24 @@ + + + + + +Hosting di un server | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/docs/settings/introduction/index.html b/build-staging/it/docs/settings/introduction/index.html new file mode 100644 index 00000000..853076d9 --- /dev/null +++ b/build-staging/it/docs/settings/introduction/index.html @@ -0,0 +1,24 @@ + + + + + +Un'introduzione alle impostazioni dell'app di Cwtch | The Cwtch Handbook + + + + + + + + + + + + +
+

Un'introduzione alle impostazioni dell'app di Cwtch

Aspetto

These are settings which effect how Cwtch looks, including themes and localization.

Comportamento

These settings impact how Cwtch responds to certain events e.g. notifications for new messages, or requests from unknown public addresses.

Esperimenti

Ci sono molte funzionalitá in Cwtch che sono desiderabili ma la cui implementazione richiede metadati aggiuntivi, o un certo rischio, oltre il minimo che Cwtch richiede per le operazioni di base.

Di conseguenza, sotto Esperimenti troverete un certo numero di impostazioni opzionali che, quando abilitate, forniscono funzionalità aggiuntive come conversazioni di gruppo, condivisione di file o formattazione dei messaggi.

Rifletti attentamente sui nuovi rischi che potrebbero essere coinvolti quando abiliti queste funzionalitá, e chiediti se sei a tuo agio o meno nel momento in cui acconsenti a correre quei rischi. Per molti i vantaggi della condivisione di file, le anteprime dell'immagine e la chat di gruppo superano di gran lunga i potenziali danni - ma per tener conto e rispettare altre esigenze richiediamo a tutti di dare un consenso esplicito a queste funzionalità.

Puoi ritirare il tuo consensoin qualsiasi momento, tutte le funzionalità sono implementate localmente all'interno dell'app Cwtch.

+ + + + \ No newline at end of file diff --git a/build-staging/it/docs/tor/index.html b/build-staging/it/docs/tor/index.html new file mode 100644 index 00000000..d42bca59 --- /dev/null +++ b/build-staging/it/docs/tor/index.html @@ -0,0 +1,24 @@ + + + + + +Tor | The Cwtch Handbook + + + + + + + + + + + + +
+

Tor

Cwtch utilizza Tor per routing e connessioni. L'utilizzo dei servizi nascosti di Tor per ospitare profili e connessioni "effimere" generate al volo durante la creazione di una connessione fornisce forti garanzie di anonimato agli utenti di Cwtch.

Pannello Tor

Dato che stiamo aggiungendo un ulteriore livello di rete a Cwtch, forniamo un pannello per visualizzare lo stato della rete Tor e apportare modifiche. Per accedervi

  1. dal pannello Elenco profili, fare clic sull'icona Tor icona di tor
  2. Visualizza lo stato della rete tor
Stato Tor: Online
Versione Tor: 0.4.6.9

Resetta Tor

La rete Tor stessa può occasionalmente avere connessioni obsolete che non vengono rilevate immediatamente da essa o da Cwtch (cerchiamo continuamente di introdurre miglioramenti a riguardo). A volte un utente può trovare contatti o gruppi visualizzati offline che ritiene dovrebbero invece essere online. Se vuoi riavviare tutte le connessioni di rete in Cwtch, forniamo un meccanismo per riavviare tor dall'interno dell'app. Il pulsante reset riavvierà Tor dall'interno dell'applicazione Cwtch.

Abilita la cache del Consenso Tor

Come impostazione predefinita, avviamo un nuovo processo Tor ogni volta che l'app si avvia, e ció richiede il download di un qualche stato di rete Tor prima che possa iniziare. Questo processo non è istantaneo. Se vuoi velocizzare gli avvii futuri di Cwtch, puoi abilitare la memorizzazione nella cache del Consenso Tor. Se riscontri un problema di avvio in cui i dati sono obsoleti o danneggiati e Cwtch segnala che non è possibile avviare Tor, disabilita questa funzione e resetta tor nuovamente, e dovrebbe funzionare.

Configurazione avanzata di Tor

Offriamo anche la possibilità di fornire opzioni di configurazione Tor avanzate in questa sezione consentendoti di

  • specificare una porta SOCKS personalizzata per connettersi a un processo Tor esistente
  • specificare una porta Controllo personalizzata per connettersi a un processo Tor esistente
  • specificare ulteriori opzioni inserendo torrc opzioni personalizzate
+ + + + \ No newline at end of file diff --git a/build-staging/it/img/1.10.midnight.png b/build-staging/it/img/1.10.midnight.png new file mode 100644 index 00000000..e706a501 Binary files /dev/null and b/build-staging/it/img/1.10.midnight.png differ diff --git a/build-staging/it/img/1.png b/build-staging/it/img/1.png new file mode 100644 index 00000000..65538ea1 Binary files /dev/null and b/build-staging/it/img/1.png differ diff --git a/build-staging/it/img/2.png b/build-staging/it/img/2.png new file mode 100644 index 00000000..4de6eb1c Binary files /dev/null and b/build-staging/it/img/2.png differ diff --git a/build-staging/it/img/3.png b/build-staging/it/img/3.png new file mode 100644 index 00000000..7aac7c0a Binary files /dev/null and b/build-staging/it/img/3.png differ diff --git a/build-staging/it/img/4.png b/build-staging/it/img/4.png new file mode 100644 index 00000000..b404f458 Binary files /dev/null and b/build-staging/it/img/4.png differ diff --git a/build-staging/it/img/5_year_banner.png b/build-staging/it/img/5_year_banner.png new file mode 100644 index 00000000..ecc179a9 Binary files /dev/null and b/build-staging/it/img/5_year_banner.png differ diff --git a/build-staging/it/img/Anti-Spam_1.svg b/build-staging/it/img/Anti-Spam_1.svg new file mode 100644 index 00000000..3860cbfb --- /dev/null +++ b/build-staging/it/img/Anti-Spam_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Anti-Spam_2.svg b/build-staging/it/img/Anti-Spam_2.svg new file mode 100644 index 00000000..eb7a90b7 --- /dev/null +++ b/build-staging/it/img/Anti-Spam_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Anti-Spam_3.svg b/build-staging/it/img/Anti-Spam_3.svg new file mode 100644 index 00000000..df33b751 --- /dev/null +++ b/build-staging/it/img/Anti-Spam_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/BASE_0.png b/build-staging/it/img/BASE_0.png new file mode 100644 index 00000000..384cbefa Binary files /dev/null and b/build-staging/it/img/BASE_0.png differ diff --git a/build-staging/it/img/BASE_1.png b/build-staging/it/img/BASE_1.png new file mode 100644 index 00000000..0adb8240 Binary files /dev/null and b/build-staging/it/img/BASE_1.png differ diff --git a/build-staging/it/img/BASE_2.png b/build-staging/it/img/BASE_2.png new file mode 100644 index 00000000..d1cbb8e5 Binary files /dev/null and b/build-staging/it/img/BASE_2.png differ diff --git a/build-staging/it/img/BASE_3.png b/build-staging/it/img/BASE_3.png new file mode 100644 index 00000000..8dde1832 Binary files /dev/null and b/build-staging/it/img/BASE_3.png differ diff --git a/build-staging/it/img/BASE_5.png b/build-staging/it/img/BASE_5.png new file mode 100644 index 00000000..0330d03b Binary files /dev/null and b/build-staging/it/img/BASE_5.png differ diff --git a/build-staging/it/img/BASE_6.png b/build-staging/it/img/BASE_6.png new file mode 100644 index 00000000..3de5d899 Binary files /dev/null and b/build-staging/it/img/BASE_6.png differ diff --git a/build-staging/it/img/BASE_7.png b/build-staging/it/img/BASE_7.png new file mode 100644 index 00000000..00f730ad Binary files /dev/null and b/build-staging/it/img/BASE_7.png differ diff --git a/build-staging/it/img/BASE_8.png b/build-staging/it/img/BASE_8.png new file mode 100644 index 00000000..3881065e Binary files /dev/null and b/build-staging/it/img/BASE_8.png differ diff --git a/build-staging/it/img/Create_group.svg b/build-staging/it/img/Create_group.svg new file mode 100644 index 00000000..47001a56 --- /dev/null +++ b/build-staging/it/img/Create_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Eye_Closed.svg b/build-staging/it/img/Eye_Closed.svg new file mode 100644 index 00000000..01e6e0b0 --- /dev/null +++ b/build-staging/it/img/Eye_Closed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Eye_Open.svg b/build-staging/it/img/Eye_Open.svg new file mode 100644 index 00000000..3f29f7e1 --- /dev/null +++ b/build-staging/it/img/Eye_Open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/HB_svg_1.svg b/build-staging/it/img/HB_svg_1.svg new file mode 100644 index 00000000..4dd29705 --- /dev/null +++ b/build-staging/it/img/HB_svg_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/HB_svg_2.svg b/build-staging/it/img/HB_svg_2.svg new file mode 100644 index 00000000..4a4f36d3 --- /dev/null +++ b/build-staging/it/img/HB_svg_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/HB_svg_3.svg b/build-staging/it/img/HB_svg_3.svg new file mode 100644 index 00000000..f385b41a --- /dev/null +++ b/build-staging/it/img/HB_svg_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/HB_svg_4.svg b/build-staging/it/img/HB_svg_4.svg new file mode 100644 index 00000000..cf7ee829 --- /dev/null +++ b/build-staging/it/img/HB_svg_4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/OP_eye.svg b/build-staging/it/img/OP_eye.svg new file mode 100644 index 00000000..f12b17e5 --- /dev/null +++ b/build-staging/it/img/OP_eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Onion_Waiting.svg b/build-staging/it/img/Onion_Waiting.svg new file mode 100644 index 00000000..1f4f8005 --- /dev/null +++ b/build-staging/it/img/Onion_Waiting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Onion_off.svg b/build-staging/it/img/Onion_off.svg new file mode 100644 index 00000000..8075d469 --- /dev/null +++ b/build-staging/it/img/Onion_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Onion_on.svg b/build-staging/it/img/Onion_on.svg new file mode 100644 index 00000000..51771b97 --- /dev/null +++ b/build-staging/it/img/Onion_on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Screenshot_2022-06-17_13-42-19.png b/build-staging/it/img/Screenshot_2022-06-17_13-42-19.png new file mode 100644 index 00000000..f3bd84ac Binary files /dev/null and b/build-staging/it/img/Screenshot_2022-06-17_13-42-19.png differ diff --git a/build-staging/it/img/Tor_Booting_up.svg b/build-staging/it/img/Tor_Booting_up.svg new file mode 100644 index 00000000..2df93fe0 --- /dev/null +++ b/build-staging/it/img/Tor_Booting_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Tor_OFF.svg b/build-staging/it/img/Tor_OFF.svg new file mode 100644 index 00000000..fd2a714c --- /dev/null +++ b/build-staging/it/img/Tor_OFF.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/Tor_icon.png b/build-staging/it/img/Tor_icon.png new file mode 100644 index 00000000..0c871e9f Binary files /dev/null and b/build-staging/it/img/Tor_icon.png differ diff --git a/build-staging/it/img/View_replies.svg b/build-staging/it/img/View_replies.svg new file mode 100644 index 00000000..03cae418 --- /dev/null +++ b/build-staging/it/img/View_replies.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/aar-diff.png b/build-staging/it/img/aar-diff.png new file mode 100644 index 00000000..36a02e25 Binary files /dev/null and b/build-staging/it/img/aar-diff.png differ diff --git a/build-staging/it/img/account_blocked.svg b/build-staging/it/img/account_blocked.svg new file mode 100644 index 00000000..412efcff --- /dev/null +++ b/build-staging/it/img/account_blocked.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/build-staging/it/img/account_circle-24px.svg b/build-staging/it/img/account_circle-24px.svg new file mode 100644 index 00000000..013a30af --- /dev/null +++ b/build-staging/it/img/account_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/account_circle-24px_lines.svg b/build-staging/it/img/account_circle-24px_lines.svg new file mode 100644 index 00000000..9fec981a --- /dev/null +++ b/build-staging/it/img/account_circle-24px_lines.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/account_circle-24px_lines_thin - blocked.svg b/build-staging/it/img/account_circle-24px_lines_thin - blocked.svg new file mode 100644 index 00000000..5c3b9b7a --- /dev/null +++ b/build-staging/it/img/account_circle-24px_lines_thin - blocked.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/build-staging/it/img/account_circle-24px_lines_thin.svg b/build-staging/it/img/account_circle-24px_lines_thin.svg new file mode 100644 index 00000000..7ded72ff --- /dev/null +++ b/build-staging/it/img/account_circle-24px_lines_thin.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/build-staging/it/img/account_circle-24px_negative_space.svg b/build-staging/it/img/account_circle-24px_negative_space.svg new file mode 100644 index 00000000..c9c4f83c --- /dev/null +++ b/build-staging/it/img/account_circle-24px_negative_space.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/build-staging/it/img/account_circle-24px_user.svg b/build-staging/it/img/account_circle-24px_user.svg new file mode 100644 index 00000000..3eb8ffc7 --- /dev/null +++ b/build-staging/it/img/account_circle-24px_user.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/build-staging/it/img/add_circle-24px.svg b/build-staging/it/img/add_circle-24px.svg new file mode 100644 index 00000000..e8e583ad --- /dev/null +++ b/build-staging/it/img/add_circle-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/add_group.svg b/build-staging/it/img/add_group.svg new file mode 100644 index 00000000..c4a8658e --- /dev/null +++ b/build-staging/it/img/add_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/add_peer.svg b/build-staging/it/img/add_peer.svg new file mode 100644 index 00000000..0b15edbd --- /dev/null +++ b/build-staging/it/img/add_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/android.png b/build-staging/it/img/android.png new file mode 100644 index 00000000..afee7fce Binary files /dev/null and b/build-staging/it/img/android.png differ diff --git a/build-staging/it/img/android.svg b/build-staging/it/img/android.svg new file mode 100644 index 00000000..f743813f --- /dev/null +++ b/build-staging/it/img/android.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/build-staging/it/img/apple.svg b/build-staging/it/img/apple.svg new file mode 100644 index 00000000..a090c68e --- /dev/null +++ b/build-staging/it/img/apple.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/build-staging/it/img/attach_file-24px.svg b/build-staging/it/img/attach_file-24px.svg new file mode 100644 index 00000000..471fb991 --- /dev/null +++ b/build-staging/it/img/attach_file-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/attached-file-2.svg b/build-staging/it/img/attached-file-2.svg new file mode 100644 index 00000000..0f7b9eb3 --- /dev/null +++ b/build-staging/it/img/attached-file-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/attached-file-3.svg b/build-staging/it/img/attached-file-3.svg new file mode 100644 index 00000000..37e2f74a --- /dev/null +++ b/build-staging/it/img/attached-file-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/attached-file.svg b/build-staging/it/img/attached-file.svg new file mode 100644 index 00000000..28ea8263 --- /dev/null +++ b/build-staging/it/img/attached-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/block-24px.svg b/build-staging/it/img/block-24px.svg new file mode 100644 index 00000000..8636ff6a --- /dev/null +++ b/build-staging/it/img/block-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/block_peer.svg b/build-staging/it/img/block_peer.svg new file mode 100644 index 00000000..fb4a84e7 --- /dev/null +++ b/build-staging/it/img/block_peer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/block_unknown.svg b/build-staging/it/img/block_unknown.svg new file mode 100644 index 00000000..f5afc576 --- /dev/null +++ b/build-staging/it/img/block_unknown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/card_header.png b/build-staging/it/img/card_header.png new file mode 100644 index 00000000..aaa0368b Binary files /dev/null and b/build-staging/it/img/card_header.png differ diff --git a/build-staging/it/img/change_language.svg b/build-staging/it/img/change_language.svg new file mode 100644 index 00000000..d36e819b --- /dev/null +++ b/build-staging/it/img/change_language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/change_theme.svg b/build-staging/it/img/change_theme.svg new file mode 100644 index 00000000..95bf1fd4 --- /dev/null +++ b/build-staging/it/img/change_theme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/check-24px.svg b/build-staging/it/img/check-24px.svg new file mode 100644 index 00000000..c5c42b66 --- /dev/null +++ b/build-staging/it/img/check-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/chevron_left-24px.svg b/build-staging/it/img/chevron_left-24px.svg new file mode 100644 index 00000000..6f78ae79 --- /dev/null +++ b/build-staging/it/img/chevron_left-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/clear-24px.svg b/build-staging/it/img/clear-24px.svg new file mode 100644 index 00000000..08149461 --- /dev/null +++ b/build-staging/it/img/clear-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/clickable_links.png b/build-staging/it/img/clickable_links.png new file mode 100644 index 00000000..7875fe74 Binary files /dev/null and b/build-staging/it/img/clickable_links.png differ diff --git a/build-staging/it/img/clickable_links_experiment.png b/build-staging/it/img/clickable_links_experiment.png new file mode 100644 index 00000000..1d809218 Binary files /dev/null and b/build-staging/it/img/clickable_links_experiment.png differ diff --git a/build-staging/it/img/conversations/settings-full.png b/build-staging/it/img/conversations/settings-full.png new file mode 100644 index 00000000..1dd31bd4 Binary files /dev/null and b/build-staging/it/img/conversations/settings-full.png differ diff --git a/build-staging/it/img/conversations/settings.png b/build-staging/it/img/conversations/settings.png new file mode 100644 index 00000000..ed93099a Binary files /dev/null and b/build-staging/it/img/conversations/settings.png differ diff --git a/build-staging/it/img/cwtch phones.png b/build-staging/it/img/cwtch phones.png new file mode 100644 index 00000000..54396db9 Binary files /dev/null and b/build-staging/it/img/cwtch phones.png differ diff --git a/build-staging/it/img/cwtch_handbook_header.jpg b/build-staging/it/img/cwtch_handbook_header.jpg new file mode 100644 index 00000000..7b75a456 Binary files /dev/null and b/build-staging/it/img/cwtch_handbook_header.jpg differ diff --git a/build-staging/it/img/cwtch_knott.svg b/build-staging/it/img/cwtch_knott.svg new file mode 100644 index 00000000..7b16f58f --- /dev/null +++ b/build-staging/it/img/cwtch_knott.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/delete-24px.svg b/build-staging/it/img/delete-24px.svg new file mode 100644 index 00000000..8f6e9a27 --- /dev/null +++ b/build-staging/it/img/delete-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/dev9-host-disabled.png b/build-staging/it/img/dev9-host-disabled.png new file mode 100644 index 00000000..3869f4bc Binary files /dev/null and b/build-staging/it/img/dev9-host-disabled.png differ diff --git a/build-staging/it/img/devlog1.jpg b/build-staging/it/img/devlog1.jpg new file mode 100644 index 00000000..639ccabd Binary files /dev/null and b/build-staging/it/img/devlog1.jpg differ diff --git a/build-staging/it/img/devlog1.png b/build-staging/it/img/devlog1.png new file mode 100644 index 00000000..1133f073 Binary files /dev/null and b/build-staging/it/img/devlog1.png differ diff --git a/build-staging/it/img/devlog10.png b/build-staging/it/img/devlog10.png new file mode 100644 index 00000000..f8db0848 Binary files /dev/null and b/build-staging/it/img/devlog10.png differ diff --git a/build-staging/it/img/devlog10_small.png b/build-staging/it/img/devlog10_small.png new file mode 100644 index 00000000..d27ea94f Binary files /dev/null and b/build-staging/it/img/devlog10_small.png differ diff --git a/build-staging/it/img/devlog12.png b/build-staging/it/img/devlog12.png new file mode 100644 index 00000000..9932ffe6 Binary files /dev/null and b/build-staging/it/img/devlog12.png differ diff --git a/build-staging/it/img/devlog12_small.png b/build-staging/it/img/devlog12_small.png new file mode 100644 index 00000000..425cd4bb Binary files /dev/null and b/build-staging/it/img/devlog12_small.png differ diff --git a/build-staging/it/img/devlog13.png b/build-staging/it/img/devlog13.png new file mode 100644 index 00000000..8640aa3d Binary files /dev/null and b/build-staging/it/img/devlog13.png differ diff --git a/build-staging/it/img/devlog13_small.png b/build-staging/it/img/devlog13_small.png new file mode 100644 index 00000000..e6de7752 Binary files /dev/null and b/build-staging/it/img/devlog13_small.png differ diff --git a/build-staging/it/img/devlog1_small.jpg b/build-staging/it/img/devlog1_small.jpg new file mode 100644 index 00000000..a7ffb46a Binary files /dev/null and b/build-staging/it/img/devlog1_small.jpg differ diff --git a/build-staging/it/img/devlog2.png b/build-staging/it/img/devlog2.png new file mode 100644 index 00000000..0c84bfc4 Binary files /dev/null and b/build-staging/it/img/devlog2.png differ diff --git a/build-staging/it/img/devlog2_small.png b/build-staging/it/img/devlog2_small.png new file mode 100644 index 00000000..0eb53c1f Binary files /dev/null and b/build-staging/it/img/devlog2_small.png differ diff --git a/build-staging/it/img/devlog3.png b/build-staging/it/img/devlog3.png new file mode 100644 index 00000000..b1a2a9a3 Binary files /dev/null and b/build-staging/it/img/devlog3.png differ diff --git a/build-staging/it/img/devlog3_small.png b/build-staging/it/img/devlog3_small.png new file mode 100644 index 00000000..dc99bef2 Binary files /dev/null and b/build-staging/it/img/devlog3_small.png differ diff --git a/build-staging/it/img/devlog4.png b/build-staging/it/img/devlog4.png new file mode 100644 index 00000000..b8aaad4f Binary files /dev/null and b/build-staging/it/img/devlog4.png differ diff --git a/build-staging/it/img/devlog4_small.png b/build-staging/it/img/devlog4_small.png new file mode 100644 index 00000000..77354e45 Binary files /dev/null and b/build-staging/it/img/devlog4_small.png differ diff --git a/build-staging/it/img/devlog5.png b/build-staging/it/img/devlog5.png new file mode 100644 index 00000000..60981a38 Binary files /dev/null and b/build-staging/it/img/devlog5.png differ diff --git a/build-staging/it/img/devlog5_small.png b/build-staging/it/img/devlog5_small.png new file mode 100644 index 00000000..c2a4d835 Binary files /dev/null and b/build-staging/it/img/devlog5_small.png differ diff --git a/build-staging/it/img/devlog6.png b/build-staging/it/img/devlog6.png new file mode 100644 index 00000000..04490fb3 Binary files /dev/null and b/build-staging/it/img/devlog6.png differ diff --git a/build-staging/it/img/devlog6_small.png b/build-staging/it/img/devlog6_small.png new file mode 100644 index 00000000..384738b5 Binary files /dev/null and b/build-staging/it/img/devlog6_small.png differ diff --git a/build-staging/it/img/devlog7.png b/build-staging/it/img/devlog7.png new file mode 100644 index 00000000..9d8c0312 Binary files /dev/null and b/build-staging/it/img/devlog7.png differ diff --git a/build-staging/it/img/devlog7_small.png b/build-staging/it/img/devlog7_small.png new file mode 100644 index 00000000..a919c58d Binary files /dev/null and b/build-staging/it/img/devlog7_small.png differ diff --git a/build-staging/it/img/devlog8.png b/build-staging/it/img/devlog8.png new file mode 100644 index 00000000..e0be7cf8 Binary files /dev/null and b/build-staging/it/img/devlog8.png differ diff --git a/build-staging/it/img/devlog8_small.png b/build-staging/it/img/devlog8_small.png new file mode 100644 index 00000000..64d19eab Binary files /dev/null and b/build-staging/it/img/devlog8_small.png differ diff --git a/build-staging/it/img/devlog9.png b/build-staging/it/img/devlog9.png new file mode 100644 index 00000000..5610f57d Binary files /dev/null and b/build-staging/it/img/devlog9.png differ diff --git a/build-staging/it/img/devlog9_small.png b/build-staging/it/img/devlog9_small.png new file mode 100644 index 00000000..4a1e749f Binary files /dev/null and b/build-staging/it/img/devlog9_small.png differ diff --git a/build-staging/it/img/dl7-after.png b/build-staging/it/img/dl7-after.png new file mode 100644 index 00000000..7e747a61 Binary files /dev/null and b/build-staging/it/img/dl7-after.png differ diff --git a/build-staging/it/img/dl7-before.png b/build-staging/it/img/dl7-before.png new file mode 100644 index 00000000..d267f8fd Binary files /dev/null and b/build-staging/it/img/dl7-before.png differ diff --git a/build-staging/it/img/docusaurus.png b/build-staging/it/img/docusaurus.png new file mode 100644 index 00000000..f458149e Binary files /dev/null and b/build-staging/it/img/docusaurus.png differ diff --git a/build-staging/it/img/done-24px.svg b/build-staging/it/img/done-24px.svg new file mode 100644 index 00000000..2ee44187 --- /dev/null +++ b/build-staging/it/img/done-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/drag_indicator-24px.svg b/build-staging/it/img/drag_indicator-24px.svg new file mode 100644 index 00000000..0559cf1d --- /dev/null +++ b/build-staging/it/img/drag_indicator-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/edit-24px.svg b/build-staging/it/img/edit-24px.svg new file mode 100644 index 00000000..1a7d71c7 --- /dev/null +++ b/build-staging/it/img/edit-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/enable_experiments.svg b/build-staging/it/img/enable_experiments.svg new file mode 100644 index 00000000..c94642b6 --- /dev/null +++ b/build-staging/it/img/enable_experiments.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/enable_groups.svg b/build-staging/it/img/enable_groups.svg new file mode 100644 index 00000000..94480604 --- /dev/null +++ b/build-staging/it/img/enable_groups.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/favicon.png b/build-staging/it/img/favicon.png new file mode 100644 index 00000000..df58306b Binary files /dev/null and b/build-staging/it/img/favicon.png differ diff --git a/build-staging/it/img/favorite-24px.svg b/build-staging/it/img/favorite-24px.svg new file mode 100644 index 00000000..1c334308 --- /dev/null +++ b/build-staging/it/img/favorite-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/favorite_black_24dp_broken.svg b/build-staging/it/img/favorite_black_24dp_broken.svg new file mode 100644 index 00000000..cf82b44c --- /dev/null +++ b/build-staging/it/img/favorite_black_24dp_broken.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/build-staging/it/img/group_settings-24px.svg b/build-staging/it/img/group_settings-24px.svg new file mode 100644 index 00000000..bc8e0f60 --- /dev/null +++ b/build-staging/it/img/group_settings-24px.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/build-staging/it/img/handbook-banner.png b/build-staging/it/img/handbook-banner.png new file mode 100644 index 00000000..2ef4021b Binary files /dev/null and b/build-staging/it/img/handbook-banner.png differ diff --git a/build-staging/it/img/handbook-banner_small.jpg b/build-staging/it/img/handbook-banner_small.jpg new file mode 100644 index 00000000..be9c71e7 Binary files /dev/null and b/build-staging/it/img/handbook-banner_small.jpg differ diff --git a/build-staging/it/img/handbook-banner_small.png b/build-staging/it/img/handbook-banner_small.png new file mode 100644 index 00000000..c232310d Binary files /dev/null and b/build-staging/it/img/handbook-banner_small.png differ diff --git a/build-staging/it/img/info-24px.svg b/build-staging/it/img/info-24px.svg new file mode 100644 index 00000000..eb2424b5 --- /dev/null +++ b/build-staging/it/img/info-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/join_group.svg b/build-staging/it/img/join_group.svg new file mode 100644 index 00000000..d42dee0a --- /dev/null +++ b/build-staging/it/img/join_group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/knott.png b/build-staging/it/img/knott.png new file mode 100644 index 00000000..e50812f7 Binary files /dev/null and b/build-staging/it/img/knott.png differ diff --git a/build-staging/it/img/linux.svg b/build-staging/it/img/linux.svg new file mode 100644 index 00000000..f81c7944 --- /dev/null +++ b/build-staging/it/img/linux.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + diff --git a/build-staging/it/img/lock-24px.svg b/build-staging/it/img/lock-24px.svg new file mode 100644 index 00000000..472bd965 --- /dev/null +++ b/build-staging/it/img/lock-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/lock_open-24px.svg b/build-staging/it/img/lock_open-24px.svg new file mode 100644 index 00000000..b26d7274 --- /dev/null +++ b/build-staging/it/img/lock_open-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/lock_open-24px.webp b/build-staging/it/img/lock_open-24px.webp new file mode 100644 index 00000000..a913757a Binary files /dev/null and b/build-staging/it/img/lock_open-24px.webp differ diff --git a/build-staging/it/img/logo.svg b/build-staging/it/img/logo.svg new file mode 100644 index 00000000..9db6d0d0 --- /dev/null +++ b/build-staging/it/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/manage_files.svg b/build-staging/it/img/manage_files.svg new file mode 100644 index 00000000..13edcfe6 --- /dev/null +++ b/build-staging/it/img/manage_files.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/menu-24px.svg b/build-staging/it/img/menu-24px.svg new file mode 100644 index 00000000..8525078d --- /dev/null +++ b/build-staging/it/img/menu-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/mood-24px.svg b/build-staging/it/img/mood-24px.svg new file mode 100644 index 00000000..655863fa --- /dev/null +++ b/build-staging/it/img/mood-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/more_vert-24px.svg b/build-staging/it/img/more_vert-24px.svg new file mode 100644 index 00000000..49c84995 --- /dev/null +++ b/build-staging/it/img/more_vert-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/negative_heart_24px.svg b/build-staging/it/img/negative_heart_24px.svg new file mode 100644 index 00000000..05f00c83 --- /dev/null +++ b/build-staging/it/img/negative_heart_24px.svg @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/build-staging/it/img/peer_history.svg b/build-staging/it/img/peer_history.svg new file mode 100644 index 00000000..3c618c50 --- /dev/null +++ b/build-staging/it/img/peer_history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/peer_settings-24px.svg b/build-staging/it/img/peer_settings-24px.svg new file mode 100644 index 00000000..86d1c94f --- /dev/null +++ b/build-staging/it/img/peer_settings-24px.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/build-staging/it/img/person_add_alt_1-24px.svg b/build-staging/it/img/person_add_alt_1-24px.svg new file mode 100644 index 00000000..d9f3f0f2 --- /dev/null +++ b/build-staging/it/img/person_add_alt_1-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/picnic.png b/build-staging/it/img/picnic.png new file mode 100644 index 00000000..1eb4e29d Binary files /dev/null and b/build-staging/it/img/picnic.png differ diff --git a/build-staging/it/img/picnic1.12.png b/build-staging/it/img/picnic1.12.png new file mode 100644 index 00000000..fc981e41 Binary files /dev/null and b/build-staging/it/img/picnic1.12.png differ diff --git a/build-staging/it/img/profiles/attributes-contact.png b/build-staging/it/img/profiles/attributes-contact.png new file mode 100644 index 00000000..900ca4f3 Binary files /dev/null and b/build-staging/it/img/profiles/attributes-contact.png differ diff --git a/build-staging/it/img/profiles/attributes-empty.png b/build-staging/it/img/profiles/attributes-empty.png new file mode 100644 index 00000000..ae0ee6a9 Binary files /dev/null and b/build-staging/it/img/profiles/attributes-empty.png differ diff --git a/build-staging/it/img/profiles/attributes-set.png b/build-staging/it/img/profiles/attributes-set.png new file mode 100644 index 00000000..58b38ede Binary files /dev/null and b/build-staging/it/img/profiles/attributes-set.png differ diff --git a/build-staging/it/img/profiles/status-busy.png b/build-staging/it/img/profiles/status-busy.png new file mode 100644 index 00000000..841acada Binary files /dev/null and b/build-staging/it/img/profiles/status-busy.png differ diff --git a/build-staging/it/img/profiles/status-tooltip-busy-set.png b/build-staging/it/img/profiles/status-tooltip-busy-set.png new file mode 100644 index 00000000..7a05923d Binary files /dev/null and b/build-staging/it/img/profiles/status-tooltip-busy-set.png differ diff --git a/build-staging/it/img/profiles/status-tooltip-busy.png b/build-staging/it/img/profiles/status-tooltip-busy.png new file mode 100644 index 00000000..5df9bbc3 Binary files /dev/null and b/build-staging/it/img/profiles/status-tooltip-busy.png differ diff --git a/build-staging/it/img/profiles/status-tooltip.png b/build-staging/it/img/profiles/status-tooltip.png new file mode 100644 index 00000000..78fab618 Binary files /dev/null and b/build-staging/it/img/profiles/status-tooltip.png differ diff --git a/build-staging/it/img/sarah.jpg b/build-staging/it/img/sarah.jpg new file mode 100644 index 00000000..ef603626 Binary files /dev/null and b/build-staging/it/img/sarah.jpg differ diff --git a/build-staging/it/img/search-24px.svg b/build-staging/it/img/search-24px.svg new file mode 100644 index 00000000..45ea1457 --- /dev/null +++ b/build-staging/it/img/search-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/send-24px.svg b/build-staging/it/img/send-24px.svg new file mode 100644 index 00000000..ba848bae --- /dev/null +++ b/build-staging/it/img/send-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/signal_cellular_4_bar-24px.svg b/build-staging/it/img/signal_cellular_4_bar-24px.svg new file mode 100644 index 00000000..7fa91cd3 --- /dev/null +++ b/build-staging/it/img/signal_cellular_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/signal_cellular_connected_no_internet_4_bar-24px.svg b/build-staging/it/img/signal_cellular_connected_no_internet_4_bar-24px.svg new file mode 100644 index 00000000..76788f92 --- /dev/null +++ b/build-staging/it/img/signal_cellular_connected_no_internet_4_bar-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/signal_cellular_off-24px.svg b/build-staging/it/img/signal_cellular_off-24px.svg new file mode 100644 index 00000000..53a569e8 --- /dev/null +++ b/build-staging/it/img/signal_cellular_off-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/stickers-new.jpg b/build-staging/it/img/stickers-new.jpg new file mode 100644 index 00000000..2efbd940 Binary files /dev/null and b/build-staging/it/img/stickers-new.jpg differ diff --git a/build-staging/it/img/streamer_bunnymask.svg b/build-staging/it/img/streamer_bunnymask.svg new file mode 100644 index 00000000..345e3eae --- /dev/null +++ b/build-staging/it/img/streamer_bunnymask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/streamer_ghost.svg b/build-staging/it/img/streamer_ghost.svg new file mode 100644 index 00000000..c47a41e8 --- /dev/null +++ b/build-staging/it/img/streamer_ghost.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/sync-24px.svg b/build-staging/it/img/sync-24px.svg new file mode 100644 index 00000000..514301f8 --- /dev/null +++ b/build-staging/it/img/sync-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/sync_disabled-24px.svg b/build-staging/it/img/sync_disabled-24px.svg new file mode 100644 index 00000000..36a97cbf --- /dev/null +++ b/build-staging/it/img/sync_disabled-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/sync_problem-24px.svg b/build-staging/it/img/sync_problem-24px.svg new file mode 100644 index 00000000..9eb870b0 --- /dev/null +++ b/build-staging/it/img/sync_problem-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/syncing-01.svg b/build-staging/it/img/syncing-01.svg new file mode 100644 index 00000000..f9eb9791 --- /dev/null +++ b/build-staging/it/img/syncing-01.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/it/img/syncing-02.svg b/build-staging/it/img/syncing-02.svg new file mode 100644 index 00000000..4ae41d5c --- /dev/null +++ b/build-staging/it/img/syncing-02.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/it/img/syncing-03.svg b/build-staging/it/img/syncing-03.svg new file mode 100644 index 00000000..d4313757 --- /dev/null +++ b/build-staging/it/img/syncing-03.svg @@ -0,0 +1 @@ +syncing \ No newline at end of file diff --git a/build-staging/it/img/toggle_on-24px.svg b/build-staging/it/img/toggle_on-24px.svg new file mode 100644 index 00000000..5da416c4 --- /dev/null +++ b/build-staging/it/img/toggle_on-24px.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-staging/it/img/undraw_docusaurus_mountain.svg b/build-staging/it/img/undraw_docusaurus_mountain.svg new file mode 100644 index 00000000..af961c49 --- /dev/null +++ b/build-staging/it/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/it/img/undraw_docusaurus_react.svg b/build-staging/it/img/undraw_docusaurus_react.svg new file mode 100644 index 00000000..94b5cf08 --- /dev/null +++ b/build-staging/it/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/it/img/undraw_docusaurus_tree.svg b/build-staging/it/img/undraw_docusaurus_tree.svg new file mode 100644 index 00000000..d9161d33 --- /dev/null +++ b/build-staging/it/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-staging/it/img/windows.png b/build-staging/it/img/windows.png new file mode 100644 index 00000000..e3ffef93 Binary files /dev/null and b/build-staging/it/img/windows.png differ diff --git a/build-staging/it/img/windows.svg b/build-staging/it/img/windows.svg new file mode 100644 index 00000000..ad0ad190 --- /dev/null +++ b/build-staging/it/img/windows.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + diff --git a/build-staging/it/index.html b/build-staging/it/index.html new file mode 100644 index 00000000..69bc51da --- /dev/null +++ b/build-staging/it/index.html @@ -0,0 +1,24 @@ + + + + + +The Cwtch Handbook | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/katex/fonts/KaTeX_AMS-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_AMS-Regular.ttf new file mode 100644 index 00000000..c6f9a5e7 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_AMS-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_AMS-Regular.woff b/build-staging/it/katex/fonts/KaTeX_AMS-Regular.woff new file mode 100644 index 00000000..b804d7b3 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_AMS-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_AMS-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 00000000..0acaaff0 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_AMS-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.ttf b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.ttf new file mode 100644 index 00000000..9ff4a5e0 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.woff b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.woff new file mode 100644 index 00000000..9759710d Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.woff2 b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.woff2 new file mode 100644 index 00000000..f390922e Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Bold.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.ttf new file mode 100644 index 00000000..f522294f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.woff new file mode 100644 index 00000000..9bdd534f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 00000000..75344a1f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Caligraphic-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.ttf b/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.ttf new file mode 100644 index 00000000..4e98259c Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.woff b/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.woff new file mode 100644 index 00000000..e7730f66 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 00000000..395f28be Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Fraktur-Bold.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.ttf new file mode 100644 index 00000000..b8461b27 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.woff new file mode 100644 index 00000000..acab069f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.woff2 new file mode 100644 index 00000000..735f6948 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Fraktur-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Bold.ttf b/build-staging/it/katex/fonts/KaTeX_Main-Bold.ttf new file mode 100644 index 00000000..4060e627 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Bold.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Bold.woff b/build-staging/it/katex/fonts/KaTeX_Main-Bold.woff new file mode 100644 index 00000000..f38136ac Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Bold.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Bold.woff2 b/build-staging/it/katex/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 00000000..ab2ad21d Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Bold.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.ttf b/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.ttf new file mode 100644 index 00000000..dc007977 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.woff b/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.woff new file mode 100644 index 00000000..67807b0b Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.woff2 b/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.woff2 new file mode 100644 index 00000000..5931794d Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-BoldItalic.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Italic.ttf b/build-staging/it/katex/fonts/KaTeX_Main-Italic.ttf new file mode 100644 index 00000000..0e9b0f35 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Italic.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Italic.woff b/build-staging/it/katex/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 00000000..6f43b594 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Italic.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Italic.woff2 b/build-staging/it/katex/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 00000000..b50920e1 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Italic.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Main-Regular.ttf new file mode 100644 index 00000000..dd45e1ed Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Main-Regular.woff new file mode 100644 index 00000000..21f58129 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Main-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 00000000..eb24a7ba Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Main-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.ttf b/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.ttf new file mode 100644 index 00000000..728ce7a1 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.woff b/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 00000000..0ae390d7 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 00000000..29657023 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Math-BoldItalic.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Math-Italic.ttf b/build-staging/it/katex/fonts/KaTeX_Math-Italic.ttf new file mode 100644 index 00000000..70d559b4 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Math-Italic.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Math-Italic.woff b/build-staging/it/katex/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 00000000..eb5159d4 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Math-Italic.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Math-Italic.woff2 b/build-staging/it/katex/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 00000000..215c143f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Math-Italic.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.ttf b/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.ttf new file mode 100644 index 00000000..2f65a8a3 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.woff b/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.woff new file mode 100644 index 00000000..8d47c02d Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 00000000..cfaa3bda Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Bold.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.ttf b/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.ttf new file mode 100644 index 00000000..d5850df9 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.woff b/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 00000000..7e02df96 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.woff2 b/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 00000000..349c06dc Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Italic.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.ttf new file mode 100644 index 00000000..537279f6 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.woff b/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.woff new file mode 100644 index 00000000..31b84829 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 00000000..a90eea85 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_SansSerif-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Script-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Script-Regular.ttf new file mode 100644 index 00000000..fd679bf3 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Script-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Script-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 00000000..0e7da821 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Script-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Script-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 00000000..b3048fc1 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Script-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size1-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Size1-Regular.ttf new file mode 100644 index 00000000..871fd7d1 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size1-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size1-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Size1-Regular.woff new file mode 100644 index 00000000..7f292d91 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size1-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size1-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 00000000..c5a8462f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size1-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size2-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Size2-Regular.ttf new file mode 100644 index 00000000..7a212caf Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size2-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size2-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Size2-Regular.woff new file mode 100644 index 00000000..d241d9be Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size2-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size2-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 00000000..e1bccfe2 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size2-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size3-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Size3-Regular.ttf new file mode 100644 index 00000000..00bff349 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size3-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size3-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Size3-Regular.woff new file mode 100644 index 00000000..e6e9b658 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size3-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size3-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Size3-Regular.woff2 new file mode 100644 index 00000000..249a2866 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size3-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size4-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Size4-Regular.ttf new file mode 100644 index 00000000..74f08921 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size4-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size4-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 00000000..e1ec5457 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size4-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Size4-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 00000000..680c1308 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Size4-Regular.woff2 differ diff --git a/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.ttf b/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.ttf new file mode 100644 index 00000000..c83252c5 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.ttf differ diff --git a/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.woff b/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 00000000..2432419f Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.woff differ diff --git a/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.woff2 b/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 00000000..771f1af7 Binary files /dev/null and b/build-staging/it/katex/fonts/KaTeX_Typewriter-Regular.woff2 differ diff --git a/build-staging/it/katex/katex.min.css b/build-staging/it/katex/katex.min.css new file mode 100644 index 00000000..f7ebca1f --- /dev/null +++ b/build-staging/it/katex/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.13.24"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/build-staging/it/katex/katex.min.js b/build-staging/it/katex/katex.min.js new file mode 100644 index 00000000..2d04ed3b --- /dev/null +++ b/build-staging/it/katex/katex.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return _n}});var r=function e(t,r){this.position=void 0;var n,a="KaTeX parse error: "+t,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;n=i.start;var s=i.end;n===o.length?a+=" at end of input: ":a+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332");a+=(n>15?"\u2026"+o.slice(n-15,n):o.slice(0,n))+l+(s+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;var s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(o,(function(e){return i[e]}))},hyphenate:function(e){return e.replace(a,"-$1").toLowerCase()},getBaseElem:s,isCharacterBox:function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"}},h=function(){function e(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},this.displayMode=l.deflt(e.displayMode,!1),this.output=l.deflt(e.output,"htmlAndMathml"),this.leqno=l.deflt(e.leqno,!1),this.fleqn=l.deflt(e.fleqn,!1),this.throwOnError=l.deflt(e.throwOnError,!0),this.errorColor=l.deflt(e.errorColor,"#cc0000"),this.macros=e.macros||{},this.minRuleThickness=Math.max(0,l.deflt(e.minRuleThickness,0)),this.colorIsTextColor=l.deflt(e.colorIsTextColor,!1),this.strict=l.deflt(e.strict,"warn"),this.trust=l.deflt(e.trust,!1),this.maxSize=Math.max(0,l.deflt(e.maxSize,1/0)),this.maxExpand=Math.max(0,l.deflt(e.maxExpand,1e3)),this.globalGroup=l.deflt(e.globalGroup,!1)}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=l.protocolFromUrl(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),m=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return c[u[this.id]]},t.sub=function(){return c[p[this.id]]},t.fracNum=function(){return c[d[this.id]]},t.fracDen=function(){return c[f[this.id]]},t.cramp=function(){return c[g[this.id]]},t.text=function(){return c[v[this.id]]},t.isTight=function(){return this.size>=2},e}(),c=[new m(0,0,!1),new m(1,0,!0),new m(2,1,!1),new m(3,1,!0),new m(4,2,!1),new m(5,2,!0),new m(6,3,!1),new m(7,3,!0)],u=[4,5,4,5,6,7,6,7],p=[5,5,5,5,7,7,7,7],d=[2,3,4,5,6,7,6,7],f=[3,3,5,5,7,7,7,7],g=[1,1,3,3,5,5,7,7],v=[0,1,2,3,2,3,2,3],b={DISPLAY:c[0],TEXT:c[2],SCRIPT:c[4],SCRIPTSCRIPT:c[6]},y=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var x=[];function w(e){for(var t=0;t=x[t]&&e<=x[t+1])return!0;return!1}y.forEach((function(e){return e.blocks.forEach((function(e){return x.push.apply(x,e)}))}));var k=80,S={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},M=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=q[t]={cssEmPerMu:A.quad[t]/18};for(var n in A)A.hasOwnProperty(n)&&(r[n]=A[n][t])}return q[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();R.BASESIZE=6;var O=R,E={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},H={ex:!0,em:!0,mu:!0},L=function(e){return"string"!=typeof e&&(e=e.unit),e in E||e in H||"ex"===e},D=function(e,t){var r;if(e.unit in E)r=E[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},P=function(e){return+e.toFixed(4)+"em"},F=function(e){return e.filter((function(e){return e})).join(" ")},V=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},G=function(e){var t=document.createElement(e);for(var r in t.className=F(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},Y=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"span")},t.toMarkup=function(){return U.call(this,"span")},e}(),W=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"a")},t.toMarkup=function(){return U.call(this,"a")},e}(),X=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+"=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=_[this.text])}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=P(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=F(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=l.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');var a=l.escape(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),$=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r":""},e}(),K=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e="","\\gt",!0),ne(ae,oe,ge,"\u2208","\\in",!0),ne(ae,oe,ge,"\ue020","\\@not"),ne(ae,oe,ge,"\u2282","\\subset",!0),ne(ae,oe,ge,"\u2283","\\supset",!0),ne(ae,oe,ge,"\u2286","\\subseteq",!0),ne(ae,oe,ge,"\u2287","\\supseteq",!0),ne(ae,se,ge,"\u2288","\\nsubseteq",!0),ne(ae,se,ge,"\u2289","\\nsupseteq",!0),ne(ae,oe,ge,"\u22a8","\\models"),ne(ae,oe,ge,"\u2190","\\leftarrow",!0),ne(ae,oe,ge,"\u2264","\\le"),ne(ae,oe,ge,"\u2264","\\leq",!0),ne(ae,oe,ge,"<","\\lt",!0),ne(ae,oe,ge,"\u2192","\\rightarrow",!0),ne(ae,oe,ge,"\u2192","\\to"),ne(ae,se,ge,"\u2271","\\ngeq",!0),ne(ae,se,ge,"\u2270","\\nleq",!0),ne(ae,oe,ve,"\xa0","\\ "),ne(ae,oe,ve,"\xa0","\\space"),ne(ae,oe,ve,"\xa0","\\nobreakspace"),ne(ie,oe,ve,"\xa0","\\ "),ne(ie,oe,ve,"\xa0"," "),ne(ie,oe,ve,"\xa0","\\space"),ne(ie,oe,ve,"\xa0","\\nobreakspace"),ne(ae,oe,ve,null,"\\nobreak"),ne(ae,oe,ve,null,"\\allowbreak"),ne(ae,oe,fe,",",","),ne(ae,oe,fe,";",";"),ne(ae,se,he,"\u22bc","\\barwedge",!0),ne(ae,se,he,"\u22bb","\\veebar",!0),ne(ae,oe,he,"\u2299","\\odot",!0),ne(ae,oe,he,"\u2295","\\oplus",!0),ne(ae,oe,he,"\u2297","\\otimes",!0),ne(ae,oe,be,"\u2202","\\partial",!0),ne(ae,oe,he,"\u2298","\\oslash",!0),ne(ae,se,he,"\u229a","\\circledcirc",!0),ne(ae,se,he,"\u22a1","\\boxdot",!0),ne(ae,oe,he,"\u25b3","\\bigtriangleup"),ne(ae,oe,he,"\u25bd","\\bigtriangledown"),ne(ae,oe,he,"\u2020","\\dagger"),ne(ae,oe,he,"\u22c4","\\diamond"),ne(ae,oe,he,"\u22c6","\\star"),ne(ae,oe,he,"\u25c3","\\triangleleft"),ne(ae,oe,he,"\u25b9","\\triangleright"),ne(ae,oe,de,"{","\\{"),ne(ie,oe,be,"{","\\{"),ne(ie,oe,be,"{","\\textbraceleft"),ne(ae,oe,me,"}","\\}"),ne(ie,oe,be,"}","\\}"),ne(ie,oe,be,"}","\\textbraceright"),ne(ae,oe,de,"{","\\lbrace"),ne(ae,oe,me,"}","\\rbrace"),ne(ae,oe,de,"[","\\lbrack",!0),ne(ie,oe,be,"[","\\lbrack",!0),ne(ae,oe,me,"]","\\rbrack",!0),ne(ie,oe,be,"]","\\rbrack",!0),ne(ae,oe,de,"(","\\lparen",!0),ne(ae,oe,me,")","\\rparen",!0),ne(ie,oe,be,"<","\\textless",!0),ne(ie,oe,be,">","\\textgreater",!0),ne(ae,oe,de,"\u230a","\\lfloor",!0),ne(ae,oe,me,"\u230b","\\rfloor",!0),ne(ae,oe,de,"\u2308","\\lceil",!0),ne(ae,oe,me,"\u2309","\\rceil",!0),ne(ae,oe,be,"\\","\\backslash"),ne(ae,oe,be,"\u2223","|"),ne(ae,oe,be,"\u2223","\\vert"),ne(ie,oe,be,"|","\\textbar",!0),ne(ae,oe,be,"\u2225","\\|"),ne(ae,oe,be,"\u2225","\\Vert"),ne(ie,oe,be,"\u2225","\\textbardbl"),ne(ie,oe,be,"~","\\textasciitilde"),ne(ie,oe,be,"\\","\\textbackslash"),ne(ie,oe,be,"^","\\textasciicircum"),ne(ae,oe,ge,"\u2191","\\uparrow",!0),ne(ae,oe,ge,"\u21d1","\\Uparrow",!0),ne(ae,oe,ge,"\u2193","\\downarrow",!0),ne(ae,oe,ge,"\u21d3","\\Downarrow",!0),ne(ae,oe,ge,"\u2195","\\updownarrow",!0),ne(ae,oe,ge,"\u21d5","\\Updownarrow",!0),ne(ae,oe,pe,"\u2210","\\coprod"),ne(ae,oe,pe,"\u22c1","\\bigvee"),ne(ae,oe,pe,"\u22c0","\\bigwedge"),ne(ae,oe,pe,"\u2a04","\\biguplus"),ne(ae,oe,pe,"\u22c2","\\bigcap"),ne(ae,oe,pe,"\u22c3","\\bigcup"),ne(ae,oe,pe,"\u222b","\\int"),ne(ae,oe,pe,"\u222b","\\intop"),ne(ae,oe,pe,"\u222c","\\iint"),ne(ae,oe,pe,"\u222d","\\iiint"),ne(ae,oe,pe,"\u220f","\\prod"),ne(ae,oe,pe,"\u2211","\\sum"),ne(ae,oe,pe,"\u2a02","\\bigotimes"),ne(ae,oe,pe,"\u2a01","\\bigoplus"),ne(ae,oe,pe,"\u2a00","\\bigodot"),ne(ae,oe,pe,"\u222e","\\oint"),ne(ae,oe,pe,"\u222f","\\oiint"),ne(ae,oe,pe,"\u2230","\\oiiint"),ne(ae,oe,pe,"\u2a06","\\bigsqcup"),ne(ae,oe,pe,"\u222b","\\smallint"),ne(ie,oe,ce,"\u2026","\\textellipsis"),ne(ae,oe,ce,"\u2026","\\mathellipsis"),ne(ie,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u22ef","\\@cdots",!0),ne(ae,oe,ce,"\u22f1","\\ddots",!0),ne(ae,oe,be,"\u22ee","\\varvdots"),ne(ae,oe,le,"\u02ca","\\acute"),ne(ae,oe,le,"\u02cb","\\grave"),ne(ae,oe,le,"\xa8","\\ddot"),ne(ae,oe,le,"~","\\tilde"),ne(ae,oe,le,"\u02c9","\\bar"),ne(ae,oe,le,"\u02d8","\\breve"),ne(ae,oe,le,"\u02c7","\\check"),ne(ae,oe,le,"^","\\hat"),ne(ae,oe,le,"\u20d7","\\vec"),ne(ae,oe,le,"\u02d9","\\dot"),ne(ae,oe,le,"\u02da","\\mathring"),ne(ae,oe,ue,"\ue131","\\@imath"),ne(ae,oe,ue,"\ue237","\\@jmath"),ne(ae,oe,be,"\u0131","\u0131"),ne(ae,oe,be,"\u0237","\u0237"),ne(ie,oe,be,"\u0131","\\i",!0),ne(ie,oe,be,"\u0237","\\j",!0),ne(ie,oe,be,"\xdf","\\ss",!0),ne(ie,oe,be,"\xe6","\\ae",!0),ne(ie,oe,be,"\u0153","\\oe",!0),ne(ie,oe,be,"\xf8","\\o",!0),ne(ie,oe,be,"\xc6","\\AE",!0),ne(ie,oe,be,"\u0152","\\OE",!0),ne(ie,oe,be,"\xd8","\\O",!0),ne(ie,oe,le,"\u02ca","\\'"),ne(ie,oe,le,"\u02cb","\\`"),ne(ie,oe,le,"\u02c6","\\^"),ne(ie,oe,le,"\u02dc","\\~"),ne(ie,oe,le,"\u02c9","\\="),ne(ie,oe,le,"\u02d8","\\u"),ne(ie,oe,le,"\u02d9","\\."),ne(ie,oe,le,"\xb8","\\c"),ne(ie,oe,le,"\u02da","\\r"),ne(ie,oe,le,"\u02c7","\\v"),ne(ie,oe,le,"\xa8",'\\"'),ne(ie,oe,le,"\u02dd","\\H"),ne(ie,oe,le,"\u25ef","\\textcircled");var ye={"--":!0,"---":!0,"``":!0,"''":!0};ne(ie,oe,be,"\u2013","--",!0),ne(ie,oe,be,"\u2013","\\textendash"),ne(ie,oe,be,"\u2014","---",!0),ne(ie,oe,be,"\u2014","\\textemdash"),ne(ie,oe,be,"\u2018","`",!0),ne(ie,oe,be,"\u2018","\\textquoteleft"),ne(ie,oe,be,"\u2019","'",!0),ne(ie,oe,be,"\u2019","\\textquoteright"),ne(ie,oe,be,"\u201c","``",!0),ne(ie,oe,be,"\u201c","\\textquotedblleft"),ne(ie,oe,be,"\u201d","''",!0),ne(ie,oe,be,"\u201d","\\textquotedblright"),ne(ae,oe,be,"\xb0","\\degree",!0),ne(ie,oe,be,"\xb0","\\degree"),ne(ie,oe,be,"\xb0","\\textdegree",!0),ne(ae,oe,be,"\xa3","\\pounds"),ne(ae,oe,be,"\xa3","\\mathsterling",!0),ne(ie,oe,be,"\xa3","\\pounds"),ne(ie,oe,be,"\xa3","\\textsterling",!0),ne(ae,se,be,"\u2720","\\maltese"),ne(ie,se,be,"\u2720","\\maltese");for(var xe='0123456789/@."',we=0;wet&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Ue=function(e,t,r,n){var a=new Y(e,t,r,n);return Ge(a),a},Ye=function(e,t,r,n){return new Y(e,t,r,n)},We=function(e){var t=new M(e);return Ge(t),t},Xe=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},_e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},je={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},$e={fontMap:_e,makeSymbol:Fe,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Pe(e,"Main-Bold",t).metrics?Fe(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===re[t][e].font?Fe(e,"Main-Regular",t,r,n):Fe(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:Ue,makeSvgSpan:Ye,makeLineSpan:function(e,t,r){var n=Ue([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=P(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new W(e,t,r,n);return Ge(a),a},makeFragment:We,wrapFragment:function(e,t){return e instanceof M?Ue([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(xt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(xt(s,t)),r?((i=xt(pt(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var m=lt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=P(m.height+m.depth),m.depth&&(c.style.verticalAlign=P(-m.depth))}return m}function kt(e){return new M(e)}var St=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=F(this.classes));for(var r=0;r0&&(e+=' class ="'+l.escape(F(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),Mt=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return l.escape(this.toText())},t.toText=function(){return this.text},e}(),zt={MathNode:St,TextNode:Mt,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",P(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:kt},At=function(e,t,r){return!re[t][e]||!re[t][e].replace||55349===e.charCodeAt(0)||ye.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(e=re[t][e].replace),new zt.TextNode(e)},Tt=function(e){return 1===e.length?e[0]:new zt.MathNode("mrow",e)},Bt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l.contains(["\\imath","\\jmath"],a)?null:(re[n][a]&&re[n][a].replace&&(a=re[n][a].replace),B(a,$e.fontMap[r].fontName,n)?$e.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var n=Ct(e[0],t);return r&&n instanceof St&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},Nt=function(e,t,r){return Tt(qt(e,t,r))},Ct=function(e,t){if(!e)return new zt.MathNode("mrow");if(nt[e.type])return nt[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function It(e,t,r,n,a){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof St&&l.contains(["mrow","mtable"],o[0].type)?o[0]:new zt.MathNode("mrow",o);var s=new zt.MathNode("annotation",[new zt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new zt.MathNode("semantics",[i,s]),m=new zt.MathNode("math",[h]);m.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&m.setAttribute("display","block");var c=a?"katex":"katex-mathml";return $e.makeSpan([c],[m])}var Rt=function(e){return new O({style:e.displayMode?b.DISPLAY:b.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Ot=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=$e.makeSpan(r,[e])}return e},Et=function(e,t,r){var n,a=Rt(r);if("mathml"===r.output)return It(e,t,a,r.displayMode,!0);if("html"===r.output){var i=wt(e,a);n=$e.makeSpan(["katex"],[i])}else{var o=It(e,t,a,r.displayMode,!1),s=wt(e,a);n=$e.makeSpan(["katex"],[o,s])}return Ot(n,r)},Ht={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Lt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Dt=function(e,t,r,n,a){var i,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(i=$e.makeSpan(["stretchy",t],[],a),"fbox"===t){var s=a.color&&a.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new K({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new K({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new $(l,{width:"100%",height:P(o)});i=$e.makeSvgSpan([],[h],a)}return i.height=o,i.style.height=P(o),i},Pt=function(e){var t=new zt.MathNode("mo",[new zt.TextNode(Ht[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var r=function(){var r=4e5,n=e.label.substr(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var m=new Z(i),c=new $([m],{width:"100%",height:P(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:$e.makeSvgSpan([],[c],t),minWidth:0,height:o}}var u,p,d,f=[],g=Lt[n],v=g[0],b=g[1],y=g[2],x=y/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=P(a)),n};function Vt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Gt(e){var t=Ut(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Ut(e){return e&&("atom"===e.type||ee.hasOwnProperty(e.type))?e:null}var Yt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Vt(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof Y)return e;throw new Error("Expected span but got "+String(e)+".")}(yt(e,t)),e.base=n):r=(n=Vt(e,"accent")).base;var i=yt(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&l.isCharacterBox(r)){var s=l.getBaseElem(r);o=J(yt(s,t.havingCrampedStyle())).skew}var h,m="\\c"===n.label,c=m?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)h=Ft(n,t),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+P(2*o)+")",marginLeft:P(2*o)}:void 0}]},t);else{var u,p;"\\vec"===n.label?(u=$e.staticSvg("vec",t),p=$e.svgData.vec[1]):((u=J(u=$e.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,p=u.width,m&&(c+=u.depth)),h=$e.makeSpan(["accent-body"],[u]);var d="\\textcircled"===n.label;d&&(h.classes.push("accent-full"),c=i.height);var f=o;d||(f-=p/2),h.style.left=P(f),"\\textcircled"===n.label&&(h.style.top=".2em"),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}var g=$e.makeSpan(["mord","accent"],[h],t);return a?(a.children[0]=g,a.height=Math.max(g.height,a.height),a.classes[0]="mord",a):g},Wt=function(e,t){var r=e.isStretchy?Pt(e.label):new zt.MathNode("mo",[At(e.label,e.mode)]),n=new zt.MathNode("mover",[Ct(e.base,t),r]);return n.setAttribute("accent","true"),n},Xt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));at({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=ot(t[0]),n=!Xt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=yt(e.base,t),n=Ft(e,t),a="\\utilde"===e.label?.12:0,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Pt(e.label),n=new zt.MathNode("munder",[Ct(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var _t=function(e){var t=new zt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};at({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=$e.wrapFragment(yt(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=$e.wrapFragment(yt(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),$e.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Pt(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=_t(Ct(e.body,t));if(e.below){var i=_t(Ct(e.below,t));r=new zt.MathNode("munderover",[n,i,a])}else r=new zt.MathNode("mover",[n,a])}else if(e.below){var o=_t(Ct(e.below,t));r=new zt.MathNode("munder",[n,o])}else r=_t(),r=new zt.MathNode("mover",[n,r]);return r}});var jt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},$t=function(e){return"textord"===e.type&&"@"===e.text};function Zt(e,t,r){var n=jt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}at({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=$e.wrapFragment(yt(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=P(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new zt.MathNode("mrow",[Ct(e.label,t)]);return(r=new zt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new zt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),at({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=$e.wrapFragment(yt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new zt.MathNode("mrow",[Ct(e.fragment,t)])}}),at({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Vt(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var Kt=function(e,t){var r=pt(e.body,t.withColor(e.color),!1);return $e.makeFragment(r)},Jt=function(e,t){var r=qt(e.body,t.withColor(e.color)),n=new zt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};at({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Vt(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:st(a)}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Vt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=r[0],i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Vt(a,"size").value}},htmlBuilder:function(e,t){var r=$e.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=P(D(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new zt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",P(D(e.size,t)))),r}});var Qt={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},er=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},tr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};at({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(Qt[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=Qt[a.text]),Vt(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),at({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===Qt[r]),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return tr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return tr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var rr=function(e,t,r){var n=B(re.math[e]&&re.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},nr=function(e,t,r,n){var a=r.havingBaseStyle(t),i=$e.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},ar=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=P(a),e.height-=a,e.depth+=a},ir=function(e,t,r,n,a,i){var o=function(e,t,r,n){return $e.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=nr($e.makeSpan(["delimsizing","size"+t],[o],n),b.TEXT,n,i);return r&&ar(s,n,b.TEXT),s},or=function(e,t,r){var n;return n="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:$e.makeSpan(["delimsizinginner",n],[$e.makeSpan([],[$e.makeSymbol(e,t,r)])])}},sr=function(e,t,r){var n=z["Size4-Regular"][e.charCodeAt(0)]?z["Size4-Regular"][e.charCodeAt(0)][4]:z["Size1-Regular"][e.charCodeAt(0)][4],a=new Z("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new $([a],{width:P(n),height:P(t),style:"width:"+P(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=$e.makeSvgSpan([],[i],r);return o.height=t,o.style.height=P(t),o.style.width=P(n),{type:"elem",elem:o}},lr={type:"kern",size:-.008},hr=["|","\\lvert","\\rvert","\\vert"],mr=["\\|","\\lVert","\\rVert","\\Vert"],cr=function(e,t,r,n,a,i){var o,s,h,m;o=h=m=e,s=null;var c="Size1-Regular";"\\uparrow"===e?h=m="\u23d0":"\\Uparrow"===e?h=m="\u2016":"\\downarrow"===e?o=h="\u23d0":"\\Downarrow"===e?o=h="\u2016":"\\updownarrow"===e?(o="\\uparrow",h="\u23d0",m="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="\u2016",m="\\Downarrow"):l.contains(hr,e)?h="\u2223":l.contains(mr,e)?h="\u2225":"["===e||"\\lbrack"===e?(o="\u23a1",h="\u23a2",m="\u23a3",c="Size4-Regular"):"]"===e||"\\rbrack"===e?(o="\u23a4",h="\u23a5",m="\u23a6",c="Size4-Regular"):"\\lfloor"===e||"\u230a"===e?(h=o="\u23a2",m="\u23a3",c="Size4-Regular"):"\\lceil"===e||"\u2308"===e?(o="\u23a1",h=m="\u23a2",c="Size4-Regular"):"\\rfloor"===e||"\u230b"===e?(h=o="\u23a5",m="\u23a6",c="Size4-Regular"):"\\rceil"===e||"\u2309"===e?(o="\u23a4",h=m="\u23a5",c="Size4-Regular"):"("===e||"\\lparen"===e?(o="\u239b",h="\u239c",m="\u239d",c="Size4-Regular"):")"===e||"\\rparen"===e?(o="\u239e",h="\u239f",m="\u23a0",c="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",m="\u23a9",h="\u23aa",c="Size4-Regular");var u=rr(o,c,a),p=u.height+u.depth,d=rr(h,c,a),f=d.height+d.depth,g=rr(m,c,a),v=g.height+g.depth,y=0,x=1;if(null!==s){var w=rr(s,c,a);y=w.height+w.depth,x=2}var k=p+v+y,S=k+Math.max(0,Math.ceil((t-k)/(x*f)))*x*f,M=n.fontMetrics().axisHeight;r&&(M*=n.sizeMultiplier);var z=S/2-M,A=[];if(A.push(or(m,c,a)),A.push(lr),null===s){var T=S-p-v+.016;A.push(sr(h,T,n))}else{var B=(S-p-v-y)/2+.016;A.push(sr(h,B,n)),A.push(lr),A.push(or(s,c,a)),A.push(lr),A.push(sr(h,B,n))}A.push(lr),A.push(or(o,c,a));var q=n.havingBaseStyle(b.TEXT),N=$e.makeVList({positionType:"bottom",positionData:z,children:A},q);return nr($e.makeSpan(["delimsizing","mult"],[N],q),b.TEXT,n,i)},ur=.08,pr=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,k);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,k,r)}return n}(e,n,r),o=new Z(e,i),s=new $([o],{width:"400em",height:P(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return $e.makeSvgSpan(["hide-tail"],[s],a)},dr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],fr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],gr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],vr=[0,1.2,1.8,2.4,3],br=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],yr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"stack"}],xr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],wr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},kr=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},Sr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=l.contains(gr,e)?br:l.contains(dr,e)?xr:yr;var s=kr(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=$e.makeSymbol(e,"Main-Regular",a,n),s=nr(o,t,n,i);return r&&ar(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?ir(e,s.size,r,n,a,i):cr(e,t,r,n,a,i)},Mr={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=kr("\\surd",e*a.sizeMultiplier,xr,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=pr("sqrtMain",l=(1+s+ur)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(m=1080*vr[i.size],h=(vr[i.size]+s)/o,l=(vr[i.size]+s+ur)/o,(r=pr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+ur,h=e+s,m=Math.floor(1e3*e+s)+80,(r=pr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=P(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(dr,e)||l.contains(gr,e))return ir(e,t,!1,r,a,i);if(l.contains(fr,e))return cr(e,vr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:vr,customSizedDelim:Sr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Sr(e,h,!0,n,a,i)}},zr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Ar=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Tr(e,t){var r=Ut(e);if(r&&l.contains(Ar,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Br(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}at({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Tr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:zr[e.funcName].size,mclass:zr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?$e.makeSpan([e.mclass]):Mr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(At(e.delim,e.mode));var r=new zt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=P(Mr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),at({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Tr(t[0],e).text,color:r}}}),at({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Tr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Vt(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){Br(e);for(var r,n,a=pt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Ct(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};at({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=Vt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),at({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Cr={};function Ir(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!c)&&g.pop(),b.length0&&(x+=.25),m.push({pos:x,isDashed:e[t]})}for(w(o[0]),r=0;r0&&(M<(B+=y)&&(M=B),B=0),e.addJot&&(M+=f),z.height=S,z.depth=M,x+=S,z.pos=x,x+=M+B,h[r]=z,w(o[r+1])}var q,N,C=x/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],O=[];if(e.addEqnNum)for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=l.deflt(F.pregap,p))&&((q=$e.makeSpan(["arraycolsep"],[])).style.width=P(W),R.push(q));var X=[];for(r=0;r0){for(var Z=$e.makeLineSpan("hline",t,c),K=$e.makeLineSpan("hdashline",t,c),J=[{type:"elem",elem:h,shift:0}];m.length>0;){var Q=m.pop(),ee=Q.pos-C;Q.isDashed?J.push({type:"elem",elem:K,shift:ee}):J.push({type:"elem",elem:Z,shift:ee})}h=$e.makeVList({positionType:"individualShift",children:J},t)}if(e.addEqnNum){var te=$e.makeVList({positionType:"individualShift",children:O},t);return te=$e.makeSpan(["tag"],[te],t),$e.makeFragment([h,te])}return $e.makeSpan(["mord"],[h],t)},Dr={c:"center ",l:"left ",r:"right "},Pr=function(e,t){for(var r=[],n=new zt.MathNode("mtd",[],["mtr-glue"]),a=new zt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(c+="top ",g=1),"separator"===p[p.length-1].type&&(c+="bottom ",v-=1);for(var b=g;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o=Er(e.parser,{cols:a,addJot:!0,addEqnNum:"align"===e.envName||"alignat"===e.envName,emptySingleRow:!0,colSeparationType:i,maxNumCols:"split"===e.envName?2:void 0,leqno:e.parser.settings.leqno},"display"),s=0,l={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var h="",m=0;m0&&c&&(d=1),a[u]={type:"align",align:p,pregap:d,postgap:0}}return o.colSeparationType=c?"align":"alignat",o};Ir({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Er(e.parser,a,Hr(e.envName))},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Er(e.parser,a,Hr(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Er(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Hr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l.contains(["gather","gather*"],e.envName)&&Or(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",addEqnNum:"gather"===e.envName,emptySingleRow:!0,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Or(e);var t={addEqnNum:"equation"===e.envName,emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Or(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var f=!0,g=c+1;g=b.SCRIPT.id?r.text():b.DISPLAY:"text"===e&&r.size===b.DISPLAY.size?r=b.TEXT:"script"===e?r=b.SCRIPT:"scriptscript"===e&&(r=b.SCRIPTSCRIPT),r},Zr=function(e,t){var r,n=$r(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=yt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(u=t.fontMetrics().num2,p=c):(u=t.fontMetrics().num3,p=3*c),d=t.fontMetrics().denom2),h){var w=t.fontMetrics().axisHeight;u-o.depth-(w+.5*m)0&&(t="."===(t=e)?null:t),t};at({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=ot(t[0]),s="atom"===o.type&&"open"===o.family?Qr(o.text):null,l=ot(t[1]),h="atom"===l.type&&"close"===l.family?Qr(l.text):null,m=Vt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Vt(p.body[0],"textord");u=Jr[Number(d.text)]}}else p=Vt(p,"textord"),u=Jr[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:Zr,mathmlBuilder:Kr}),at({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Vt(t[0],"size").value,token:n}}}),at({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Vt(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Zr,mathmlBuilder:Kr});var en=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?yt(e.sup,t.havingStyle(a.sup()),t):yt(e.sub,t.havingStyle(a.sub()),t),n=Vt(e.base,"horizBrace")):n=Vt(e,"horizBrace");var i,o=yt(n.base,t.havingBaseStyle(b.DISPLAY)),s=Ft(n,t);if(n.isOver?(i=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=$e.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=$e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):$e.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return $e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};at({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:en,mathmlBuilder:function(e,t){var r=Pt(e.label);return new zt.MathNode(e.isOver?"mover":"munder",[Ct(e.base,t),r])}}),at({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Vt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:st(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=pt(e.body,t,!1);return $e.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=Nt(e.body,t);return r instanceof St||(r=new St("mrow",[r])),r.setAttribute("href",e.href),r}}),at({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Vt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=D(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=D(e.width,t));var i={height:P(r+n)};a>0&&(i.width=P(a)),n>0&&(i.verticalAlign=P(-n));var o=new X(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new zt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=D(e.height,t),a=0;if(e.totalheight.number>0&&(a=D(e.totalheight,t)-n,r.setAttribute("valign",P(-a))),r.setAttribute("height",P(n+a)),e.width.number>0){var i=D(e.width,t);r.setAttribute("width",P(i))}return r.setAttribute("src",e.src),r}}),at({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Vt(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return $e.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=D(e.dimension,t);return new zt.SpaceNode(r)}}),at({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=$e.makeSpan([],[yt(e.body,t)]),r=$e.makeSpan(["inner"],[r],t)):r=$e.makeSpan(["inner"],[yt(e.body,t)]);var n=$e.makeSpan(["fix"],[]),a=$e.makeSpan([e.alignment],[r,n],t),i=$e.makeSpan(["strut"]);return i.style.height=P(a.height+a.depth),a.depth&&(i.style.verticalAlign=P(-a.depth)),a.children.unshift(i),a=$e.makeSpan(["thinbox"],[a],t),$e.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mpadded",[Ct(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),at({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),at({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var rn=function(e,t){switch(t.style.size){case b.DISPLAY.size:return e.display;case b.TEXT.size:return e.text;case b.SCRIPT.size:return e.script;case b.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};at({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:st(t[0]),text:st(t[1]),script:st(t[2]),scriptscript:st(t[3])}},htmlBuilder:function(e,t){var r=rn(e,t),n=pt(r,t,!1);return $e.makeFragment(n)},mathmlBuilder:function(e,t){var r=rn(e,t);return Nt(r,t)}});var nn=function(e,t,r,n,a,i,o){e=$e.makeSpan([],[e]);var s,h,m,c=r&&l.isCharacterBox(r);if(t){var u=yt(t,n.havingStyle(a.sup()),n);h={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-u.depth)}}if(r){var p=yt(r,n.havingStyle(a.sub()),n);s={elem:p,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-p.height)}}if(h&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;m=$e.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!h)return e;var g=e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[m];if(s&&0!==i&&!c){var b=$e.makeSpan(["mspace"],[],n);b.style.marginRight=P(i),v.unshift(b)}return $e.makeSpan(["mop","op-limits"],v,n)},an=["\\smallint"],on=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Vt(e.base,"op"),i=!0):a=Vt(e,"op");var o,s=t.style,h=!1;if(s.size===b.DISPLAY.size&&a.symbol&&!l.contains(an,a.name)&&(h=!0),a.symbol){var m=h?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(c=a.name.substr(1),a.name="oiint"===c?"\\iint":"\\iiint"),o=$e.makeSymbol(a.name,m,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),c.length>0){var u=o.italic,p=$e.staticSvg(c+"Size"+(h?"2":"1"),t);o=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+c,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=pt(a.body,t,!0);1===d.length&&d[0]instanceof j?(o=d[0]).classes[0]="mop":o=$e.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=pt(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",P(a)):(s.setAttribute("height",P(a)),s.setAttribute("depth",P(-a))),s.setAttribute("voffset",P(a)),s}});var dn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];at({type:"sizing",names:dn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:dn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return pn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=qt(e.body,r),a=new zt.MathNode("mstyle",n);return a.setAttribute("mathsize",P(r.sizeMultiplier)),a}}),at({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Vt(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=P(m);var p=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(b.SCRIPTSCRIPT),f=yt(e.index,d,t),g=.6*(p.height-p.depth),v=$e.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),y=$e.makeSpan(["root"],[v]);return $e.makeSpan(["mord","sqrt"],[y,p],t)}return $e.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new zt.MathNode("mroot",[Ct(r,t),Ct(n,t)]):new zt.MathNode("msqrt",[Ct(r,t)])}});var fn={display:b.DISPLAY,text:b.TEXT,script:b.SCRIPT,scriptscript:b.SCRIPTSCRIPT};at({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r).withFont("");return pn(e.body,n,t)},mathmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r),a=qt(e.body,n),i=new zt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});var gn=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===b.DISPLAY.size||r.alwaysHandleSupSub)?on:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===b.DISPLAY.size||r.limits)?un:null:"accent"===r.type?l.isCharacterBox(r.base)?Yt:null:"horizBrace"===r.type&&!e.sub===r.isOver?en:null:null};it({type:"supsub",htmlBuilder:function(e,t){var r=gn(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,h=e.sub,m=yt(o,t),c=t.fontMetrics(),u=0,p=0,d=o&&l.isCharacterBox(o);if(s){var f=t.havingStyle(t.style.sup());n=yt(s,f,t),d||(u=m.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(h){var g=t.havingStyle(t.style.sub());a=yt(h,g,t),d||(p=m.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===b.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,y=t.sizeMultiplier,x=P(.5/c.ptPerEm/y),w=null;if(a){var k=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(m instanceof j||k)&&(w=P(-m.italic))}if(n&&a){u=Math.max(u,i,n.depth+.25*c.xHeight),p=Math.max(p,c.sub2);var S=4*c.defaultRuleThickness;if(u-n.depth-(a.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:a,shift:p,marginRight:x,marginLeft:w},{type:"elem",elem:n,shift:-u,marginRight:x}];v=$e.makeVList({positionType:"individualShift",children:z},t)}else if(a){p=Math.max(p,c.sub1,a.height-.8*c.xHeight);var A=[{type:"elem",elem:a,marginLeft:w,marginRight:x}];v=$e.makeVList({positionType:"shift",positionData:p,children:A},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,n.depth+.25*c.xHeight),v=$e.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:n,marginRight:x}]},t)}var T=vt(m,"right")||"mord";return $e.makeSpan([T],[m,$e.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Ct(e.base,t)];if(e.sub&&i.push(Ct(e.sub,t)),e.sup&&i.push(Ct(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===b.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===b.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===b.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===b.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===b.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===b.DISPLAY)?"mover":"msup"}return new zt.MathNode(a,i)}}),it({type:"atom",htmlBuilder:function(e,t){return $e.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[At(e.text,e.mode)]);if("bin"===e.family){var n=Bt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var vn={mi:"italic",mn:"normal",mtext:"normal"};it({type:"mathord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new zt.MathNode("mi",[At(e.text,e.mode,t)]),n=Bt(e,t)||"italic";return n!==vn[r.type]&&r.setAttribute("mathvariant",n),r}}),it({type:"textord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=At(e.text,e.mode,t),a=Bt(e,t)||"normal";return r="text"===e.mode?new zt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new zt.MathNode("mn",[n]):"\\prime"===e.text?new zt.MathNode("mo",[n]):new zt.MathNode("mi",[n]),a!==vn[r.type]&&r.setAttribute("mathvariant",a),r}});var bn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},yn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};it({type:"spacing",htmlBuilder:function(e,t){if(yn.hasOwnProperty(e.text)){var r=yn[e.text].className||"";if("text"===e.mode){var a=$e.makeOrd(e,t,"textord");return a.classes.push(r),a}return $e.makeSpan(["mspace",r],[$e.mathsym(e.text,e.mode,t)],t)}if(bn.hasOwnProperty(e.text))return $e.makeSpan(["mspace",bn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!yn.hasOwnProperty(e.text)){if(bn.hasOwnProperty(e.text))return new zt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new zt.MathNode("mtext",[new zt.TextNode("\xa0")])}});var xn=function(){var e=new zt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};it({type:"tag",mathmlBuilder:function(e,t){var r=new zt.MathNode("mtable",[new zt.MathNode("mtr",[xn(),new zt.MathNode("mtd",[Nt(e.body,t)]),xn(),new zt.MathNode("mtd",[Nt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},kn={"\\textbf":"textbf","\\textmd":"textmd"},Sn={"\\textit":"textit","\\textup":"textup"},Mn=function(e,t){var r=e.font;return r?wn[r]?t.withTextFontFamily(wn[r]):kn[r]?t.withTextFontWeight(kn[r]):t.withTextFontShape(Sn[r]):t};at({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:st(a),font:n}},htmlBuilder:function(e,t){var r=Mn(e,t),n=pt(e.body,r,!0);return $e.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Mn(e,t);return Nt(e.body,r)}}),at({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=$e.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[new zt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var n=new zt.MathNode("munder",[Ct(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),at({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return $e.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new zt.MathNode("mpadded",[Ct(e.body,t)],["vcenter"])}}),at({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=zn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}this.current[e]=t},e}(),In=mn;cn("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),cn("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),cn("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),cn("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),cn("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),cn("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),cn("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Rn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};cn("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Rn[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=Rn[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};cn("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in En?t=En[r]:("\\not"===r.substr(0,4)||r in re.math&&l.contains(["bin","rel"],re.math[r].group))&&(t="\\dotsb"),t}));var Hn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};cn("\\dotso",(function(e){return e.future().text in Hn?"\\ldots\\,":"\\ldots"})),cn("\\dotsc",(function(e){var t=e.future().text;return t in Hn&&","!==t?"\\ldots\\,":"\\ldots"})),cn("\\cdots",(function(e){return e.future().text in Hn?"\\@cdots\\,":"\\@cdots"})),cn("\\dotsb","\\cdots"),cn("\\dotsm","\\cdots"),cn("\\dotsi","\\!\\cdots"),cn("\\dotsx","\\ldots\\,"),cn("\\DOTSI","\\relax"),cn("\\DOTSB","\\relax"),cn("\\DOTSX","\\relax"),cn("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),cn("\\,","\\tmspace+{3mu}{.1667em}"),cn("\\thinspace","\\,"),cn("\\>","\\mskip{4mu}"),cn("\\:","\\tmspace+{4mu}{.2222em}"),cn("\\medspace","\\:"),cn("\\;","\\tmspace+{5mu}{.2777em}"),cn("\\thickspace","\\;"),cn("\\!","\\tmspace-{3mu}{.1667em}"),cn("\\negthinspace","\\!"),cn("\\negmedspace","\\tmspace-{4mu}{.2222em}"),cn("\\negthickspace","\\tmspace-{5mu}{.277em}"),cn("\\enspace","\\kern.5em "),cn("\\enskip","\\hskip.5em\\relax"),cn("\\quad","\\hskip1em\\relax"),cn("\\qquad","\\hskip2em\\relax"),cn("\\tag","\\@ifstar\\tag@literal\\tag@paren"),cn("\\tag@paren","\\tag@literal{({#1})}"),cn("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),cn("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),cn("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),cn("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),cn("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),cn("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),cn("\\newline","\\\\\\relax"),cn("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Ln=P(z["Main-Regular"]["T".charCodeAt(0)][1]-.7*z["Main-Regular"]["A".charCodeAt(0)][1]);cn("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),cn("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),cn("\\hspace","\\@ifstar\\@hspacer\\@hspace"),cn("\\@hspace","\\hskip #1\\relax"),cn("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),cn("\\ordinarycolon",":"),cn("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),cn("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),cn("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),cn("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),cn("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),cn("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),cn("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),cn("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),cn("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),cn("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),cn("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),cn("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),cn("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),cn("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),cn("\u2237","\\dblcolon"),cn("\u2239","\\eqcolon"),cn("\u2254","\\coloneqq"),cn("\u2255","\\eqqcolon"),cn("\u2a74","\\Coloneqq"),cn("\\ratio","\\vcentcolon"),cn("\\coloncolon","\\dblcolon"),cn("\\colonequals","\\coloneqq"),cn("\\coloncolonequals","\\Coloneqq"),cn("\\equalscolon","\\eqqcolon"),cn("\\equalscoloncolon","\\Eqqcolon"),cn("\\colonminus","\\coloneq"),cn("\\coloncolonminus","\\Coloneq"),cn("\\minuscolon","\\eqcolon"),cn("\\minuscoloncolon","\\Eqcolon"),cn("\\coloncolonapprox","\\Colonapprox"),cn("\\coloncolonsim","\\Colonsim"),cn("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),cn("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),cn("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),cn("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),cn("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),cn("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),cn("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),cn("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),cn("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),cn("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),cn("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),cn("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),cn("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),cn("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),cn("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),cn("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),cn("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),cn("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),cn("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),cn("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),cn("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),cn("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),cn("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),cn("\\imath","\\html@mathml{\\@imath}{\u0131}"),cn("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),cn("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),cn("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),cn("\u27e6","\\llbracket"),cn("\u27e7","\\rrbracket"),cn("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),cn("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),cn("\u2983","\\lBrace"),cn("\u2984","\\rBrace"),cn("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),cn("\u29b5","\\minuso"),cn("\\darr","\\downarrow"),cn("\\dArr","\\Downarrow"),cn("\\Darr","\\Downarrow"),cn("\\lang","\\langle"),cn("\\rang","\\rangle"),cn("\\uarr","\\uparrow"),cn("\\uArr","\\Uparrow"),cn("\\Uarr","\\Uparrow"),cn("\\N","\\mathbb{N}"),cn("\\R","\\mathbb{R}"),cn("\\Z","\\mathbb{Z}"),cn("\\alef","\\aleph"),cn("\\alefsym","\\aleph"),cn("\\Alpha","\\mathrm{A}"),cn("\\Beta","\\mathrm{B}"),cn("\\bull","\\bullet"),cn("\\Chi","\\mathrm{X}"),cn("\\clubs","\\clubsuit"),cn("\\cnums","\\mathbb{C}"),cn("\\Complex","\\mathbb{C}"),cn("\\Dagger","\\ddagger"),cn("\\diamonds","\\diamondsuit"),cn("\\empty","\\emptyset"),cn("\\Epsilon","\\mathrm{E}"),cn("\\Eta","\\mathrm{H}"),cn("\\exist","\\exists"),cn("\\harr","\\leftrightarrow"),cn("\\hArr","\\Leftrightarrow"),cn("\\Harr","\\Leftrightarrow"),cn("\\hearts","\\heartsuit"),cn("\\image","\\Im"),cn("\\infin","\\infty"),cn("\\Iota","\\mathrm{I}"),cn("\\isin","\\in"),cn("\\Kappa","\\mathrm{K}"),cn("\\larr","\\leftarrow"),cn("\\lArr","\\Leftarrow"),cn("\\Larr","\\Leftarrow"),cn("\\lrarr","\\leftrightarrow"),cn("\\lrArr","\\Leftrightarrow"),cn("\\Lrarr","\\Leftrightarrow"),cn("\\Mu","\\mathrm{M}"),cn("\\natnums","\\mathbb{N}"),cn("\\Nu","\\mathrm{N}"),cn("\\Omicron","\\mathrm{O}"),cn("\\plusmn","\\pm"),cn("\\rarr","\\rightarrow"),cn("\\rArr","\\Rightarrow"),cn("\\Rarr","\\Rightarrow"),cn("\\real","\\Re"),cn("\\reals","\\mathbb{R}"),cn("\\Reals","\\mathbb{R}"),cn("\\Rho","\\mathrm{P}"),cn("\\sdot","\\cdot"),cn("\\sect","\\S"),cn("\\spades","\\spadesuit"),cn("\\sub","\\subset"),cn("\\sube","\\subseteq"),cn("\\supe","\\supseteq"),cn("\\Tau","\\mathrm{T}"),cn("\\thetasym","\\vartheta"),cn("\\weierp","\\wp"),cn("\\Zeta","\\mathrm{Z}"),cn("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),cn("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),cn("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),cn("\\bra","\\mathinner{\\langle{#1}|}"),cn("\\ket","\\mathinner{|{#1}\\rangle}"),cn("\\braket","\\mathinner{\\langle{#1}\\rangle}"),cn("\\Bra","\\left\\langle#1\\right|"),cn("\\Ket","\\left|#1\\right\\rangle"),cn("\\angln","{\\angl n}"),cn("\\blue","\\textcolor{##6495ed}{#1}"),cn("\\orange","\\textcolor{##ffa500}{#1}"),cn("\\pink","\\textcolor{##ff00af}{#1}"),cn("\\red","\\textcolor{##df0030}{#1}"),cn("\\green","\\textcolor{##28ae7b}{#1}"),cn("\\gray","\\textcolor{gray}{#1}"),cn("\\purple","\\textcolor{##9d38bd}{#1}"),cn("\\blueA","\\textcolor{##ccfaff}{#1}"),cn("\\blueB","\\textcolor{##80f6ff}{#1}"),cn("\\blueC","\\textcolor{##63d9ea}{#1}"),cn("\\blueD","\\textcolor{##11accd}{#1}"),cn("\\blueE","\\textcolor{##0c7f99}{#1}"),cn("\\tealA","\\textcolor{##94fff5}{#1}"),cn("\\tealB","\\textcolor{##26edd5}{#1}"),cn("\\tealC","\\textcolor{##01d1c1}{#1}"),cn("\\tealD","\\textcolor{##01a995}{#1}"),cn("\\tealE","\\textcolor{##208170}{#1}"),cn("\\greenA","\\textcolor{##b6ffb0}{#1}"),cn("\\greenB","\\textcolor{##8af281}{#1}"),cn("\\greenC","\\textcolor{##74cf70}{#1}"),cn("\\greenD","\\textcolor{##1fab54}{#1}"),cn("\\greenE","\\textcolor{##0d923f}{#1}"),cn("\\goldA","\\textcolor{##ffd0a9}{#1}"),cn("\\goldB","\\textcolor{##ffbb71}{#1}"),cn("\\goldC","\\textcolor{##ff9c39}{#1}"),cn("\\goldD","\\textcolor{##e07d10}{#1}"),cn("\\goldE","\\textcolor{##a75a05}{#1}"),cn("\\redA","\\textcolor{##fca9a9}{#1}"),cn("\\redB","\\textcolor{##ff8482}{#1}"),cn("\\redC","\\textcolor{##f9685d}{#1}"),cn("\\redD","\\textcolor{##e84d39}{#1}"),cn("\\redE","\\textcolor{##bc2612}{#1}"),cn("\\maroonA","\\textcolor{##ffbde0}{#1}"),cn("\\maroonB","\\textcolor{##ff92c6}{#1}"),cn("\\maroonC","\\textcolor{##ed5fa6}{#1}"),cn("\\maroonD","\\textcolor{##ca337c}{#1}"),cn("\\maroonE","\\textcolor{##9e034e}{#1}"),cn("\\purpleA","\\textcolor{##ddd7ff}{#1}"),cn("\\purpleB","\\textcolor{##c6b9fc}{#1}"),cn("\\purpleC","\\textcolor{##aa87ff}{#1}"),cn("\\purpleD","\\textcolor{##7854ab}{#1}"),cn("\\purpleE","\\textcolor{##543b78}{#1}"),cn("\\mintA","\\textcolor{##f5f9e8}{#1}"),cn("\\mintB","\\textcolor{##edf2df}{#1}"),cn("\\mintC","\\textcolor{##e0e5cc}{#1}"),cn("\\grayA","\\textcolor{##f6f7f7}{#1}"),cn("\\grayB","\\textcolor{##f0f1f2}{#1}"),cn("\\grayC","\\textcolor{##e3e5e6}{#1}"),cn("\\grayD","\\textcolor{##d6d8da}{#1}"),cn("\\grayE","\\textcolor{##babec2}{#1}"),cn("\\grayF","\\textcolor{##888d93}{#1}"),cn("\\grayG","\\textcolor{##626569}{#1}"),cn("\\grayH","\\textcolor{##3b3e40}{#1}"),cn("\\grayI","\\textcolor{##21242c}{#1}"),cn("\\kaBlue","\\textcolor{##314453}{#1}"),cn("\\kaGreen","\\textcolor{##71B307}{#1}");var Dn={"\\relax":!0,"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Pn=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Cn(In,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new Nn(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Bn("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof Bn){if("\\relax"!==e.text&&!e.treatAsRelax)return this.stack.pop();this.stack.pop()}}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Bn(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof Bn&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new Nn(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||An.hasOwnProperty(e)||re.math.hasOwnProperty(e)||re.text.hasOwnProperty(e)||Dn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:An.hasOwnProperty(e)&&!An[e].primitive},e}(),Fn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Vn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Gn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Pn(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&An[a.text]&&An[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=re[this.mode][t].group,h=Tn.range(e);if(Q.hasOwnProperty(l)){var m=l;s={type:"atom",mode:this.mode,family:m,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(w(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Tn.range(e),text:t}}if(this.consume(),o)for(var c=0;c + + + + +Connectivity & Tor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/security/category/cwtch-components/index.html b/build-staging/it/security/category/cwtch-components/index.html new file mode 100644 index 00000000..dcdb7fd5 --- /dev/null +++ b/build-staging/it/security/category/cwtch-components/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Components | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/security/category/cwtch-ui/index.html b/build-staging/it/security/category/cwtch-ui/index.html new file mode 100644 index 00000000..8326cff9 --- /dev/null +++ b/build-staging/it/security/category/cwtch-ui/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI | The Cwtch Handbook + + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/build-staging/it/security/category/cwtch/index.html b/build-staging/it/security/category/cwtch/index.html new file mode 100644 index 00000000..8d143e9a --- /dev/null +++ b/build-staging/it/security/category/cwtch/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/security/category/tapir/index.html b/build-staging/it/security/category/tapir/index.html new file mode 100644 index 00000000..2901d4eb --- /dev/null +++ b/build-staging/it/security/category/tapir/index.html @@ -0,0 +1,24 @@ + + + + + +Tapir | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/it/security/components/connectivity/intro/index.html b/build-staging/it/security/components/connectivity/intro/index.html new file mode 100644 index 00000000..4c2fe2d9 --- /dev/null +++ b/build-staging/it/security/components/connectivity/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Connectivity | The Cwtch Handbook + + + + + + + + + + + + +
+

Connectivity

Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.

We provide the openprivacy/connectivity package for managing the Tor daemon and setting up and tearing down onion services through Tor.

Known Risks

Private Key Exposure to the Tor Process

Status: Partially Mitigated (Requires Physical Access or Privilege Escalation to exploit)

We must pass the private key of any onion service we wish to set up to the connectivity library, through the Listen interface (and thus to the Tor process). This is one of the most critical areas that is outside of our control. Any binding to a rouge tor process or binary will result in compromise of the Onion private key.

Mitigations

Connectivity attempt to bind to the system-provided Tor process as the default, only when it has been provided with an authentication token.

Otherwise connectivity always attempts to deploy its own Tor process using a known good binary packaged with the system (outside of the scope of the connectivity package)

In the long term we hope an integrated library will become available and allow direct management through an in-process interface to prevent the private key from leaving the process boundary (or other alternative paths that allow us to maintain full control over the private key in-memory.)

Tor Process Management

Status: Partially Mitigated (Requires Physical Access or Privilege Escalation to exploit)

Many issues can arise from the management of a separate process, including the need to restart, exit and otherwise ensure appropriate management.

The ACN interface provides Restart, Close and GetBootstrapStatus interfaces to allow applications to manage the underlying Tor process. In addition the SetStatusCallback method can be used to allow an application to be notified when the status of the Tor process changes.

However, if sufficiently-privileged users wish they can interfere with this mechanism, and as such the Tor process is a more brittle component interaction than others.

Testing Status

Current connectivity has limited unit testing capabilities and none of these are run during pull requests or merges. There is no integration testing.

It is worth noting that connectivity is used by both Tapir and Cwtch in their integration tests (and so despite the lack of package level testing, it is exposed to system-wide test conditions)

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/cwtch/groups/index.html b/build-staging/it/security/components/cwtch/groups/index.html new file mode 100644 index 00000000..390e13c9 --- /dev/null +++ b/build-staging/it/security/components/cwtch/groups/index.html @@ -0,0 +1,24 @@ + + + + + +Groups | The Cwtch Handbook + + + + + + + + + + + + +
+

Groups

For the most part the Cwtch risk model for groups is split into two distinct profiles:

  • Groups made up of mutually trusted participants where peers are assumed honest.
  • Groups consisting of strangers where peers are assumed to be potentially malicious.

Most of the mitigations described in this section relate to the latter case, but naturally also impact the former. Even if assumed honest peers later turn malicious there are mechanisms that can detect such malice and prevent it from happening in the future.

Risk Overview: Key Derivation

In the ideal case we would use a protocol like OTR, the limitations preventing us from doing so right now are:

  • Offline messages are not guaranteed to reach all peers, and as such any metadata relating to key material might get lost. We need a key derivation process which is robust to missing messages or incomplete broadcast.

Risk: Malicious Peer Leaks Group Key and/or Conversation

Status: Partially Mitigated (but impossible to mitigate fully)

Whether dealing with trusted smaller groups or partially-public larger groups there is always the possibility that a malicious actor will leak group messages.

We plan to make it easy for peers to fork groups to mitigate the same key being used to encrypt lots of sensitive information and provide some level of forward secrecy for past group conversations.

Risk: Active Attacks by Group Members

Status: Partially Mitigated

Group members, who have access to the key material of the group, can conspire with a server or other group members to break transcript consistency.

While we cannot directly prevent censorship given this kind of active collusion, we have a number of mechanisms in place that should reveal the presence of censorship to honest members of the group.

Mitigations:

  • Because each message is signed by the peers public key, it should not be possible (within the cryptographic assumptions of the underlying cryptography) for one group member to imitate another.
  • Each message contains a unique identifier derived from the contents and the previous message hash - making it impossible for collaborators to include messages from non-colluding members without revealing an implicit message chain (which if they were attempting to censor other messages would reveal such censorship)

Finally: We are actively working on adding non-repudiation to Cwtch servers such that they themselves are restricted in what they can censor efficiently.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/cwtch/key_bundles/index.html b/build-staging/it/security/components/cwtch/key_bundles/index.html new file mode 100644 index 00000000..58650808 --- /dev/null +++ b/build-staging/it/security/components/cwtch/key_bundles/index.html @@ -0,0 +1,24 @@ + + + + + +Key Bundles | The Cwtch Handbook + + + + + + + + + + + + +
+

Key Bundles

Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary to make Cwtch group communication secure and metadata resistant.

At the time of writing, key bundles are expected to contain 3 keys:

  1. A Tor v3 Onion Service Public Key for the Token Board (ed25519)- used to connect to the service over Tor to post and receive messages.
  2. A Tor v3 Onion Service Public Key for the Token Service (ed25519) - used to acquire tokens to post on the service via a small proof-of-work exercise.
  3. A Privacy Pass Public Key - used in the token acquisition process (a ristretto curve point) . See: OPTR2019-01

The key bundle is signed and can be verified via the first v3 onion service key, thus binding it to that particular oninon address.

Verifying Key Bundles

Profiles who import server key bundles verify them using the following trust-on-first-use (TOFU) algorithm:

  1. Verify the attached signature using the v3 onion address of the server. (If this fails, the import process is halted)
  2. Check that every key type exists. (If this fails, the import process is halted)
  3. If the profile has imported the server key bundle previously, assert that all the keys are the same. (If this fails, the import process is halted)
  4. Save the keys to the servers contact entry.

In the future this algorithm will likely be altered to allow the addition of new public keys (e.g. to allow tokens to be acquired via a Zcash address.)

Technically, at steps (2) and (3() the server can be assumed to be malicious, having signed a valid key bundle that does not conform to the specifications. When groups are moved from "experimental" to "stable" such an action will result in a warning being communicated to the profile.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/cwtch/message_formats/index.html b/build-staging/it/security/components/cwtch/message_formats/index.html new file mode 100644 index 00000000..1d99f3c9 --- /dev/null +++ b/build-staging/it/security/components/cwtch/message_formats/index.html @@ -0,0 +1,24 @@ + + + + + +Message Formats | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Formats

Peer to Peer Messages

PeerMessage {
ID string // A unique Message ID (primarily used for acknowledgments)
Context string // A unique context identifier i.e. im.cwtch.chat
Data []byte // The context-dependent serialized data packet.
}

Context Identifiers

  • im.cwtch.raw - Data contains a plain text chat message (see: overlays for more information)

  • im.cwtch.acknowledgement - Data is empty and ID references a previously sent message

  • im.cwtch.getVal and im.cwtch.retVal - Used for requesting / returning specific information about a peer. Data contains a serialized peerGetVal structure and peerRetVal respectively.

      peerGetVal struct {
    Scope string
    Path string
    }

    type peerRetVal struct {
    Val string // Serialized path-dependent value
    Exists bool
    }

Plaintext / Decrypted Group Messages

type DecryptedGroupMessage struct {
Text string // plaintext of the message
Onion string // The Cwtch address of the sender
Timestamp uint64 // A user specified timestamp
// NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages
// We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.
// respect particular group constitutions) can be built on top of group messages, but the underlying groups are
// now agnostic to those models.
SignedGroupID []byte
PreviousMessageSig []byte // A reference to a previous message
Padding []byte // random bytes of length = 1800 - len(Text)
}

DecryptedGroupMessage contains random padding to a fixed size that is equal to the length of all fixed length fields + 1800. This ensures that all encrypted group messages are equal length.

Encrypted Group Messages

// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server
type EncryptedGroupMessage struct {
Ciphertext []byte
Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key
}

Calculating the signature requires knowing the groupID of the message, the server the group is associated with and the decrypted group message (and thus, the Group Key). It is (ed25519) signed by the sender of the message, and can be verified using their public Cwtch address key.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/cwtch/server/index.html b/build-staging/it/security/components/cwtch/server/index.html new file mode 100644 index 00000000..bbf76e11 --- /dev/null +++ b/build-staging/it/security/components/cwtch/server/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Server | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Server

The goal of the Cwtch protocol is to enable group communication through Untrusted Infrastructure.

Unlike in relay-based schemes where the groups assign a leader, set of leaders, or a trusted third party server to ensure that every member of the group can send and receive messages in a timely manner (even if members are offline) - untrusted infrastructure has a goal of realizing those properties without the assumption of trust.

The original Cwtch paper defined a set of properties that Cwtch Servers were expected to provide:

  • Cwtch Server may be used by multiple groups or just one.
  • A Cwtch Server, without collaboration of a group member, should never learn the identity of participants within a group.
  • A Cwtch Server should never learn the content of any communication.
  • A Cwtch Server should never be able to distinguish messages as belonging to a particular group.

We note here that these properties are a superset of the design aims of Private Information Retrieval structures.

Malicious Servers

We expect the presence of malicious entities within the Cwtch ecosystem.

We also prioritize decentralization and permissionless entry into the ecosystem and as such we do not base any security claims on the following:

  • Any non-collusion assumptions between a set of Cwtch servers
  • Any third-party defined verification process

Peers themselves are encouraged to set up and run Cwtch servers where they can guarantee more efficient properties by relaxing trust and security assumptions - however, by default, we design the protocol to be secure without these assumptions - sacrificing efficiency where necessary.

Detectable Faults

  • If a Cwtch server fails to relay a specific message to a subset of group members then there will be a detectable gap in the message tree of certain peers that can be discovered through peer-to-peer gossip.
  • A Cwtch server cannot modify any message without the key material known to the group (any attempt to do so for a subset of group members will result in identical behavior to failing to relay a message).
  • While a server can duplicate messages, these will have no impact on the group message tree (because of encryption, nonces and message identities) - the source of the duplication is not knowable to a peer.

Efficiency

As of writing, only 1 protocol is known for achieving the desired properties, naive PIR or "the server sends everything, and the peers sift through it".

This has an obvious impact on bandwidth efficiency, especially for peers using mobile devices, as such we are actively developing new protocols in which the privacy and efficiency guarantees can be traded-off in different ways.

As of writing, the servers allow both a complete download of all stored messages, and a request to download messages from a certain specified message.

All peers when they first join a group on a new server download all messages from the server, and from then on download only new messages.

Note: This behaviour does permit a mild form of metadata analysis. The server can new messages for each suspected unique profile, and then use these unique message signatures to track unique sessions over time ( via requests for new messages).

This is mitigated by 2 confounding factors:

  1. Profiles can refresh their connections at any time - resulting in fresh server session.
  2. Profiles can "resync" from a server at any time - resulting in a new call to download all messages. The most common usecase for this behaviour is to fetch older messages from a group.

In combination, these 2 mitigations place bounds on what the server is able to infer however we still cannot provide full metadata-resistance.

For potential future solutions to this problem see Niwl

Protecting the Server from Malicious Peers

The main risk to servers come in the form of spam generated by peers. In the prototype of Cwtch a spamguard mechanism was put in place that required peers to conduct some arbitrary proof of work given a server-specified parameter.

This is not a robust solution in the presence of a determined adversary with a significant amount of resources, and thus one of the main external risks to the Cwtch system becomes censorship-via-resource exhaustion.

We have outlined a potential solution to this in token based services but note that this also requires further development.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/ecosystem-overview/index.html b/build-staging/it/security/components/ecosystem-overview/index.html new file mode 100644 index 00000000..91175f6f --- /dev/null +++ b/build-staging/it/security/components/ecosystem-overview/index.html @@ -0,0 +1,24 @@ + + + + + +Component Ecosystem Overview | The Cwtch Handbook + + + + + + + + + + + + +
+

Component Ecosystem Overview

Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of each component and how it relates to the wider Cwtch ecosystem.

openprivacy/connectivity

Summary: A library providing an ACN (Anonymous Communication Network ) networking abstraction.

The goal of connectivity is to abstract away the underlying libraries/software needed to communicate with a specific ACN. Right now we only support Tor and so the job of connectivity is to:

  • Start and Stop the Tor Process
  • Provide configuration to the Tor process
  • Allow raw connections to endpoints via the Tor process (e.g. connect to onion services)
  • Host endpoints via the Tor process (e.g. host onion services)
  • Provide status updates about the underlying Tor process

For more information see connectivity

cwtch.im/tapir

Summary: Tapir is a small library for building p2p applications over anonymous communication systems.

The goal of tapir is to abstract away applications over a particular ACN. Tapir supports:

For more information see tapir

cwtch.im/cwtch

Summary: Cwtch is the main library for implementing the Cwtch protocol / system.

The goal of Cwtch is to provide implementations for cwtch-specific applications e.g. message sending, groups, and file sharing(implemented as Tapir applications), provide interfaces for managing and storing Cwtch profiles, provide an event bus for subsystem splutting and building plugins with new functionality, in addition to managing other core functionality.

The Cwtch library is also responsible for maintaining canonical model representations for wire formats and overlays.

cwtch.im/libcwtch-go

Summary: libcwtch-go provides C (including Android) bindings for Cwtch for use in UI implementations.

The goal of libcwtch-go is to bridge the gap between the backend Cwtch library and any front end systems which may be written in a different language.

The API provided by libcwtch is much more restricted than the one provided by Cwtch directly, each libcwtch API typically packages up several calls to Cwtch.

libcwtch-go is also responsible for managing UI settings and experimental gating. It is also often used as a staging ground for experimental features and code that may eventually end up in Cwtch.

cwtch-ui

Summary: A flutter based UI for Cwtch.

Cwtch UI uses libcwtch-go to provide a complete UI for Cwtch, allowing people to create and manage profiles, add contacts and groups, message people, share files (coming soon) and more.

The UI is also responsible for managing localization and translations.

For more information see Cwtch UI

Auxiliary Components

Occasionally, Open Privacy will factor out parts of Cwtch into standalone libraries that are not Cwtch specific. These are briefly summarized here:

openprivacy/log

An Open Privacy specific logging framework that is used throughout Cwtch packages.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/intro/index.html b/build-staging/it/security/components/intro/index.html new file mode 100644 index 00000000..d78e3ff8 --- /dev/null +++ b/build-staging/it/security/components/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Technical Basics | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Technical Basics

This page presents a brief technical overview of the Cwtch protocol.

A Cwtch Profile

Users can create one of more Cwtch Profiles. Each profile generates a random ed25519 keypair compatible with Tor.

In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys + associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages).

2-party conversions: Peer to Peer

For 2 parties to engage in a peer-to-peer conversation both must be online, but only one needs to be reachable via their onion service. For the sake of clarity we often label one party the "inbound peer" (the one who hosts the onion service) and the other party the "outbound peer" (the one that connects to the onion service).

After connection both parties engage in an authentication protocol which:

  • Asserts that each party has access to the private key associated with their public identity.
  • Generates an ephemeral session key used to encrypt all further communication during the session.

This exchange (documented in further detail in authentication protocol) is offline deniable i.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the fact - it is impossible to definitely prove that the exchange happened at all.

After, the authentication protocol the two parties may exchange messages with each other freely.

Multi-party conversations: Groups and Peer to Server Communication

Note: Metadata Resistant Group Communication is still an active research area and what is documented here will likely change in the future.

When a person wants to start a group conversation they first randomly generate a secret Group Key. All group communication will be encrypted using this key.

Along with the Group Key, the group creator also decides on a Cwtch Server to use as the host of the group. For more information on how Servers authenticate themselves see key bundles.

A Group Identifier is generated using the group key and the group server and these three elements are packaged up into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections).

To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts their message using the Group Key and generates a cryptographic signature over the Group Id, Group Server and the decrypted message (see: wire formats for more information).

To receive message from the group, a profile connected to the server hosting the group and downloads all messages (since their previous connection). Profiles then attempt to decrypt each message using the Group Key and if successful attempt to verify the signature (see Cwtch Servers Cwtch Groups for an overview of attacks and mitigations).

Servers are Peers

In many respects communication with a server is identical to communication with a regular Cwtch peer, all the same steps above are taken however the server always acts as the inbound peer, and the outbound peer always uses newly generated ephemeral keypair as their "longterm identity".

As such peer-server conversations only differ in the kinds of messages that are sent between the two parties, with the server relaying all messages that it receives and also allowing any client to query for older messages.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/tapir/authentication_protocol/index.html b/build-staging/it/security/components/tapir/authentication_protocol/index.html new file mode 100644 index 00000000..7e4422f2 --- /dev/null +++ b/build-staging/it/security/components/tapir/authentication_protocol/index.html @@ -0,0 +1,24 @@ + + + + + +Authentication Protocol | The Cwtch Handbook + + + + + + + + + + + + +
+

Authentication Protocol

Each peer, given an open connection CC:

I=InitializeIdentity()Ie=InitializeEphemeralIdentity()I,IeCP,PeCk=KDF(Pei+Pie+Peie)c=E(k,transcript.Commit())cCcpCD(k,cp)=?transcript.LatestCommit()I = \mathrm{InitializeIdentity()} \\ I_e = \mathrm{InitializeEphemeralIdentity()} \\ I,I_e \rightarrow C \\ P,P_e \leftarrow C \\ k = \mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\ c = \mathrm{E}(k, transcript.Commit()) \\ c \rightarrow C \\ c_p \leftarrow C\\ \mathrm{D}(k, c_p) \stackrel{?}{=} transcript.LatestCommit()

The above represents a sketch protocol, in reality there are a few implementation details worth pointing out:

Once derived from the key derivation function (KDF\mathrm{KDF}) the key (kk) is set on the connection, meaning the authentication app doesn't do the encryption or decryption explicitly.

The concatenation of parts of the 3DH exchange is strictly ordered:

  • DH of the Long term identity of the outbound connection by the ephemeral key of the inbound connection.
  • DH of the Long term identity of the inbound connection by the ephemeral key of the outbound connection.
  • DH of the two ephemeral identities of the inbound and outbound connections.

This strict ordering ensures both sides of the connection derive the same session key.

Cryptographic Properties

During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come from their peer (or at least, someone with possession of their peers secret key as it related to their onion address).

Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and all encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant repudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied that a single message in the transcript must have originated from a peer, there is no way of linking any other message to the session.

Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the session key is made public it can be used to forge new messages in the transcript - and as such, any standalone transcript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/tapir/packet_format/index.html b/build-staging/it/security/components/tapir/packet_format/index.html new file mode 100644 index 00000000..a98b885f --- /dev/null +++ b/build-staging/it/security/components/tapir/packet_format/index.html @@ -0,0 +1,24 @@ + + + + + +Packet Format | The Cwtch Handbook + + + + + + + + + + + + +
+

Packet Format

All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, len bytes of data, and the rest zero padded:

| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|

Once encrypted, the entire 8192 byte data packet is encrypted using libsodium secretbox using the standard structure ( note in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)

For information on how the secret key is derived see the authentication protocol

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/ui/android/index.html b/build-staging/it/security/components/ui/android/index.html new file mode 100644 index 00000000..1daaf1cc --- /dev/null +++ b/build-staging/it/security/components/ui/android/index.html @@ -0,0 +1,24 @@ + + + + + +Android Service | The Cwtch Handbook + + + + + + + + + + + + +
+

Android Service

Adapted from: Discreet Log #11: Integrating FFI processes with Android services

In addition to needing to make plain ol’ method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isn’t really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service.

The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, it’s not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service.

If you’d like to follow along, our WorkManager specifications are created in the handleCwtch() method of MainActivity.kt, and the workers themselves are defined in FlwtchWorker.kt.

Our plain ol’ method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback.

One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, it’s easy for it to yield and resume as necessary while waiting for events to be generated. Cwtch’s goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately.

FlwtchWorker’s eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isn’t running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontend’s Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary.

Messages and other permanent state are stored on disk by the service, so the frontend doesn’t need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state.

Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isn’t the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:

private fun getNativeLibDir(): String {
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
"im.cwtch.flwtch", // Must be app name
PackageManager.GET_SHARED_LIBRARY_FILES)
return ainfo.nativeLibraryDir
}

…then, whenever the app is launched, we cancel any jobs that aren’t tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/ui/image_previews/index.html b/build-staging/it/security/components/ui/image_previews/index.html new file mode 100644 index 00000000..1292af16 --- /dev/null +++ b/build-staging/it/security/components/ui/image_previews/index.html @@ -0,0 +1,24 @@ + + + + + +Image Previews | The Cwtch Handbook + + + + + + + + + + + + +
+

Image Previews

Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename’s extension (and no, we’re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they’ll go to the app’s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.

For now, we only support single-image messages, and any image editing/cropping will have to be done in a separate application. As we mention in the filesharing FAQ, image files also frequently contain significant hidden metadata, and you should only share them with people you trust.

KnownRisks

Other Applications and/or the OS Inferring Information from Images

Images must be stored somewhere, and for now we have chosen to store them unencrypted on the file system. We have done this for 2 reasons:

  1. In order to support more powerful file sharing schemes like rehosting we require the ability to efficiently scan files and deliver chunks - doing this through an encrypted database layer would harm performance.
  2. This information always has to transit the application boundary (either via display drivers, or storing and viewing the file in an external application) - there is nothing that Cwtch can do after that point in any case.

Malicious Images Crashing or otherwise Compromising Cwtch

Flutter uses Skia to render Images. While the underlying code is memory unsafe, it is extensively fuzzed as part of regular development.

We also conduct our own fuzz testing of Cwtch components. In that analysis we found a single crash bug related to a malformed GIF file that caused the renderer to allocate a ridiculous amount of memory (and eventually be refused by the kernel). To prevent this from impacting Cwtch we have adopted the policy of always enabling a maximum cacheWidth and/or cacheHeight for Image widgets.

Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata

Recently a bug was found in Apple's png parser which would cause an image to render differently on Apple devices as it would on non-Apple devices.

We conducted a few tests on our Mac builds and could not replicate this issue for Flutter (because all Flutter builds use Skia for rendering), however we will continue to include such cases in our testing corpus.

For now image previews will remain experimental and opt-in.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/ui/input/index.html b/build-staging/it/security/components/ui/input/index.html new file mode 100644 index 00000000..c81c39d6 --- /dev/null +++ b/build-staging/it/security/components/ui/input/index.html @@ -0,0 +1,24 @@ + + + + + +Input | The Cwtch Handbook + + + + + + + + + + + + +
+

Input

Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices

Status: Partially Mitigated

Any component that has the potential to intercept data between a person, and the Cwtch app is a potential security risk.

One of the most likely interceptors is a 3rd party IME (Input Method Editor) commonly used by people to generate characters not natively supported by their device.

Even benign and stock IME apps may unintentionally leak information about the contents of a persons message e.g. through cloud synchronization, cloud translation or personal dictionaries.

Ultimately, this problem cannot be solved by Cwtch alone, and is a wider risk impacting the entire mobile ecosystem.

A similar risk exists on desktop through the use of similar input applications (in addition to software keyloggers), however we consider that fully outside the scope of Cwtch risk assessment (in line with other attacks on the security of the underlying operating system itself).

This is partially mitigated in Cwtch 1.2 through the use of enableIMEPersonalizedLearning: false. See this PR for more information.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/components/ui/overlays/index.html b/build-staging/it/security/components/ui/overlays/index.html new file mode 100644 index 00000000..9d8b9a68 --- /dev/null +++ b/build-staging/it/security/components/ui/overlays/index.html @@ -0,0 +1,24 @@ + + + + + +Message Overlays | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Overlays

Adapted from: Discreet Log #8: Notes on the Cwtch Chat API

Note: This section covers overlay protocols on-top of the Cwtch protcol. For information on the Cwtch Protocol messages themselves please see Message Formats

We envision Cwtch as a platform for providing an authenticated transport layer to higher-level applications. Developers are free to make their own choices about what application layer protocols to use, whether they want bespoke binary message formats or just want to throw an HTTP library on top and call it a day. Cwtch can generate new keypairs for you (which become onion addresses; no need for any DNS registrations!) and you can REST assured that any data your application receives from the (anonymous communication) network has been authenticated already.

For our current stack, messages are wrapped in a minimal JSON frame that adds some contextual information about the message type. And because serialised JSON objects are just dictionaries, we can easily add more metadata later on as needed.

Chat overlays, lists, and bulletins

The original Cwtch alpha demoed "overlays": different ways of interpreting the same data channel, depending on the structure of the atomic data itself. We included simple checklists and BBS/classified ads as overlays that could be viewed and shared with any Cwtch contact, be it a single peer or a group. The wire format looked like this:

{o:1,d:"hey there!"}
{o:2,d:"bread",l:"groceries"}
{o:3,d:"garage sale",p:"[parent message signature]"}

Overlay field o determined if it was a chat (1), list (2), or bulletin (3) message. The data field d is overloaded, and lists/bulletins need additional information about what group/post they belong to. (We use message signatures in place of IDs to avoid things like message ordering problems and maliciously crafted IDs. This is also how the Cwtch protocol communicates to the front end which message is being acked.)

Data structure

Implementing tree-structured data on top of a sequential message store comes with obvious performance disadvantages. For example, consider the message view, which loads most-recent-messages first and only goes back far enough to fetch enough messages to fill the current viewport, in comparison with a (somewhat pathological) forum where almost every message is a child of the very first message in the history, which could have been gigs and gigs of data-ago. If the UI only displays top-level posts until the user expands them, we have to parse the entire history before we get enough info to display anything at all.

Another problem is that multiplexing all these overlays into one data store creates "holes" in the data that confuse lazy-loaded listviews and scrollbars. The message count may indicate there is a ton more information to display if the user simply scrolls, but when it actually gets fetched and parsed we might realize that none of it is relevant to the current overlay.

None of these problems are insurmountable, but they demonstrate a flaw in our initial assumptions about the nature of collaborative message flows and how we should be handling that data.

Overlay Types

As stated above, overlays are specified in a very simple JSON format with the following structure:

type ChatMessage struct {
O int `json:"o"`
D string `json:"d"`
}

Where O stands for Overlay with the current supported overlays documented below:

1: data is a chat string
2: data is a list state/delta
3: data is a bulletin state/delta
100: contact suggestion; data is a peer onion address
101: contact suggestion; data is a group invite string

Chat Messages (Overlay 1)

The most simple over is a chat message which simply contains raw, unprocessed chat message information.

{o:1,d:"got milk?"}

Invitations (Overlays 100 and 101)

Instead of receiving the invite as an incoming contact request at the profile level, new inline invites are shared with a particular contact/group, where they can be viewed and/or accepted later, even if they were initially rejected (potentially by accident).

The wire format for these are equally simple:

{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}
{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}

This represents a departure from our original "overlays" thinking to a more action-oriented representation. The chat "overlay" can communicate that someone did something, even if it's paraphrased down to "added an item to a list," and the lists and bulletins and other beautifully chaotic data can have their state precomputed and stored separately.

Lists / Bulletin Boards

Note: Expected to be Defined in Cwtch Beta 1.5

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/deployment/index.html b/build-staging/it/security/deployment/index.html new file mode 100644 index 00000000..b89f4b6b --- /dev/null +++ b/build-staging/it/security/deployment/index.html @@ -0,0 +1,24 @@ + + + + + +Deployment | The Cwtch Handbook + + + + + + + + + + + + +
+

Deployment

Risk: Binaries are replaced on the website with malicious ones

Status: Partially-mitigated

While this process is now mostly automated, should this automation ever be compromised then there is nothing in our current process that would detect this.

We need:

  • Reproducible Builds - we currently use public docker containers for all builds which should allow anyone to compare distributed builds with ones built from source.
  • Signed Releases - Open Privacy does not yet maintain a public record of staff public keys. This is likely a necessity for signing released builds and creating an audit chain backed by the organization. This process must be manual by definition.
+ + + + \ No newline at end of file diff --git a/build-staging/it/security/development/index.html b/build-staging/it/security/development/index.html new file mode 100644 index 00000000..1fd05e03 --- /dev/null +++ b/build-staging/it/security/development/index.html @@ -0,0 +1,24 @@ + + + + + +Development | The Cwtch Handbook + + + + + + + + + + + + +
+

Development

The main process to counter malicious actors in development of Cwtch is the openness of the process.

To enhance this openness, automated builds, testing and packaging are defined as part of the repositories - improving te robustness of the code base at every stage.

While individual tests aren't perfect, and all processes have gaps, we should be committed to make it as easy as possible to contribute to Cwtch while also building pipelines and processes that catch errors (unintential or malicious) as soon as possible.

Risk: Developer Directly Pushes Malicious Code

Status: Mitigated

trunk is currently locked and only 3 Open Privacy staff members have permission to override it, in addition the responsibility of monitoring changes.

Further every new pull request and merge triggered automated builds & tests which trigger emails and audit logs.

The code is also open source and inspectable by anyone.

Risk: Code Regressions

Status: Partially Mitigated (See individual project entries in this handbook for more information)

Our automated pipelines have the ability to catch regressions when that behaviour is detectable.

The greatest challenge is in defining how such regressions are detected for the ui - where behaviour isn't as strictly defined as it is for the individual libraries.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/intro/index.html b/build-staging/it/security/intro/index.html new file mode 100644 index 00000000..8c04c42f --- /dev/null +++ b/build-staging/it/security/intro/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Security Handbook | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Security Handbook

Welcome to the Cwtch Secure Development Handbook! The purpose of this handbook is to provide a guide to the various components of the Cwtch ecosystem, to document the known risks and mitigations, and to enable discussion about improvements and updates to Cwtch secure development processes.

What is Cwtch?

Cwtch (/kʊtʃ/ - a Welsh word roughly translating to “a hug that creates a safe place”) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications.

  • Decentralized and Open: There is no “Cwtch service” or “Cwtch network”. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch.
  • Privacy Preserving: All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services.
  • Metadata Resistant: Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.

A (Brief) History of Metadata Resistant Chat

In recent years, public awareness of the need and benefits of end-to-end encrypted solutions has increased with applications like Signal, Whatsapp and Wire now providing users with secure communications.

However, these tools require various levels of metadata exposure to function, and much of this metadata can be used to gain details about how and why a person is using a tool to communicate. [rottermanner2015privacy].

One tool that did seek to reduce metadata is Ricochet first released in 2014. Ricochet used Tor v2 onion services to provide secure end-to-end encrypted communication, and to protect the metadata of communications.

There were no centralized servers that assist in routing Ricochet conversations. No one other than the parties involved in a conversation could know that such a conversation is taking place.

Ricochet wasn't without limitations; there was no multi-device support, nor is there a mechanism for supporting group communication or for a user to send messages while a contact is offline.

This made adoption of Ricochet a difficult proposition; with even those in environments that would be served best by metadata resistance unaware that it exists [ermoshina2017can] [renaud2014doesn].

Additionally, any solution to decentralized, metadata resistant communication faces fundamental problems when it comes to efficiency, privacy and group security (as defined by transcript consensus and consistency).

Modern alternatives to Ricochet include Briar, Zbay and Ricochet Refresh - each tool seeks to optimize for a different set of trade-offs e.g. Briar seeks to allow people to communicate even when underlying network infrastructure is down while providing resistant to metadata surveillance.


The Cwtch project began in 2017 as an extension protocol for Ricochet providing group conversations via untrusted servers, with an eye to enabling decentralized, metadata resistant applications (like shared lists and bulletin board)

An alpha version of Cwtch was was launched in February 2019, and since then the Cwtch team (run by the Open Privacy Research Society) has conducted research and development into Cwtch and the underlying protocols and libraries and problem spaces.

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/references/index.html b/build-staging/it/security/references/index.html new file mode 100644 index 00000000..5ede2ffd --- /dev/null +++ b/build-staging/it/security/references/index.html @@ -0,0 +1,24 @@ + + + + + +References | The Cwtch Handbook + + + + + + + + + + + + +
+

References

  • Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."

  • Brooks, John. Ricochet: Anonymous instant messaging for real privacy. https://ricochet.im. Accessed: 2018-03-10

  • Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.

  • Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.

  • Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).

  • Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata—New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.

  • Langley, Adam. Pond. https://github.com/agl/pond. Accessed: 2018-05-21.

  • Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).

  • Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).

  • Kalysch, A., Bove, D. and Müller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).

  • Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn’t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.

  • Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).

  • Unger, Nik et al. “SoK: secure messaging”. In: Security and Privacy (SP ), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232–249 link

+ + + + \ No newline at end of file diff --git a/build-staging/it/security/risk/index.html b/build-staging/it/security/risk/index.html new file mode 100644 index 00000000..27c7bfd8 --- /dev/null +++ b/build-staging/it/security/risk/index.html @@ -0,0 +1,24 @@ + + + + + +Risk Model | The Cwtch Handbook + + + + + + + + + + + + +
+

Risk Model

Communications metadata is known to be exploited by various adversaries to undermine the security of systems, to track victims and to conduct large scale social network analysis to feed mass surveillance. Metadata resistant tools are in their infancy and research into the construction and user experience of such tools is lacking.

Cwtch was originally conceived as an extension of the metadata resistant protocol Ricochet to support asynchronous, multi-peer group communications through the use of discardable, untrusted, anonymous infrastructure.

Since then, Cwtch has evolved into a protocol in its own right, this section will outline the various known risks that Cwtch attempts to mitigate and will be heavily referenced throughout the rest of the document when discussing the various sub-components of the Cwtch Architecture.

Threat Model

It is important to identify and understand that metadata is ubiquitous in communication protocols, it is indeed necessary for such protocols to function efficiently and at scale. However, information that is useful to facilitating peers and servers is also highly relevant to adversaries wishing to exploit such information.

For our problem definition, we will assume that the content of a communication is encrypted in such a way that an adversary is practically unable to break (see tapir and cwtch for details on the encryption that we use, a and as such we will focus to the context to the communication metadata.

We seek to protect the following communication contexts:

  • Who is involved in a communication? It may be possible to identify people or simply device or network identifiers. E.g., “this communication involves Alice, a journalist, and Bob a government employee.”.
  • Where are the participants of the conversation? E.g., “during this communication Alice was in France and Bob was in Canada.”
  • When did a conversation take place? The timing and length of communication can reveal a large amount about the nature of a call, e.g., “Bob a government employee, talked to Alice on the phone for an hour yesterday evening. This is the first time they have communicated.” *How was the conversation mediated? Whether a conversation took place over an encrypted or unencrypted email can provide useful intelligence. E.g., “Alice sent an encrypted email to Bob yesterday, whereas they usually only send plaintext emails to each other.”
  • What is the conversation about? Even if the content of the communication is encrypted it is sometimes possible to derive a probable context of a conversation without knowing exactly what is said, e.g. “a person called a pizza store at dinner time” or “someone called a known suicide hotline number at 3am.”

Beyond individual conversations, we also seek to defend against context correlation attacks, whereby multiple conversations are analyzed to derive higher level information:

  • Relationships: Discovering social relationships between a pair of entities by analyzing the frequency and length of their communications over a period of time. E.g. Carol and Eve call each other every single day for multiple hours at a time.
  • Cliques: Discovering social relationships between a group of entities that all interact with each other. E.g. Alice, Bob and Eve all communicate with each other.
  • Loosely Connected Cliques and Bridge Individuals: Discovering groups that communicate to each other through intermediaries by analyzing communication chains (e.g. everytime Alice talks to Bob she talks to Carol almost immediately after; Bob and Carol never communicate.)
  • Pattern of Life: Discovering which communications are cyclical and predictable. E.g. Alice calls Eve every Monday evening for around an hour.

Active Attacks

Misrepresentation Attacks

Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks based around misrepresentation i.e. people pretending to be other people:

A basic flow of one of these attacks is as follows, although other flows also exist:

  • Alice has a friend named Bob and another called Eve
  • Eve finds out Alice has a friend named Bob
  • Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)
  • Eve calls this new account "Eve New Account" and adds Alice as a friend.
  • Eve then changes her name on "Eve New Account" to "Bob"
  • Alice sends messages intended for "Bob" to Eve's fake Bob account

Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them is for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply won't-happen.

As such we aim to provide some user-experience hints in the ui to guide people in making choices around whether to trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users.

A note on Physical Attacks

Cwtch does not consider attacks that require physical access (or equivalent) to the users machine as practically defendable. However, in the interests of good security engineering, throughout this document we will still refer to attacks or conditions that require such privilege and point out where any mitigations we have put in place will fail.

+ + + + \ No newline at end of file diff --git a/build-staging/it/sitemap.xml b/build-staging/it/sitemap.xml new file mode 100644 index 00000000..9ba573bf --- /dev/null +++ b/build-staging/it/sitemap.xml @@ -0,0 +1 @@ +https://docs.cwtch.im/it/blogweekly0.5https://docs.cwtch.im/it/blog/archiveweekly0.5https://docs.cwtch.im/it/blog/autobindingsweekly0.5https://docs.cwtch.im/it/blog/autobindings-iiweekly0.5https://docs.cwtch.im/it/blog/availability-status-profile-attributesweekly0.5https://docs.cwtch.im/it/blog/cwtch-android-reproducibilityweekly0.5https://docs.cwtch.im/it/blog/cwtch-bindings-reproducibleweekly0.5https://docs.cwtch.im/it/blog/cwtch-developer-documentationweekly0.5https://docs.cwtch.im/it/blog/cwtch-documentationweekly0.5https://docs.cwtch.im/it/blog/cwtch-nightly-1-11weekly0.5https://docs.cwtch.im/it/blog/cwtch-nightly-1-12weekly0.5https://docs.cwtch.im/it/blog/cwtch-nightly-v.11-74weekly0.5https://docs.cwtch.im/it/blog/cwtch-platform-supportweekly0.5https://docs.cwtch.im/it/blog/cwtch-stable-api-designweekly0.5https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-updateweekly0.5https://docs.cwtch.im/it/blog/cwtch-stable-roadmap-update-juneweekly0.5https://docs.cwtch.im/it/blog/cwtch-testing-iweekly0.5https://docs.cwtch.im/it/blog/cwtch-testing-iiweekly0.5https://docs.cwtch.im/it/blog/page/2weekly0.5https://docs.cwtch.im/it/blog/path-to-cwtch-stableweekly0.5https://docs.cwtch.im/it/blog/tagsweekly0.5https://docs.cwtch.im/it/blog/tags/apiweekly0.5https://docs.cwtch.im/it/blog/tags/autobindingsweekly0.5https://docs.cwtch.im/it/blog/tags/bindingsweekly0.5https://docs.cwtch.im/it/blog/tags/cwtchweekly0.5https://docs.cwtch.im/it/blog/tags/cwtch-stableweekly0.5https://docs.cwtch.im/it/blog/tags/cwtch-stable/page/2weekly0.5https://docs.cwtch.im/it/blog/tags/cwtch/page/2weekly0.5https://docs.cwtch.im/it/blog/tags/developer-documentationweekly0.5https://docs.cwtch.im/it/blog/tags/documentationweekly0.5https://docs.cwtch.im/it/blog/tags/libcwtchweekly0.5https://docs.cwtch.im/it/blog/tags/nightlyweekly0.5https://docs.cwtch.im/it/blog/tags/planningweekly0.5https://docs.cwtch.im/it/blog/tags/releaseweekly0.5https://docs.cwtch.im/it/blog/tags/repliqateweekly0.5https://docs.cwtch.im/it/blog/tags/reproducible-buildsweekly0.5https://docs.cwtch.im/it/blog/tags/security-handbookweekly0.5https://docs.cwtch.im/it/blog/tags/supportweekly0.5https://docs.cwtch.im/it/blog/tags/testingweekly0.5https://docs.cwtch.im/it/developing/building-a-cwtch-app/building-an-echobotweekly0.5https://docs.cwtch.im/it/developing/building-a-cwtch-app/core-conceptsweekly0.5https://docs.cwtch.im/it/developing/building-a-cwtch-app/introweekly0.5https://docs.cwtch.im/it/developing/category/building-a-cwtch-appweekly0.5https://docs.cwtch.im/it/developing/introweekly0.5https://docs.cwtch.im/it/developing/releaseweekly0.5https://docs.cwtch.im/it/docs/category/appearanceweekly0.5https://docs.cwtch.im/it/docs/category/behaviourweekly0.5https://docs.cwtch.im/it/docs/category/contributeweekly0.5https://docs.cwtch.im/it/docs/category/conversationsweekly0.5https://docs.cwtch.im/it/docs/category/experimentsweekly0.5https://docs.cwtch.im/it/docs/category/getting-startedweekly0.5https://docs.cwtch.im/it/docs/category/groupsweekly0.5https://docs.cwtch.im/it/docs/category/platformsweekly0.5https://docs.cwtch.im/it/docs/category/profilesweekly0.5https://docs.cwtch.im/it/docs/category/serversweekly0.5https://docs.cwtch.im/it/docs/category/settingsweekly0.5https://docs.cwtch.im/it/docs/chat/accept-deny-new-conversationweekly0.5https://docs.cwtch.im/it/docs/chat/add-contactweekly0.5https://docs.cwtch.im/it/docs/chat/block-contactweekly0.5https://docs.cwtch.im/it/docs/chat/conversation-settingsweekly0.5https://docs.cwtch.im/it/docs/chat/delete-contactweekly0.5https://docs.cwtch.im/it/docs/chat/introductionweekly0.5https://docs.cwtch.im/it/docs/chat/message-formattingweekly0.5https://docs.cwtch.im/it/docs/chat/reply-to-messageweekly0.5https://docs.cwtch.im/it/docs/chat/save-conversation-historyweekly0.5https://docs.cwtch.im/it/docs/chat/share-address-with-friendsweekly0.5https://docs.cwtch.im/it/docs/chat/share-fileweekly0.5https://docs.cwtch.im/it/docs/chat/unblock-contactweekly0.5https://docs.cwtch.im/it/docs/contribute/developingweekly0.5https://docs.cwtch.im/it/docs/contribute/documentationweekly0.5https://docs.cwtch.im/it/docs/contribute/stickersweekly0.5https://docs.cwtch.im/it/docs/contribute/testingweekly0.5https://docs.cwtch.im/it/docs/contribute/translateweekly0.5https://docs.cwtch.im/it/docs/getting-started/supported_platformsweekly0.5https://docs.cwtch.im/it/docs/groups/accept-group-inviteweekly0.5https://docs.cwtch.im/it/docs/groups/create-groupweekly0.5https://docs.cwtch.im/it/docs/groups/edit-group-nameweekly0.5https://docs.cwtch.im/it/docs/groups/introductionweekly0.5https://docs.cwtch.im/it/docs/groups/leave-groupweekly0.5https://docs.cwtch.im/it/docs/groups/manage-known-serversweekly0.5https://docs.cwtch.im/it/docs/groups/send-inviteweekly0.5https://docs.cwtch.im/it/docs/introweekly0.5https://docs.cwtch.im/it/docs/platforms/tailsweekly0.5https://docs.cwtch.im/it/docs/profiles/availability-statusweekly0.5https://docs.cwtch.im/it/docs/profiles/change-nameweekly0.5https://docs.cwtch.im/it/docs/profiles/change-passwordweekly0.5https://docs.cwtch.im/it/docs/profiles/change-profile-imageweekly0.5https://docs.cwtch.im/it/docs/profiles/create-a-profileweekly0.5https://docs.cwtch.im/it/docs/profiles/delete-profileweekly0.5https://docs.cwtch.im/it/docs/profiles/exporting-profileweekly0.5https://docs.cwtch.im/it/docs/profiles/importing-a-profileweekly0.5https://docs.cwtch.im/it/docs/profiles/introductionweekly0.5https://docs.cwtch.im/it/docs/profiles/profile-infoweekly0.5https://docs.cwtch.im/it/docs/profiles/unlock-profileweekly0.5https://docs.cwtch.im/it/docs/servers/create-serverweekly0.5https://docs.cwtch.im/it/docs/servers/delete-serverweekly0.5https://docs.cwtch.im/it/docs/servers/edit-serverweekly0.5https://docs.cwtch.im/it/docs/servers/introductionweekly0.5https://docs.cwtch.im/it/docs/servers/share-keyweekly0.5https://docs.cwtch.im/it/docs/servers/unlock-serverweekly0.5https://docs.cwtch.im/it/docs/settings/appearance/change-languageweekly0.5https://docs.cwtch.im/it/docs/settings/appearance/light-dark-modeweekly0.5https://docs.cwtch.im/it/docs/settings/appearance/streamer-modeweekly0.5https://docs.cwtch.im/it/docs/settings/appearance/ui-columnsweekly0.5https://docs.cwtch.im/it/docs/settings/behaviour/block-unknown-connectionsweekly0.5https://docs.cwtch.im/it/docs/settings/behaviour/notification-contentweekly0.5https://docs.cwtch.im/it/docs/settings/behaviour/notification-policyweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/clickable-linksweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/file-sharingweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/group-experimentweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/image-previews-and-profile-picturesweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/message-formattingweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/qrcodesweekly0.5https://docs.cwtch.im/it/docs/settings/experiments/server-hostingweekly0.5https://docs.cwtch.im/it/docs/settings/introductionweekly0.5https://docs.cwtch.im/it/docs/torweekly0.5https://docs.cwtch.im/it/security/category/connectivity--torweekly0.5https://docs.cwtch.im/it/security/category/cwtchweekly0.5https://docs.cwtch.im/it/security/category/cwtch-componentsweekly0.5https://docs.cwtch.im/it/security/category/cwtch-uiweekly0.5https://docs.cwtch.im/it/security/category/tapirweekly0.5https://docs.cwtch.im/it/security/components/connectivity/introweekly0.5https://docs.cwtch.im/it/security/components/cwtch/groupsweekly0.5https://docs.cwtch.im/it/security/components/cwtch/key_bundlesweekly0.5https://docs.cwtch.im/it/security/components/cwtch/message_formatsweekly0.5https://docs.cwtch.im/it/security/components/cwtch/serverweekly0.5https://docs.cwtch.im/it/security/components/ecosystem-overviewweekly0.5https://docs.cwtch.im/it/security/components/introweekly0.5https://docs.cwtch.im/it/security/components/tapir/authentication_protocolweekly0.5https://docs.cwtch.im/it/security/components/tapir/packet_formatweekly0.5https://docs.cwtch.im/it/security/components/ui/androidweekly0.5https://docs.cwtch.im/it/security/components/ui/image_previewsweekly0.5https://docs.cwtch.im/it/security/components/ui/inputweekly0.5https://docs.cwtch.im/it/security/components/ui/overlaysweekly0.5https://docs.cwtch.im/it/security/deploymentweekly0.5https://docs.cwtch.im/it/security/developmentweekly0.5https://docs.cwtch.im/it/security/introweekly0.5https://docs.cwtch.im/it/security/referencesweekly0.5https://docs.cwtch.im/it/security/riskweekly0.5https://docs.cwtch.im/it/weekly0.5 \ No newline at end of file diff --git a/build-staging/it/video/Group_Create.mp4 b/build-staging/it/video/Group_Create.mp4 new file mode 100644 index 00000000..ae82be93 Binary files /dev/null and b/build-staging/it/video/Group_Create.mp4 differ diff --git a/build-staging/it/video/Group_Invite.mp4 b/build-staging/it/video/Group_Invite.mp4 new file mode 100644 index 00000000..cae8629e Binary files /dev/null and b/build-staging/it/video/Group_Invite.mp4 differ diff --git a/build-staging/it/video/Group_Leave.mp4 b/build-staging/it/video/Group_Leave.mp4 new file mode 100644 index 00000000..ecc5a20b Binary files /dev/null and b/build-staging/it/video/Group_Leave.mp4 differ diff --git a/build-staging/it/video/Group_acceptinvite.mp4 b/build-staging/it/video/Group_acceptinvite.mp4 new file mode 100644 index 00000000..a5d4c740 Binary files /dev/null and b/build-staging/it/video/Group_acceptinvite.mp4 differ diff --git a/build-staging/it/video/Server_Delete.mp4 b/build-staging/it/video/Server_Delete.mp4 new file mode 100644 index 00000000..14831661 Binary files /dev/null and b/build-staging/it/video/Server_Delete.mp4 differ diff --git a/build-staging/it/video/Server_Keys.mp4 b/build-staging/it/video/Server_Keys.mp4 new file mode 100644 index 00000000..d9498451 Binary files /dev/null and b/build-staging/it/video/Server_Keys.mp4 differ diff --git a/build-staging/it/video/Server_Manage.mp4 b/build-staging/it/video/Server_Manage.mp4 new file mode 100644 index 00000000..3c812baa Binary files /dev/null and b/build-staging/it/video/Server_Manage.mp4 differ diff --git a/build-staging/it/video/Server_New.mp4 b/build-staging/it/video/Server_New.mp4 new file mode 100644 index 00000000..af57ff12 Binary files /dev/null and b/build-staging/it/video/Server_New.mp4 differ diff --git a/build-staging/it/video/group_edit.mp4 b/build-staging/it/video/group_edit.mp4 new file mode 100644 index 00000000..55f6af2b Binary files /dev/null and b/build-staging/it/video/group_edit.mp4 differ diff --git a/build-staging/it/video/server_edit.mp4 b/build-staging/it/video/server_edit.mp4 new file mode 100644 index 00000000..4ef7b18c Binary files /dev/null and b/build-staging/it/video/server_edit.mp4 differ diff --git a/build-staging/katex/fonts/KaTeX_AMS-Regular.ttf b/build-staging/katex/fonts/KaTeX_AMS-Regular.ttf new file mode 100644 index 00000000..c6f9a5e7 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_AMS-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_AMS-Regular.woff b/build-staging/katex/fonts/KaTeX_AMS-Regular.woff new file mode 100644 index 00000000..b804d7b3 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_AMS-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_AMS-Regular.woff2 b/build-staging/katex/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 00000000..0acaaff0 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_AMS-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.ttf b/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.ttf new file mode 100644 index 00000000..9ff4a5e0 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.woff b/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.woff new file mode 100644 index 00000000..9759710d Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.woff2 b/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.woff2 new file mode 100644 index 00000000..f390922e Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Caligraphic-Bold.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.ttf new file mode 100644 index 00000000..f522294f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.woff b/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.woff new file mode 100644 index 00000000..9bdd534f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 00000000..75344a1f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Caligraphic-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Fraktur-Bold.ttf b/build-staging/katex/fonts/KaTeX_Fraktur-Bold.ttf new file mode 100644 index 00000000..4e98259c Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Fraktur-Bold.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Fraktur-Bold.woff b/build-staging/katex/fonts/KaTeX_Fraktur-Bold.woff new file mode 100644 index 00000000..e7730f66 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Fraktur-Bold.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/build-staging/katex/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 00000000..395f28be Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Fraktur-Bold.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Fraktur-Regular.ttf b/build-staging/katex/fonts/KaTeX_Fraktur-Regular.ttf new file mode 100644 index 00000000..b8461b27 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Fraktur-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Fraktur-Regular.woff b/build-staging/katex/fonts/KaTeX_Fraktur-Regular.woff new file mode 100644 index 00000000..acab069f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Fraktur-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Fraktur-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Fraktur-Regular.woff2 new file mode 100644 index 00000000..735f6948 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Fraktur-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Bold.ttf b/build-staging/katex/fonts/KaTeX_Main-Bold.ttf new file mode 100644 index 00000000..4060e627 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Bold.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Bold.woff b/build-staging/katex/fonts/KaTeX_Main-Bold.woff new file mode 100644 index 00000000..f38136ac Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Bold.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Bold.woff2 b/build-staging/katex/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 00000000..ab2ad21d Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Bold.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Main-BoldItalic.ttf b/build-staging/katex/fonts/KaTeX_Main-BoldItalic.ttf new file mode 100644 index 00000000..dc007977 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-BoldItalic.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Main-BoldItalic.woff b/build-staging/katex/fonts/KaTeX_Main-BoldItalic.woff new file mode 100644 index 00000000..67807b0b Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-BoldItalic.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Main-BoldItalic.woff2 b/build-staging/katex/fonts/KaTeX_Main-BoldItalic.woff2 new file mode 100644 index 00000000..5931794d Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-BoldItalic.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Italic.ttf b/build-staging/katex/fonts/KaTeX_Main-Italic.ttf new file mode 100644 index 00000000..0e9b0f35 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Italic.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Italic.woff b/build-staging/katex/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 00000000..6f43b594 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Italic.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Italic.woff2 b/build-staging/katex/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 00000000..b50920e1 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Italic.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Regular.ttf b/build-staging/katex/fonts/KaTeX_Main-Regular.ttf new file mode 100644 index 00000000..dd45e1ed Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Regular.woff b/build-staging/katex/fonts/KaTeX_Main-Regular.woff new file mode 100644 index 00000000..21f58129 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Main-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 00000000..eb24a7ba Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Main-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Math-BoldItalic.ttf b/build-staging/katex/fonts/KaTeX_Math-BoldItalic.ttf new file mode 100644 index 00000000..728ce7a1 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Math-BoldItalic.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Math-BoldItalic.woff b/build-staging/katex/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 00000000..0ae390d7 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Math-BoldItalic.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/build-staging/katex/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 00000000..29657023 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Math-BoldItalic.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Math-Italic.ttf b/build-staging/katex/fonts/KaTeX_Math-Italic.ttf new file mode 100644 index 00000000..70d559b4 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Math-Italic.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Math-Italic.woff b/build-staging/katex/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 00000000..eb5159d4 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Math-Italic.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Math-Italic.woff2 b/build-staging/katex/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 00000000..215c143f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Math-Italic.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Bold.ttf b/build-staging/katex/fonts/KaTeX_SansSerif-Bold.ttf new file mode 100644 index 00000000..2f65a8a3 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Bold.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Bold.woff b/build-staging/katex/fonts/KaTeX_SansSerif-Bold.woff new file mode 100644 index 00000000..8d47c02d Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Bold.woff differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/build-staging/katex/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 00000000..cfaa3bda Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Bold.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Italic.ttf b/build-staging/katex/fonts/KaTeX_SansSerif-Italic.ttf new file mode 100644 index 00000000..d5850df9 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Italic.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Italic.woff b/build-staging/katex/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 00000000..7e02df96 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Italic.woff differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Italic.woff2 b/build-staging/katex/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 00000000..349c06dc Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Italic.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Regular.ttf b/build-staging/katex/fonts/KaTeX_SansSerif-Regular.ttf new file mode 100644 index 00000000..537279f6 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Regular.woff b/build-staging/katex/fonts/KaTeX_SansSerif-Regular.woff new file mode 100644 index 00000000..31b84829 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/build-staging/katex/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 00000000..a90eea85 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_SansSerif-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Script-Regular.ttf b/build-staging/katex/fonts/KaTeX_Script-Regular.ttf new file mode 100644 index 00000000..fd679bf3 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Script-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Script-Regular.woff b/build-staging/katex/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 00000000..0e7da821 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Script-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Script-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 00000000..b3048fc1 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Script-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Size1-Regular.ttf b/build-staging/katex/fonts/KaTeX_Size1-Regular.ttf new file mode 100644 index 00000000..871fd7d1 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size1-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Size1-Regular.woff b/build-staging/katex/fonts/KaTeX_Size1-Regular.woff new file mode 100644 index 00000000..7f292d91 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size1-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Size1-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 00000000..c5a8462f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size1-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Size2-Regular.ttf b/build-staging/katex/fonts/KaTeX_Size2-Regular.ttf new file mode 100644 index 00000000..7a212caf Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size2-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Size2-Regular.woff b/build-staging/katex/fonts/KaTeX_Size2-Regular.woff new file mode 100644 index 00000000..d241d9be Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size2-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Size2-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 00000000..e1bccfe2 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size2-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Size3-Regular.ttf b/build-staging/katex/fonts/KaTeX_Size3-Regular.ttf new file mode 100644 index 00000000..00bff349 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size3-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Size3-Regular.woff b/build-staging/katex/fonts/KaTeX_Size3-Regular.woff new file mode 100644 index 00000000..e6e9b658 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size3-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Size3-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Size3-Regular.woff2 new file mode 100644 index 00000000..249a2866 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size3-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Size4-Regular.ttf b/build-staging/katex/fonts/KaTeX_Size4-Regular.ttf new file mode 100644 index 00000000..74f08921 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size4-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Size4-Regular.woff b/build-staging/katex/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 00000000..e1ec5457 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size4-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Size4-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 00000000..680c1308 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Size4-Regular.woff2 differ diff --git a/build-staging/katex/fonts/KaTeX_Typewriter-Regular.ttf b/build-staging/katex/fonts/KaTeX_Typewriter-Regular.ttf new file mode 100644 index 00000000..c83252c5 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Typewriter-Regular.ttf differ diff --git a/build-staging/katex/fonts/KaTeX_Typewriter-Regular.woff b/build-staging/katex/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 00000000..2432419f Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Typewriter-Regular.woff differ diff --git a/build-staging/katex/fonts/KaTeX_Typewriter-Regular.woff2 b/build-staging/katex/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 00000000..771f1af7 Binary files /dev/null and b/build-staging/katex/fonts/KaTeX_Typewriter-Regular.woff2 differ diff --git a/build-staging/katex/katex.min.css b/build-staging/katex/katex.min.css new file mode 100644 index 00000000..f7ebca1f --- /dev/null +++ b/build-staging/katex/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.13.24"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/build-staging/katex/katex.min.js b/build-staging/katex/katex.min.js new file mode 100644 index 00000000..2d04ed3b --- /dev/null +++ b/build-staging/katex/katex.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return _n}});var r=function e(t,r){this.position=void 0;var n,a="KaTeX parse error: "+t,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;n=i.start;var s=i.end;n===o.length?a+=" at end of input: ":a+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332");a+=(n>15?"\u2026"+o.slice(n-15,n):o.slice(0,n))+l+(s+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;var s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(o,(function(e){return i[e]}))},hyphenate:function(e){return e.replace(a,"-$1").toLowerCase()},getBaseElem:s,isCharacterBox:function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"}},h=function(){function e(e){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},this.displayMode=l.deflt(e.displayMode,!1),this.output=l.deflt(e.output,"htmlAndMathml"),this.leqno=l.deflt(e.leqno,!1),this.fleqn=l.deflt(e.fleqn,!1),this.throwOnError=l.deflt(e.throwOnError,!0),this.errorColor=l.deflt(e.errorColor,"#cc0000"),this.macros=e.macros||{},this.minRuleThickness=Math.max(0,l.deflt(e.minRuleThickness,0)),this.colorIsTextColor=l.deflt(e.colorIsTextColor,!1),this.strict=l.deflt(e.strict,"warn"),this.trust=l.deflt(e.trust,!1),this.maxSize=Math.max(0,l.deflt(e.maxSize,1/0)),this.maxExpand=Math.max(0,l.deflt(e.maxExpand,1e3)),this.globalGroup=l.deflt(e.globalGroup,!1)}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=l.protocolFromUrl(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),m=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return c[u[this.id]]},t.sub=function(){return c[p[this.id]]},t.fracNum=function(){return c[d[this.id]]},t.fracDen=function(){return c[f[this.id]]},t.cramp=function(){return c[g[this.id]]},t.text=function(){return c[v[this.id]]},t.isTight=function(){return this.size>=2},e}(),c=[new m(0,0,!1),new m(1,0,!0),new m(2,1,!1),new m(3,1,!0),new m(4,2,!1),new m(5,2,!0),new m(6,3,!1),new m(7,3,!0)],u=[4,5,4,5,6,7,6,7],p=[5,5,5,5,7,7,7,7],d=[2,3,4,5,6,7,6,7],f=[3,3,5,5,7,7,7,7],g=[1,1,3,3,5,5,7,7],v=[0,1,2,3,2,3,2,3],b={DISPLAY:c[0],TEXT:c[2],SCRIPT:c[4],SCRIPTSCRIPT:c[6]},y=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var x=[];function w(e){for(var t=0;t=x[t]&&e<=x[t+1])return!0;return!1}y.forEach((function(e){return e.blocks.forEach((function(e){return x.push.apply(x,e)}))}));var k=80,S={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},M=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=q[t]={cssEmPerMu:A.quad[t]/18};for(var n in A)A.hasOwnProperty(n)&&(r[n]=A[n][t])}return q[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();R.BASESIZE=6;var O=R,E={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},H={ex:!0,em:!0,mu:!0},L=function(e){return"string"!=typeof e&&(e=e.unit),e in E||e in H||"ex"===e},D=function(e,t){var r;if(e.unit in E)r=E[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},P=function(e){return+e.toFixed(4)+"em"},F=function(e){return e.filter((function(e){return e})).join(" ")},V=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},G=function(e){var t=document.createElement(e);for(var r in t.className=F(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},Y=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"span")},t.toMarkup=function(){return U.call(this,"span")},e}(),W=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,V.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return G.call(this,"a")},t.toMarkup=function(){return U.call(this,"a")},e}(),X=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+"=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=_[this.text])}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=P(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=F(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=l.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');var a=l.escape(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),$=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r":""},e}(),K=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e="","\\gt",!0),ne(ae,oe,ge,"\u2208","\\in",!0),ne(ae,oe,ge,"\ue020","\\@not"),ne(ae,oe,ge,"\u2282","\\subset",!0),ne(ae,oe,ge,"\u2283","\\supset",!0),ne(ae,oe,ge,"\u2286","\\subseteq",!0),ne(ae,oe,ge,"\u2287","\\supseteq",!0),ne(ae,se,ge,"\u2288","\\nsubseteq",!0),ne(ae,se,ge,"\u2289","\\nsupseteq",!0),ne(ae,oe,ge,"\u22a8","\\models"),ne(ae,oe,ge,"\u2190","\\leftarrow",!0),ne(ae,oe,ge,"\u2264","\\le"),ne(ae,oe,ge,"\u2264","\\leq",!0),ne(ae,oe,ge,"<","\\lt",!0),ne(ae,oe,ge,"\u2192","\\rightarrow",!0),ne(ae,oe,ge,"\u2192","\\to"),ne(ae,se,ge,"\u2271","\\ngeq",!0),ne(ae,se,ge,"\u2270","\\nleq",!0),ne(ae,oe,ve,"\xa0","\\ "),ne(ae,oe,ve,"\xa0","\\space"),ne(ae,oe,ve,"\xa0","\\nobreakspace"),ne(ie,oe,ve,"\xa0","\\ "),ne(ie,oe,ve,"\xa0"," "),ne(ie,oe,ve,"\xa0","\\space"),ne(ie,oe,ve,"\xa0","\\nobreakspace"),ne(ae,oe,ve,null,"\\nobreak"),ne(ae,oe,ve,null,"\\allowbreak"),ne(ae,oe,fe,",",","),ne(ae,oe,fe,";",";"),ne(ae,se,he,"\u22bc","\\barwedge",!0),ne(ae,se,he,"\u22bb","\\veebar",!0),ne(ae,oe,he,"\u2299","\\odot",!0),ne(ae,oe,he,"\u2295","\\oplus",!0),ne(ae,oe,he,"\u2297","\\otimes",!0),ne(ae,oe,be,"\u2202","\\partial",!0),ne(ae,oe,he,"\u2298","\\oslash",!0),ne(ae,se,he,"\u229a","\\circledcirc",!0),ne(ae,se,he,"\u22a1","\\boxdot",!0),ne(ae,oe,he,"\u25b3","\\bigtriangleup"),ne(ae,oe,he,"\u25bd","\\bigtriangledown"),ne(ae,oe,he,"\u2020","\\dagger"),ne(ae,oe,he,"\u22c4","\\diamond"),ne(ae,oe,he,"\u22c6","\\star"),ne(ae,oe,he,"\u25c3","\\triangleleft"),ne(ae,oe,he,"\u25b9","\\triangleright"),ne(ae,oe,de,"{","\\{"),ne(ie,oe,be,"{","\\{"),ne(ie,oe,be,"{","\\textbraceleft"),ne(ae,oe,me,"}","\\}"),ne(ie,oe,be,"}","\\}"),ne(ie,oe,be,"}","\\textbraceright"),ne(ae,oe,de,"{","\\lbrace"),ne(ae,oe,me,"}","\\rbrace"),ne(ae,oe,de,"[","\\lbrack",!0),ne(ie,oe,be,"[","\\lbrack",!0),ne(ae,oe,me,"]","\\rbrack",!0),ne(ie,oe,be,"]","\\rbrack",!0),ne(ae,oe,de,"(","\\lparen",!0),ne(ae,oe,me,")","\\rparen",!0),ne(ie,oe,be,"<","\\textless",!0),ne(ie,oe,be,">","\\textgreater",!0),ne(ae,oe,de,"\u230a","\\lfloor",!0),ne(ae,oe,me,"\u230b","\\rfloor",!0),ne(ae,oe,de,"\u2308","\\lceil",!0),ne(ae,oe,me,"\u2309","\\rceil",!0),ne(ae,oe,be,"\\","\\backslash"),ne(ae,oe,be,"\u2223","|"),ne(ae,oe,be,"\u2223","\\vert"),ne(ie,oe,be,"|","\\textbar",!0),ne(ae,oe,be,"\u2225","\\|"),ne(ae,oe,be,"\u2225","\\Vert"),ne(ie,oe,be,"\u2225","\\textbardbl"),ne(ie,oe,be,"~","\\textasciitilde"),ne(ie,oe,be,"\\","\\textbackslash"),ne(ie,oe,be,"^","\\textasciicircum"),ne(ae,oe,ge,"\u2191","\\uparrow",!0),ne(ae,oe,ge,"\u21d1","\\Uparrow",!0),ne(ae,oe,ge,"\u2193","\\downarrow",!0),ne(ae,oe,ge,"\u21d3","\\Downarrow",!0),ne(ae,oe,ge,"\u2195","\\updownarrow",!0),ne(ae,oe,ge,"\u21d5","\\Updownarrow",!0),ne(ae,oe,pe,"\u2210","\\coprod"),ne(ae,oe,pe,"\u22c1","\\bigvee"),ne(ae,oe,pe,"\u22c0","\\bigwedge"),ne(ae,oe,pe,"\u2a04","\\biguplus"),ne(ae,oe,pe,"\u22c2","\\bigcap"),ne(ae,oe,pe,"\u22c3","\\bigcup"),ne(ae,oe,pe,"\u222b","\\int"),ne(ae,oe,pe,"\u222b","\\intop"),ne(ae,oe,pe,"\u222c","\\iint"),ne(ae,oe,pe,"\u222d","\\iiint"),ne(ae,oe,pe,"\u220f","\\prod"),ne(ae,oe,pe,"\u2211","\\sum"),ne(ae,oe,pe,"\u2a02","\\bigotimes"),ne(ae,oe,pe,"\u2a01","\\bigoplus"),ne(ae,oe,pe,"\u2a00","\\bigodot"),ne(ae,oe,pe,"\u222e","\\oint"),ne(ae,oe,pe,"\u222f","\\oiint"),ne(ae,oe,pe,"\u2230","\\oiiint"),ne(ae,oe,pe,"\u2a06","\\bigsqcup"),ne(ae,oe,pe,"\u222b","\\smallint"),ne(ie,oe,ce,"\u2026","\\textellipsis"),ne(ae,oe,ce,"\u2026","\\mathellipsis"),ne(ie,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u2026","\\ldots",!0),ne(ae,oe,ce,"\u22ef","\\@cdots",!0),ne(ae,oe,ce,"\u22f1","\\ddots",!0),ne(ae,oe,be,"\u22ee","\\varvdots"),ne(ae,oe,le,"\u02ca","\\acute"),ne(ae,oe,le,"\u02cb","\\grave"),ne(ae,oe,le,"\xa8","\\ddot"),ne(ae,oe,le,"~","\\tilde"),ne(ae,oe,le,"\u02c9","\\bar"),ne(ae,oe,le,"\u02d8","\\breve"),ne(ae,oe,le,"\u02c7","\\check"),ne(ae,oe,le,"^","\\hat"),ne(ae,oe,le,"\u20d7","\\vec"),ne(ae,oe,le,"\u02d9","\\dot"),ne(ae,oe,le,"\u02da","\\mathring"),ne(ae,oe,ue,"\ue131","\\@imath"),ne(ae,oe,ue,"\ue237","\\@jmath"),ne(ae,oe,be,"\u0131","\u0131"),ne(ae,oe,be,"\u0237","\u0237"),ne(ie,oe,be,"\u0131","\\i",!0),ne(ie,oe,be,"\u0237","\\j",!0),ne(ie,oe,be,"\xdf","\\ss",!0),ne(ie,oe,be,"\xe6","\\ae",!0),ne(ie,oe,be,"\u0153","\\oe",!0),ne(ie,oe,be,"\xf8","\\o",!0),ne(ie,oe,be,"\xc6","\\AE",!0),ne(ie,oe,be,"\u0152","\\OE",!0),ne(ie,oe,be,"\xd8","\\O",!0),ne(ie,oe,le,"\u02ca","\\'"),ne(ie,oe,le,"\u02cb","\\`"),ne(ie,oe,le,"\u02c6","\\^"),ne(ie,oe,le,"\u02dc","\\~"),ne(ie,oe,le,"\u02c9","\\="),ne(ie,oe,le,"\u02d8","\\u"),ne(ie,oe,le,"\u02d9","\\."),ne(ie,oe,le,"\xb8","\\c"),ne(ie,oe,le,"\u02da","\\r"),ne(ie,oe,le,"\u02c7","\\v"),ne(ie,oe,le,"\xa8",'\\"'),ne(ie,oe,le,"\u02dd","\\H"),ne(ie,oe,le,"\u25ef","\\textcircled");var ye={"--":!0,"---":!0,"``":!0,"''":!0};ne(ie,oe,be,"\u2013","--",!0),ne(ie,oe,be,"\u2013","\\textendash"),ne(ie,oe,be,"\u2014","---",!0),ne(ie,oe,be,"\u2014","\\textemdash"),ne(ie,oe,be,"\u2018","`",!0),ne(ie,oe,be,"\u2018","\\textquoteleft"),ne(ie,oe,be,"\u2019","'",!0),ne(ie,oe,be,"\u2019","\\textquoteright"),ne(ie,oe,be,"\u201c","``",!0),ne(ie,oe,be,"\u201c","\\textquotedblleft"),ne(ie,oe,be,"\u201d","''",!0),ne(ie,oe,be,"\u201d","\\textquotedblright"),ne(ae,oe,be,"\xb0","\\degree",!0),ne(ie,oe,be,"\xb0","\\degree"),ne(ie,oe,be,"\xb0","\\textdegree",!0),ne(ae,oe,be,"\xa3","\\pounds"),ne(ae,oe,be,"\xa3","\\mathsterling",!0),ne(ie,oe,be,"\xa3","\\pounds"),ne(ie,oe,be,"\xa3","\\textsterling",!0),ne(ae,se,be,"\u2720","\\maltese"),ne(ie,se,be,"\u2720","\\maltese");for(var xe='0123456789/@."',we=0;wet&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Ue=function(e,t,r,n){var a=new Y(e,t,r,n);return Ge(a),a},Ye=function(e,t,r,n){return new Y(e,t,r,n)},We=function(e){var t=new M(e);return Ge(t),t},Xe=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},_e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},je={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},$e={fontMap:_e,makeSymbol:Fe,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Pe(e,"Main-Bold",t).metrics?Fe(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===re[t][e].font?Fe(e,"Main-Regular",t,r,n):Fe(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:Ue,makeSvgSpan:Ye,makeLineSpan:function(e,t,r){var n=Ue([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=P(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new W(e,t,r,n);return Ge(a),a},makeFragment:We,wrapFragment:function(e,t){return e instanceof M?Ue([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(xt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(xt(s,t)),r?((i=xt(pt(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var m=lt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=P(m.height+m.depth),m.depth&&(c.style.verticalAlign=P(-m.depth))}return m}function kt(e){return new M(e)}var St=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=F(this.classes));for(var r=0;r0&&(e+=' class ="'+l.escape(F(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),Mt=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return l.escape(this.toText())},t.toText=function(){return this.text},e}(),zt={MathNode:St,TextNode:Mt,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",P(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:kt},At=function(e,t,r){return!re[t][e]||!re[t][e].replace||55349===e.charCodeAt(0)||ye.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(e=re[t][e].replace),new zt.TextNode(e)},Tt=function(e){return 1===e.length?e[0]:new zt.MathNode("mrow",e)},Bt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l.contains(["\\imath","\\jmath"],a)?null:(re[n][a]&&re[n][a].replace&&(a=re[n][a].replace),B(a,$e.fontMap[r].fontName,n)?$e.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var n=Ct(e[0],t);return r&&n instanceof St&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},Nt=function(e,t,r){return Tt(qt(e,t,r))},Ct=function(e,t){if(!e)return new zt.MathNode("mrow");if(nt[e.type])return nt[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function It(e,t,r,n,a){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof St&&l.contains(["mrow","mtable"],o[0].type)?o[0]:new zt.MathNode("mrow",o);var s=new zt.MathNode("annotation",[new zt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new zt.MathNode("semantics",[i,s]),m=new zt.MathNode("math",[h]);m.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&m.setAttribute("display","block");var c=a?"katex":"katex-mathml";return $e.makeSpan([c],[m])}var Rt=function(e){return new O({style:e.displayMode?b.DISPLAY:b.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Ot=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=$e.makeSpan(r,[e])}return e},Et=function(e,t,r){var n,a=Rt(r);if("mathml"===r.output)return It(e,t,a,r.displayMode,!0);if("html"===r.output){var i=wt(e,a);n=$e.makeSpan(["katex"],[i])}else{var o=It(e,t,a,r.displayMode,!1),s=wt(e,a);n=$e.makeSpan(["katex"],[o,s])}return Ot(n,r)},Ht={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Lt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Dt=function(e,t,r,n,a){var i,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(i=$e.makeSpan(["stretchy",t],[],a),"fbox"===t){var s=a.color&&a.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new K({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new K({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new $(l,{width:"100%",height:P(o)});i=$e.makeSvgSpan([],[h],a)}return i.height=o,i.style.height=P(o),i},Pt=function(e){var t=new zt.MathNode("mo",[new zt.TextNode(Ht[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var r=function(){var r=4e5,n=e.label.substr(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var m=new Z(i),c=new $([m],{width:"100%",height:P(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:$e.makeSvgSpan([],[c],t),minWidth:0,height:o}}var u,p,d,f=[],g=Lt[n],v=g[0],b=g[1],y=g[2],x=y/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=P(a)),n};function Vt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Gt(e){var t=Ut(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Ut(e){return e&&("atom"===e.type||ee.hasOwnProperty(e.type))?e:null}var Yt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Vt(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof Y)return e;throw new Error("Expected span but got "+String(e)+".")}(yt(e,t)),e.base=n):r=(n=Vt(e,"accent")).base;var i=yt(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&l.isCharacterBox(r)){var s=l.getBaseElem(r);o=J(yt(s,t.havingCrampedStyle())).skew}var h,m="\\c"===n.label,c=m?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)h=Ft(n,t),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+P(2*o)+")",marginLeft:P(2*o)}:void 0}]},t);else{var u,p;"\\vec"===n.label?(u=$e.staticSvg("vec",t),p=$e.svgData.vec[1]):((u=J(u=$e.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,p=u.width,m&&(c+=u.depth)),h=$e.makeSpan(["accent-body"],[u]);var d="\\textcircled"===n.label;d&&(h.classes.push("accent-full"),c=i.height);var f=o;d||(f-=p/2),h.style.left=P(f),"\\textcircled"===n.label&&(h.style.top=".2em"),h=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}var g=$e.makeSpan(["mord","accent"],[h],t);return a?(a.children[0]=g,a.height=Math.max(g.height,a.height),a.classes[0]="mord",a):g},Wt=function(e,t){var r=e.isStretchy?Pt(e.label):new zt.MathNode("mo",[At(e.label,e.mode)]),n=new zt.MathNode("mover",[Ct(e.base,t),r]);return n.setAttribute("accent","true"),n},Xt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));at({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=ot(t[0]),n=!Xt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Yt,mathmlBuilder:Wt}),at({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=yt(e.base,t),n=Ft(e,t),a="\\utilde"===e.label?.12:0,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Pt(e.label),n=new zt.MathNode("munder",[Ct(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var _t=function(e){var t=new zt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};at({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=$e.wrapFragment(yt(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=$e.wrapFragment(yt(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),$e.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Pt(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=_t(Ct(e.body,t));if(e.below){var i=_t(Ct(e.below,t));r=new zt.MathNode("munderover",[n,i,a])}else r=new zt.MathNode("mover",[n,a])}else if(e.below){var o=_t(Ct(e.below,t));r=new zt.MathNode("munder",[n,o])}else r=_t(),r=new zt.MathNode("mover",[n,r]);return r}});var jt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},$t=function(e){return"textord"===e.type&&"@"===e.text};function Zt(e,t,r){var n=jt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}at({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=$e.wrapFragment(yt(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=P(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new zt.MathNode("mrow",[Ct(e.label,t)]);return(r=new zt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new zt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),at({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=$e.wrapFragment(yt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new zt.MathNode("mrow",[Ct(e.fragment,t)])}}),at({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Vt(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var Kt=function(e,t){var r=pt(e.body,t.withColor(e.color),!1);return $e.makeFragment(r)},Jt=function(e,t){var r=qt(e.body,t.withColor(e.color)),n=new zt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};at({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Vt(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:st(a)}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Vt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:Kt,mathmlBuilder:Jt}),at({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=r[0],i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Vt(a,"size").value}},htmlBuilder:function(e,t){var r=$e.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=P(D(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new zt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",P(D(e.size,t)))),r}});var Qt={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},er=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},tr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};at({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(Qt[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=Qt[a.text]),Vt(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),at({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===Qt[r]),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return tr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),at({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=er(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return tr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var rr=function(e,t,r){var n=B(re.math[e]&&re.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},nr=function(e,t,r,n){var a=r.havingBaseStyle(t),i=$e.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},ar=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=P(a),e.height-=a,e.depth+=a},ir=function(e,t,r,n,a,i){var o=function(e,t,r,n){return $e.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=nr($e.makeSpan(["delimsizing","size"+t],[o],n),b.TEXT,n,i);return r&&ar(s,n,b.TEXT),s},or=function(e,t,r){var n;return n="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:$e.makeSpan(["delimsizinginner",n],[$e.makeSpan([],[$e.makeSymbol(e,t,r)])])}},sr=function(e,t,r){var n=z["Size4-Regular"][e.charCodeAt(0)]?z["Size4-Regular"][e.charCodeAt(0)][4]:z["Size1-Regular"][e.charCodeAt(0)][4],a=new Z("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new $([a],{width:P(n),height:P(t),style:"width:"+P(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=$e.makeSvgSpan([],[i],r);return o.height=t,o.style.height=P(t),o.style.width=P(n),{type:"elem",elem:o}},lr={type:"kern",size:-.008},hr=["|","\\lvert","\\rvert","\\vert"],mr=["\\|","\\lVert","\\rVert","\\Vert"],cr=function(e,t,r,n,a,i){var o,s,h,m;o=h=m=e,s=null;var c="Size1-Regular";"\\uparrow"===e?h=m="\u23d0":"\\Uparrow"===e?h=m="\u2016":"\\downarrow"===e?o=h="\u23d0":"\\Downarrow"===e?o=h="\u2016":"\\updownarrow"===e?(o="\\uparrow",h="\u23d0",m="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="\u2016",m="\\Downarrow"):l.contains(hr,e)?h="\u2223":l.contains(mr,e)?h="\u2225":"["===e||"\\lbrack"===e?(o="\u23a1",h="\u23a2",m="\u23a3",c="Size4-Regular"):"]"===e||"\\rbrack"===e?(o="\u23a4",h="\u23a5",m="\u23a6",c="Size4-Regular"):"\\lfloor"===e||"\u230a"===e?(h=o="\u23a2",m="\u23a3",c="Size4-Regular"):"\\lceil"===e||"\u2308"===e?(o="\u23a1",h=m="\u23a2",c="Size4-Regular"):"\\rfloor"===e||"\u230b"===e?(h=o="\u23a5",m="\u23a6",c="Size4-Regular"):"\\rceil"===e||"\u2309"===e?(o="\u23a4",h=m="\u23a5",c="Size4-Regular"):"("===e||"\\lparen"===e?(o="\u239b",h="\u239c",m="\u239d",c="Size4-Regular"):")"===e||"\\rparen"===e?(o="\u239e",h="\u239f",m="\u23a0",c="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",m="\u23a9",h="\u23aa",c="Size4-Regular");var u=rr(o,c,a),p=u.height+u.depth,d=rr(h,c,a),f=d.height+d.depth,g=rr(m,c,a),v=g.height+g.depth,y=0,x=1;if(null!==s){var w=rr(s,c,a);y=w.height+w.depth,x=2}var k=p+v+y,S=k+Math.max(0,Math.ceil((t-k)/(x*f)))*x*f,M=n.fontMetrics().axisHeight;r&&(M*=n.sizeMultiplier);var z=S/2-M,A=[];if(A.push(or(m,c,a)),A.push(lr),null===s){var T=S-p-v+.016;A.push(sr(h,T,n))}else{var B=(S-p-v-y)/2+.016;A.push(sr(h,B,n)),A.push(lr),A.push(or(s,c,a)),A.push(lr),A.push(sr(h,B,n))}A.push(lr),A.push(or(o,c,a));var q=n.havingBaseStyle(b.TEXT),N=$e.makeVList({positionType:"bottom",positionData:z,children:A},q);return nr($e.makeSpan(["delimsizing","mult"],[N],q),b.TEXT,n,i)},ur=.08,pr=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,k);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,k);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,k,r)}return n}(e,n,r),o=new Z(e,i),s=new $([o],{width:"400em",height:P(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return $e.makeSvgSpan(["hide-tail"],[s],a)},dr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],fr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],gr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],vr=[0,1.2,1.8,2.4,3],br=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],yr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"stack"}],xr=[{type:"small",style:b.SCRIPTSCRIPT},{type:"small",style:b.SCRIPT},{type:"small",style:b.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],wr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},kr=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},Sr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=l.contains(gr,e)?br:l.contains(dr,e)?xr:yr;var s=kr(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=$e.makeSymbol(e,"Main-Regular",a,n),s=nr(o,t,n,i);return r&&ar(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?ir(e,s.size,r,n,a,i):cr(e,t,r,n,a,i)},Mr={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=kr("\\surd",e*a.sizeMultiplier,xr,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=pr("sqrtMain",l=(1+s+ur)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(m=1080*vr[i.size],h=(vr[i.size]+s)/o,l=(vr[i.size]+s+ur)/o,(r=pr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+ur,h=e+s,m=Math.floor(1e3*e+s)+80,(r=pr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=P(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(dr,e)||l.contains(gr,e))return ir(e,t,!1,r,a,i);if(l.contains(fr,e))return cr(e,vr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:vr,customSizedDelim:Sr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Sr(e,h,!0,n,a,i)}},zr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Ar=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Tr(e,t){var r=Ut(e);if(r&&l.contains(Ar,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Br(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}at({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Tr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:zr[e.funcName].size,mclass:zr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?$e.makeSpan([e.mclass]):Mr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(At(e.delim,e.mode));var r=new zt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=P(Mr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),at({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Tr(t[0],e).text,color:r}}}),at({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Tr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Vt(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){Br(e);for(var r,n,a=pt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Ct(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};at({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Vt(t[0],"color-token").color,o=Vt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),at({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:qr,mathmlBuilder:Nr}),at({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Cr={};function Ir(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!c)&&g.pop(),b.length0&&(x+=.25),m.push({pos:x,isDashed:e[t]})}for(w(o[0]),r=0;r0&&(M<(B+=y)&&(M=B),B=0),e.addJot&&(M+=f),z.height=S,z.depth=M,x+=S,z.pos=x,x+=M+B,h[r]=z,w(o[r+1])}var q,N,C=x/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],O=[];if(e.addEqnNum)for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=l.deflt(F.pregap,p))&&((q=$e.makeSpan(["arraycolsep"],[])).style.width=P(W),R.push(q));var X=[];for(r=0;r0){for(var Z=$e.makeLineSpan("hline",t,c),K=$e.makeLineSpan("hdashline",t,c),J=[{type:"elem",elem:h,shift:0}];m.length>0;){var Q=m.pop(),ee=Q.pos-C;Q.isDashed?J.push({type:"elem",elem:K,shift:ee}):J.push({type:"elem",elem:Z,shift:ee})}h=$e.makeVList({positionType:"individualShift",children:J},t)}if(e.addEqnNum){var te=$e.makeVList({positionType:"individualShift",children:O},t);return te=$e.makeSpan(["tag"],[te],t),$e.makeFragment([h,te])}return $e.makeSpan(["mord"],[h],t)},Dr={c:"center ",l:"left ",r:"right "},Pr=function(e,t){for(var r=[],n=new zt.MathNode("mtd",[],["mtr-glue"]),a=new zt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(c+="top ",g=1),"separator"===p[p.length-1].type&&(c+="bottom ",v-=1);for(var b=g;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o=Er(e.parser,{cols:a,addJot:!0,addEqnNum:"align"===e.envName||"alignat"===e.envName,emptySingleRow:!0,colSeparationType:i,maxNumCols:"split"===e.envName?2:void 0,leqno:e.parser.settings.leqno},"display"),s=0,l={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var h="",m=0;m0&&c&&(d=1),a[u]={type:"align",align:p,pregap:d,postgap:0}}return o.colSeparationType=c?"align":"alignat",o};Ir({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Er(e.parser,a,Hr(e.envName))},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Er(e.parser,a,Hr(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Ut(t[0])?[t[0]]:Vt(t[0],"ordgroup").body).map((function(e){var t=Gt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Er(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Er(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Hr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l.contains(["gather","gather*"],e.envName)&&Or(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",addEqnNum:"gather"===e.envName,emptySingleRow:!0,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Fr,htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Or(e);var t={addEqnNum:"equation"===e.envName,emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Er(e.parser,t,"display")},htmlBuilder:Lr,mathmlBuilder:Pr}),Ir({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Or(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var f=!0,g=c+1;g=b.SCRIPT.id?r.text():b.DISPLAY:"text"===e&&r.size===b.DISPLAY.size?r=b.TEXT:"script"===e?r=b.SCRIPT:"scriptscript"===e&&(r=b.SCRIPTSCRIPT),r},Zr=function(e,t){var r,n=$r(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=yt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(u=t.fontMetrics().num2,p=c):(u=t.fontMetrics().num3,p=3*c),d=t.fontMetrics().denom2),h){var w=t.fontMetrics().axisHeight;u-o.depth-(w+.5*m)0&&(t="."===(t=e)?null:t),t};at({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=ot(t[0]),s="atom"===o.type&&"open"===o.family?Qr(o.text):null,l=ot(t[1]),h="atom"===l.type&&"close"===l.family?Qr(l.text):null,m=Vt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Vt(p.body[0],"textord");u=Jr[Number(d.text)]}}else p=Vt(p,"textord"),u=Jr[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:Zr,mathmlBuilder:Kr}),at({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Vt(t[0],"size").value,token:n}}}),at({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Vt(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Zr,mathmlBuilder:Kr});var en=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?yt(e.sup,t.havingStyle(a.sup()),t):yt(e.sub,t.havingStyle(a.sub()),t),n=Vt(e.base,"horizBrace")):n=Vt(e,"horizBrace");var i,o=yt(n.base,t.havingBaseStyle(b.DISPLAY)),s=Ft(n,t);if(n.isOver?(i=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=$e.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=$e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):$e.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return $e.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};at({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:en,mathmlBuilder:function(e,t){var r=Pt(e.label);return new zt.MathNode(e.isOver?"mover":"munder",[Ct(e.base,t),r])}}),at({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Vt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:st(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=pt(e.body,t,!1);return $e.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=Nt(e.body,t);return r instanceof St||(r=new St("mrow",[r])),r.setAttribute("href",e.href),r}}),at({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Vt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=D(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=D(e.width,t));var i={height:P(r+n)};a>0&&(i.width=P(a)),n>0&&(i.verticalAlign=P(-n));var o=new X(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new zt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=D(e.height,t),a=0;if(e.totalheight.number>0&&(a=D(e.totalheight,t)-n,r.setAttribute("valign",P(-a))),r.setAttribute("height",P(n+a)),e.width.number>0){var i=D(e.width,t);r.setAttribute("width",P(i))}return r.setAttribute("src",e.src),r}}),at({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Vt(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return $e.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=D(e.dimension,t);return new zt.SpaceNode(r)}}),at({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=$e.makeSpan([],[yt(e.body,t)]),r=$e.makeSpan(["inner"],[r],t)):r=$e.makeSpan(["inner"],[yt(e.body,t)]);var n=$e.makeSpan(["fix"],[]),a=$e.makeSpan([e.alignment],[r,n],t),i=$e.makeSpan(["strut"]);return i.style.height=P(a.height+a.depth),a.depth&&(i.style.verticalAlign=P(-a.depth)),a.children.unshift(i),a=$e.makeSpan(["thinbox"],[a],t),$e.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mpadded",[Ct(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),at({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),at({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var rn=function(e,t){switch(t.style.size){case b.DISPLAY.size:return e.display;case b.TEXT.size:return e.text;case b.SCRIPT.size:return e.script;case b.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};at({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:st(t[0]),text:st(t[1]),script:st(t[2]),scriptscript:st(t[3])}},htmlBuilder:function(e,t){var r=rn(e,t),n=pt(r,t,!1);return $e.makeFragment(n)},mathmlBuilder:function(e,t){var r=rn(e,t);return Nt(r,t)}});var nn=function(e,t,r,n,a,i,o){e=$e.makeSpan([],[e]);var s,h,m,c=r&&l.isCharacterBox(r);if(t){var u=yt(t,n.havingStyle(a.sup()),n);h={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-u.depth)}}if(r){var p=yt(r,n.havingStyle(a.sub()),n);s={elem:p,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-p.height)}}if(h&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;m=$e.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:P(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!h)return e;var g=e.depth+o;m=$e.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:P(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[m];if(s&&0!==i&&!c){var b=$e.makeSpan(["mspace"],[],n);b.style.marginRight=P(i),v.unshift(b)}return $e.makeSpan(["mop","op-limits"],v,n)},an=["\\smallint"],on=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Vt(e.base,"op"),i=!0):a=Vt(e,"op");var o,s=t.style,h=!1;if(s.size===b.DISPLAY.size&&a.symbol&&!l.contains(an,a.name)&&(h=!0),a.symbol){var m=h?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(c=a.name.substr(1),a.name="oiint"===c?"\\iint":"\\iiint"),o=$e.makeSymbol(a.name,m,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),c.length>0){var u=o.italic,p=$e.staticSvg(c+"Size"+(h?"2":"1"),t);o=$e.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+c,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=pt(a.body,t,!0);1===d.length&&d[0]instanceof j?(o=d[0]).classes[0]="mop":o=$e.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=pt(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",P(a)):(s.setAttribute("height",P(a)),s.setAttribute("depth",P(-a))),s.setAttribute("voffset",P(a)),s}});var dn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];at({type:"sizing",names:dn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:dn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return pn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=qt(e.body,r),a=new zt.MathNode("mstyle",n);return a.setAttribute("mathsize",P(r.sizeMultiplier)),a}}),at({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Vt(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=P(m);var p=$e.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(b.SCRIPTSCRIPT),f=yt(e.index,d,t),g=.6*(p.height-p.depth),v=$e.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),y=$e.makeSpan(["root"],[v]);return $e.makeSpan(["mord","sqrt"],[y,p],t)}return $e.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new zt.MathNode("mroot",[Ct(r,t),Ct(n,t)]):new zt.MathNode("msqrt",[Ct(r,t)])}});var fn={display:b.DISPLAY,text:b.TEXT,script:b.SCRIPT,scriptscript:b.SCRIPTSCRIPT};at({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r).withFont("");return pn(e.body,n,t)},mathmlBuilder:function(e,t){var r=fn[e.style],n=t.havingStyle(r),a=qt(e.body,n),i=new zt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});var gn=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===b.DISPLAY.size||r.alwaysHandleSupSub)?on:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===b.DISPLAY.size||r.limits)?un:null:"accent"===r.type?l.isCharacterBox(r.base)?Yt:null:"horizBrace"===r.type&&!e.sub===r.isOver?en:null:null};it({type:"supsub",htmlBuilder:function(e,t){var r=gn(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,h=e.sub,m=yt(o,t),c=t.fontMetrics(),u=0,p=0,d=o&&l.isCharacterBox(o);if(s){var f=t.havingStyle(t.style.sup());n=yt(s,f,t),d||(u=m.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(h){var g=t.havingStyle(t.style.sub());a=yt(h,g,t),d||(p=m.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===b.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,y=t.sizeMultiplier,x=P(.5/c.ptPerEm/y),w=null;if(a){var k=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(m instanceof j||k)&&(w=P(-m.italic))}if(n&&a){u=Math.max(u,i,n.depth+.25*c.xHeight),p=Math.max(p,c.sub2);var S=4*c.defaultRuleThickness;if(u-n.depth-(a.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:a,shift:p,marginRight:x,marginLeft:w},{type:"elem",elem:n,shift:-u,marginRight:x}];v=$e.makeVList({positionType:"individualShift",children:z},t)}else if(a){p=Math.max(p,c.sub1,a.height-.8*c.xHeight);var A=[{type:"elem",elem:a,marginLeft:w,marginRight:x}];v=$e.makeVList({positionType:"shift",positionData:p,children:A},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,n.depth+.25*c.xHeight),v=$e.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:n,marginRight:x}]},t)}var T=vt(m,"right")||"mord";return $e.makeSpan([T],[m,$e.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Ct(e.base,t)];if(e.sub&&i.push(Ct(e.sub,t)),e.sup&&i.push(Ct(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===b.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===b.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===b.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===b.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===b.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===b.DISPLAY)?"mover":"msup"}return new zt.MathNode(a,i)}}),it({type:"atom",htmlBuilder:function(e,t){return $e.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[At(e.text,e.mode)]);if("bin"===e.family){var n=Bt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var vn={mi:"italic",mn:"normal",mtext:"normal"};it({type:"mathord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new zt.MathNode("mi",[At(e.text,e.mode,t)]),n=Bt(e,t)||"italic";return n!==vn[r.type]&&r.setAttribute("mathvariant",n),r}}),it({type:"textord",htmlBuilder:function(e,t){return $e.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=At(e.text,e.mode,t),a=Bt(e,t)||"normal";return r="text"===e.mode?new zt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new zt.MathNode("mn",[n]):"\\prime"===e.text?new zt.MathNode("mo",[n]):new zt.MathNode("mi",[n]),a!==vn[r.type]&&r.setAttribute("mathvariant",a),r}});var bn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},yn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};it({type:"spacing",htmlBuilder:function(e,t){if(yn.hasOwnProperty(e.text)){var r=yn[e.text].className||"";if("text"===e.mode){var a=$e.makeOrd(e,t,"textord");return a.classes.push(r),a}return $e.makeSpan(["mspace",r],[$e.mathsym(e.text,e.mode,t)],t)}if(bn.hasOwnProperty(e.text))return $e.makeSpan(["mspace",bn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!yn.hasOwnProperty(e.text)){if(bn.hasOwnProperty(e.text))return new zt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new zt.MathNode("mtext",[new zt.TextNode("\xa0")])}});var xn=function(){var e=new zt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};it({type:"tag",mathmlBuilder:function(e,t){var r=new zt.MathNode("mtable",[new zt.MathNode("mtr",[xn(),new zt.MathNode("mtd",[Nt(e.body,t)]),xn(),new zt.MathNode("mtd",[Nt(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},kn={"\\textbf":"textbf","\\textmd":"textmd"},Sn={"\\textit":"textit","\\textup":"textup"},Mn=function(e,t){var r=e.font;return r?wn[r]?t.withTextFontFamily(wn[r]):kn[r]?t.withTextFontWeight(kn[r]):t.withTextFontShape(Sn[r]):t};at({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:st(a),font:n}},htmlBuilder:function(e,t){var r=Mn(e,t),n=pt(e.body,r,!0);return $e.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Mn(e,t);return Nt(e.body,r)}}),at({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=$e.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=$e.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return $e.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new zt.MathNode("mo",[new zt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var n=new zt.MathNode("munder",[Ct(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),at({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=yt(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return $e.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new zt.MathNode("mpadded",[Ct(e.body,t)],["vcenter"])}}),at({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=zn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}this.current[e]=t},e}(),In=mn;cn("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),cn("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),cn("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),cn("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),cn("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),cn("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),cn("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Rn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};cn("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Rn[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=Rn[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};cn("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in En?t=En[r]:("\\not"===r.substr(0,4)||r in re.math&&l.contains(["bin","rel"],re.math[r].group))&&(t="\\dotsb"),t}));var Hn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};cn("\\dotso",(function(e){return e.future().text in Hn?"\\ldots\\,":"\\ldots"})),cn("\\dotsc",(function(e){var t=e.future().text;return t in Hn&&","!==t?"\\ldots\\,":"\\ldots"})),cn("\\cdots",(function(e){return e.future().text in Hn?"\\@cdots\\,":"\\@cdots"})),cn("\\dotsb","\\cdots"),cn("\\dotsm","\\cdots"),cn("\\dotsi","\\!\\cdots"),cn("\\dotsx","\\ldots\\,"),cn("\\DOTSI","\\relax"),cn("\\DOTSB","\\relax"),cn("\\DOTSX","\\relax"),cn("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),cn("\\,","\\tmspace+{3mu}{.1667em}"),cn("\\thinspace","\\,"),cn("\\>","\\mskip{4mu}"),cn("\\:","\\tmspace+{4mu}{.2222em}"),cn("\\medspace","\\:"),cn("\\;","\\tmspace+{5mu}{.2777em}"),cn("\\thickspace","\\;"),cn("\\!","\\tmspace-{3mu}{.1667em}"),cn("\\negthinspace","\\!"),cn("\\negmedspace","\\tmspace-{4mu}{.2222em}"),cn("\\negthickspace","\\tmspace-{5mu}{.277em}"),cn("\\enspace","\\kern.5em "),cn("\\enskip","\\hskip.5em\\relax"),cn("\\quad","\\hskip1em\\relax"),cn("\\qquad","\\hskip2em\\relax"),cn("\\tag","\\@ifstar\\tag@literal\\tag@paren"),cn("\\tag@paren","\\tag@literal{({#1})}"),cn("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),cn("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),cn("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),cn("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),cn("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),cn("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),cn("\\newline","\\\\\\relax"),cn("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Ln=P(z["Main-Regular"]["T".charCodeAt(0)][1]-.7*z["Main-Regular"]["A".charCodeAt(0)][1]);cn("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),cn("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Ln+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),cn("\\hspace","\\@ifstar\\@hspacer\\@hspace"),cn("\\@hspace","\\hskip #1\\relax"),cn("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),cn("\\ordinarycolon",":"),cn("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),cn("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),cn("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),cn("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),cn("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),cn("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),cn("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),cn("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),cn("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),cn("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),cn("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),cn("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),cn("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),cn("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),cn("\u2237","\\dblcolon"),cn("\u2239","\\eqcolon"),cn("\u2254","\\coloneqq"),cn("\u2255","\\eqqcolon"),cn("\u2a74","\\Coloneqq"),cn("\\ratio","\\vcentcolon"),cn("\\coloncolon","\\dblcolon"),cn("\\colonequals","\\coloneqq"),cn("\\coloncolonequals","\\Coloneqq"),cn("\\equalscolon","\\eqqcolon"),cn("\\equalscoloncolon","\\Eqqcolon"),cn("\\colonminus","\\coloneq"),cn("\\coloncolonminus","\\Coloneq"),cn("\\minuscolon","\\eqcolon"),cn("\\minuscoloncolon","\\Eqcolon"),cn("\\coloncolonapprox","\\Colonapprox"),cn("\\coloncolonsim","\\Colonsim"),cn("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),cn("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),cn("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),cn("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),cn("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),cn("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),cn("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),cn("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),cn("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),cn("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),cn("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),cn("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),cn("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),cn("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),cn("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),cn("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),cn("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),cn("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),cn("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),cn("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),cn("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),cn("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),cn("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),cn("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),cn("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),cn("\\imath","\\html@mathml{\\@imath}{\u0131}"),cn("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),cn("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),cn("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),cn("\u27e6","\\llbracket"),cn("\u27e7","\\rrbracket"),cn("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),cn("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),cn("\u2983","\\lBrace"),cn("\u2984","\\rBrace"),cn("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),cn("\u29b5","\\minuso"),cn("\\darr","\\downarrow"),cn("\\dArr","\\Downarrow"),cn("\\Darr","\\Downarrow"),cn("\\lang","\\langle"),cn("\\rang","\\rangle"),cn("\\uarr","\\uparrow"),cn("\\uArr","\\Uparrow"),cn("\\Uarr","\\Uparrow"),cn("\\N","\\mathbb{N}"),cn("\\R","\\mathbb{R}"),cn("\\Z","\\mathbb{Z}"),cn("\\alef","\\aleph"),cn("\\alefsym","\\aleph"),cn("\\Alpha","\\mathrm{A}"),cn("\\Beta","\\mathrm{B}"),cn("\\bull","\\bullet"),cn("\\Chi","\\mathrm{X}"),cn("\\clubs","\\clubsuit"),cn("\\cnums","\\mathbb{C}"),cn("\\Complex","\\mathbb{C}"),cn("\\Dagger","\\ddagger"),cn("\\diamonds","\\diamondsuit"),cn("\\empty","\\emptyset"),cn("\\Epsilon","\\mathrm{E}"),cn("\\Eta","\\mathrm{H}"),cn("\\exist","\\exists"),cn("\\harr","\\leftrightarrow"),cn("\\hArr","\\Leftrightarrow"),cn("\\Harr","\\Leftrightarrow"),cn("\\hearts","\\heartsuit"),cn("\\image","\\Im"),cn("\\infin","\\infty"),cn("\\Iota","\\mathrm{I}"),cn("\\isin","\\in"),cn("\\Kappa","\\mathrm{K}"),cn("\\larr","\\leftarrow"),cn("\\lArr","\\Leftarrow"),cn("\\Larr","\\Leftarrow"),cn("\\lrarr","\\leftrightarrow"),cn("\\lrArr","\\Leftrightarrow"),cn("\\Lrarr","\\Leftrightarrow"),cn("\\Mu","\\mathrm{M}"),cn("\\natnums","\\mathbb{N}"),cn("\\Nu","\\mathrm{N}"),cn("\\Omicron","\\mathrm{O}"),cn("\\plusmn","\\pm"),cn("\\rarr","\\rightarrow"),cn("\\rArr","\\Rightarrow"),cn("\\Rarr","\\Rightarrow"),cn("\\real","\\Re"),cn("\\reals","\\mathbb{R}"),cn("\\Reals","\\mathbb{R}"),cn("\\Rho","\\mathrm{P}"),cn("\\sdot","\\cdot"),cn("\\sect","\\S"),cn("\\spades","\\spadesuit"),cn("\\sub","\\subset"),cn("\\sube","\\subseteq"),cn("\\supe","\\supseteq"),cn("\\Tau","\\mathrm{T}"),cn("\\thetasym","\\vartheta"),cn("\\weierp","\\wp"),cn("\\Zeta","\\mathrm{Z}"),cn("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),cn("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),cn("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),cn("\\bra","\\mathinner{\\langle{#1}|}"),cn("\\ket","\\mathinner{|{#1}\\rangle}"),cn("\\braket","\\mathinner{\\langle{#1}\\rangle}"),cn("\\Bra","\\left\\langle#1\\right|"),cn("\\Ket","\\left|#1\\right\\rangle"),cn("\\angln","{\\angl n}"),cn("\\blue","\\textcolor{##6495ed}{#1}"),cn("\\orange","\\textcolor{##ffa500}{#1}"),cn("\\pink","\\textcolor{##ff00af}{#1}"),cn("\\red","\\textcolor{##df0030}{#1}"),cn("\\green","\\textcolor{##28ae7b}{#1}"),cn("\\gray","\\textcolor{gray}{#1}"),cn("\\purple","\\textcolor{##9d38bd}{#1}"),cn("\\blueA","\\textcolor{##ccfaff}{#1}"),cn("\\blueB","\\textcolor{##80f6ff}{#1}"),cn("\\blueC","\\textcolor{##63d9ea}{#1}"),cn("\\blueD","\\textcolor{##11accd}{#1}"),cn("\\blueE","\\textcolor{##0c7f99}{#1}"),cn("\\tealA","\\textcolor{##94fff5}{#1}"),cn("\\tealB","\\textcolor{##26edd5}{#1}"),cn("\\tealC","\\textcolor{##01d1c1}{#1}"),cn("\\tealD","\\textcolor{##01a995}{#1}"),cn("\\tealE","\\textcolor{##208170}{#1}"),cn("\\greenA","\\textcolor{##b6ffb0}{#1}"),cn("\\greenB","\\textcolor{##8af281}{#1}"),cn("\\greenC","\\textcolor{##74cf70}{#1}"),cn("\\greenD","\\textcolor{##1fab54}{#1}"),cn("\\greenE","\\textcolor{##0d923f}{#1}"),cn("\\goldA","\\textcolor{##ffd0a9}{#1}"),cn("\\goldB","\\textcolor{##ffbb71}{#1}"),cn("\\goldC","\\textcolor{##ff9c39}{#1}"),cn("\\goldD","\\textcolor{##e07d10}{#1}"),cn("\\goldE","\\textcolor{##a75a05}{#1}"),cn("\\redA","\\textcolor{##fca9a9}{#1}"),cn("\\redB","\\textcolor{##ff8482}{#1}"),cn("\\redC","\\textcolor{##f9685d}{#1}"),cn("\\redD","\\textcolor{##e84d39}{#1}"),cn("\\redE","\\textcolor{##bc2612}{#1}"),cn("\\maroonA","\\textcolor{##ffbde0}{#1}"),cn("\\maroonB","\\textcolor{##ff92c6}{#1}"),cn("\\maroonC","\\textcolor{##ed5fa6}{#1}"),cn("\\maroonD","\\textcolor{##ca337c}{#1}"),cn("\\maroonE","\\textcolor{##9e034e}{#1}"),cn("\\purpleA","\\textcolor{##ddd7ff}{#1}"),cn("\\purpleB","\\textcolor{##c6b9fc}{#1}"),cn("\\purpleC","\\textcolor{##aa87ff}{#1}"),cn("\\purpleD","\\textcolor{##7854ab}{#1}"),cn("\\purpleE","\\textcolor{##543b78}{#1}"),cn("\\mintA","\\textcolor{##f5f9e8}{#1}"),cn("\\mintB","\\textcolor{##edf2df}{#1}"),cn("\\mintC","\\textcolor{##e0e5cc}{#1}"),cn("\\grayA","\\textcolor{##f6f7f7}{#1}"),cn("\\grayB","\\textcolor{##f0f1f2}{#1}"),cn("\\grayC","\\textcolor{##e3e5e6}{#1}"),cn("\\grayD","\\textcolor{##d6d8da}{#1}"),cn("\\grayE","\\textcolor{##babec2}{#1}"),cn("\\grayF","\\textcolor{##888d93}{#1}"),cn("\\grayG","\\textcolor{##626569}{#1}"),cn("\\grayH","\\textcolor{##3b3e40}{#1}"),cn("\\grayI","\\textcolor{##21242c}{#1}"),cn("\\kaBlue","\\textcolor{##314453}{#1}"),cn("\\kaGreen","\\textcolor{##71B307}{#1}");var Dn={"\\relax":!0,"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Pn=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Cn(In,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new Nn(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Bn("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof Bn){if("\\relax"!==e.text&&!e.treatAsRelax)return this.stack.pop();this.stack.pop()}}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Bn(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof Bn&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new Nn(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||An.hasOwnProperty(e)||re.math.hasOwnProperty(e)||re.text.hasOwnProperty(e)||Dn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:An.hasOwnProperty(e)&&!An[e].primitive},e}(),Fn={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Vn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Gn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Pn(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&An[a.text]&&An[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=re[this.mode][t].group,h=Tn.range(e);if(Q.hasOwnProperty(l)){var m=l;s={type:"atom",mode:this.mode,family:m,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(w(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Tn.range(e),text:t}}if(this.consume(),o)for(var c=0;c + + + + +Connectivity & Tor | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/security/category/cwtch-components/index.html b/build-staging/security/category/cwtch-components/index.html new file mode 100644 index 00000000..f3c80456 --- /dev/null +++ b/build-staging/security/category/cwtch-components/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch Components | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/security/category/cwtch-ui/index.html b/build-staging/security/category/cwtch-ui/index.html new file mode 100644 index 00000000..8f6750d9 --- /dev/null +++ b/build-staging/security/category/cwtch-ui/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch UI | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/security/category/cwtch/index.html b/build-staging/security/category/cwtch/index.html new file mode 100644 index 00000000..96984560 --- /dev/null +++ b/build-staging/security/category/cwtch/index.html @@ -0,0 +1,24 @@ + + + + + +Cwtch | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/security/category/tapir/index.html b/build-staging/security/category/tapir/index.html new file mode 100644 index 00000000..9b2385be --- /dev/null +++ b/build-staging/security/category/tapir/index.html @@ -0,0 +1,24 @@ + + + + + +Tapir | The Cwtch Handbook + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build-staging/security/components/connectivity/intro/index.html b/build-staging/security/components/connectivity/intro/index.html new file mode 100644 index 00000000..04d8d972 --- /dev/null +++ b/build-staging/security/components/connectivity/intro/index.html @@ -0,0 +1,49 @@ + + + + + +Connectivity | The Cwtch Handbook + + + + + + + + + + + + +
+

Connectivity

Cwtch makes use of Tor Onion Services (v3) for all inter-node communication.

We provide the openprivacy/connectivity +package for managing the Tor daemon and setting up and tearing down onion +services through Tor.

Known Risks

Private Key Exposure to the Tor Process

Status: Partially Mitigated (Requires Physical Access or Privilege Escalation to +exploit)

We must pass the private key of any onion service we wish to set up to the +connectivity library, through the Listen interface (and thus to the Tor +process). This is one of the most critical areas that is outside of our +control. Any binding to a rouge tor process or binary will result in +compromise of the Onion private key.

Mitigations

Connectivity attempt to bind to the system-provided Tor process as the default, +only when it has been provided with an authentication token.

Otherwise connectivity always attempts to deploy its own Tor process +using a known +good binary packaged with the system (outside of the scope of the connectivity +package)

In the long term we hope an integrated library will become available and allow +direct management through an in-process interface to prevent the private key +from leaving the process boundary (or other alternative paths that allow us +to maintain full control over the private key in-memory.)

Tor Process Management

Status: Partially Mitigated (Requires Physical Access or Privilege +Escalation to exploit)

Many issues can arise from the management of a separate process, including the +need to restart, exit and otherwise ensure appropriate management.

The ACN +interface provides Restart, Close and GetBootstrapStatus interfaces to +allow applications to manage the underlying Tor process. In addition the SetStatusCallback +method can be used to allow an application to be notified when the status of +the Tor process changes.

However, if sufficiently-privileged users wish they can interfere with this +mechanism, and as such the Tor process is a more brittle component +interaction than others.

Testing Status

Current connectivity has limited unit testing capabilities and none of these +are run during pull requests or merges. There is no integration testing.

It is worth noting that connectivity is used by both Tapir and Cwtch in their +integration tests (and so despite the lack of package level testing, it is +exposed to system-wide test conditions)

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/cwtch/groups/index.html b/build-staging/security/components/cwtch/groups/index.html new file mode 100644 index 00000000..c73da898 --- /dev/null +++ b/build-staging/security/components/cwtch/groups/index.html @@ -0,0 +1,49 @@ + + + + + +Groups | The Cwtch Handbook + + + + + + + + + + + + +
+

Groups

For the most part the Cwtch risk model for groups is split into two distinct +profiles:

  • Groups made up of mutually trusted participants where peers are assumed +honest.
  • Groups consisting of strangers where peers are assumed to be potentially +malicious.

Most of the mitigations described in this section relate to the latter case, but +naturally also impact the former. Even if assumed honest peers later turn +malicious there are mechanisms that can detect such malice and prevent it from +happening in the future.

Risk Overview: Key Derivation

In the ideal case we would use a protocol like OTR, the limitations preventing +us from doing so right now are:

  • Offline messages are not guaranteed to reach all peers, and as such any +metadata relating to key material might get lost. We need a key derivation +process which is robust to missing messages or incomplete broadcast. +

Risk: Malicious Peer Leaks Group Key and/or Conversation

Status: Partially Mitigated (but impossible to mitigate fully)

Whether dealing with trusted smaller groups or partially-public larger groups +there is always the possibility that a malicious actor will leak group +messages.

We plan to make it easy for peers to fork groups to mitigate the +same key being used to encrypt lots of sensitive information and provide +some level of forward secrecy for past group conversations.

Risk: Active Attacks by Group Members

Status: Partially Mitigated

Group members, who have access to the key material of the group, can conspire +with a server or other group members to break transcript consistency.

While we cannot directly prevent censorship given this kind of active +collusion, we have a number of mechanisms in place that should reveal the +presence of censorship to honest members of the group.

Mitigations:

  • Because each message is signed by the peers public key, it should not be +possible (within the cryptographic assumptions of the underlying cryptography) +for one group member to imitate another.
  • Each message contains a unique identifier derived from the contents and the +previous message hash - making it impossible for collaborators to include +messages from non-colluding members without revealing an implicit message +chain (which if they were attempting to censor other messages would +reveal such censorship) +

Finally: We are actively working on adding non-repudiation to Cwtch servers such +that they themselves are restricted in what they can censor efficiently.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/cwtch/key_bundles/index.html b/build-staging/security/components/cwtch/key_bundles/index.html new file mode 100644 index 00000000..bf2d7908 --- /dev/null +++ b/build-staging/security/components/cwtch/key_bundles/index.html @@ -0,0 +1,31 @@ + + + + + +Key Bundles | The Cwtch Handbook + + + + + + + + + + + + +
+

Key Bundles

Cwtch servers identify themselves through signed key bundles. These key bundles contain a list of keys necessary +to make Cwtch group communication secure and metadata resistant.

At the time of writing, key bundles are expected to contain 3 keys:

  1. A Tor v3 Onion Service Public Key for the Token Board (ed25519)- used to connect to the service over Tor to post and +receive messages.
  2. A Tor v3 Onion Service Public Key for the Token Service (ed25519) - used to acquire tokens to post on the service via +a small proof-of-work exercise.
  3. A Privacy Pass Public Key - used in the token acquisition process (a ristretto curve point) . See: OPTR2019-01

The key bundle is signed and can be verified via the first v3 onion service key, thus binding it to that particular oninon +address.

Verifying Key Bundles

Profiles who import server key bundles verify them using the following trust-on-first-use (TOFU) algorithm:

  1. Verify the attached signature using the v3 onion address of the server. (If this fails, the import process is halted)
  2. Check that every key type exists. (If this fails, the import process is halted)
  3. If the profile has imported the server key bundle previously, assert that all the keys are the same. (If this fails, the import process is halted)
  4. Save the keys to the servers contact entry.

In the future this algorithm will likely be altered to allow the addition of new public keys (e.g. to allow +tokens to be acquired via a Zcash address.)

Technically, at steps (2) and (3() the server can be assumed to be malicious, having signed a valid key bundle that +does not conform to the specifications. When groups are moved from "experimental" to "stable" such an action will +result in a warning being communicated to the profile.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/cwtch/message_formats/index.html b/build-staging/security/components/cwtch/message_formats/index.html new file mode 100644 index 00000000..593a89ff --- /dev/null +++ b/build-staging/security/components/cwtch/message_formats/index.html @@ -0,0 +1,28 @@ + + + + + +Message Formats | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Formats

Peer to Peer Messages

PeerMessage {
ID string // A unique Message ID (primarily used for acknowledgments)
Context string // A unique context identifier i.e. im.cwtch.chat
Data []byte // The context-dependent serialized data packet.
}

Context Identifiers

  • im.cwtch.raw - Data contains a plain text chat message (see: overlays for more information)

  • im.cwtch.acknowledgement - Data is empty and ID references a previously sent message

  • im.cwtch.getVal and im.cwtch.retVal - Used for requesting / returning specific information about a peer. Data +contains a serialized peerGetVal structure and peerRetVal respectively.

        peerGetVal struct {
    Scope string
    Path string
    }

    type peerRetVal struct {
    Val string // Serialized path-dependent value
    Exists bool
    }

Plaintext / Decrypted Group Messages

type DecryptedGroupMessage struct {
Text string // plaintext of the message
Onion string // The Cwtch address of the sender
Timestamp uint64 // A user specified timestamp
// NOTE: SignedGroupID is now a misnomer, the only way this is signed is indirectly via the signed encrypted group messages
// We now treat GroupID as binding to a server/key rather than an "owner" - additional validation logic (to e.g.
// respect particular group constitutions) can be built on top of group messages, but the underlying groups are
// now agnostic to those models.
SignedGroupID []byte
PreviousMessageSig []byte // A reference to a previous message
Padding []byte // random bytes of length = 1800 - len(Text)
}

DecryptedGroupMessage contains random padding to a fixed size that is equal to the length of all fixed length fields + 1800. +This ensures that all encrypted group messages are equal length.

Encrypted Group Messages

// EncryptedGroupMessage provides an encapsulation of the encrypted group message stored on the server
type EncryptedGroupMessage struct {
Ciphertext []byte
Signature []byte // Sign(groupID + group.GroupServer + base64(decrypted group message)) using the senders Cwtch key
}

Calculating the signature requires knowing the groupID of the message, the server the group is associated with +and the decrypted group message (and thus, the Group Key). It is (ed25519) signed by the sender of the message, and can be +verified using their public Cwtch address key.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/cwtch/server/index.html b/build-staging/security/components/cwtch/server/index.html new file mode 100644 index 00000000..e52601b0 --- /dev/null +++ b/build-staging/security/components/cwtch/server/index.html @@ -0,0 +1,61 @@ + + + + + +Cwtch Server | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Server

The goal of the Cwtch protocol is to enable group communication through +Untrusted Infrastructure.

Unlike in relay-based schemes where the groups assign a leader, set of +leaders, or a trusted third party server to ensure that every member of the +group can send and receive messages in a timely manner (even if members are +offline) - untrusted infrastructure has a goal of realizing those properties +without the assumption of trust.

The original Cwtch paper defined a set of properties that Cwtch Servers were +expected to provide:

  • Cwtch Server may be used by multiple groups or just one.
  • A Cwtch Server, without collaboration of a group member, should +never learn the identity of participants within a group.
  • A Cwtch Server should never learn the content of any communication.
  • A Cwtch Server should never be able to distinguish messages as belonging +to a particular group.

We note here that these properties are a superset of the design aims of Private +Information Retrieval structures.

Malicious Servers

We expect the presence of malicious entities within the Cwtch ecosystem.

We also prioritize decentralization and permissionless entry into the +ecosystem and as such we do not base any security claims on the following:

  • Any non-collusion assumptions between a set of Cwtch servers
  • Any third-party defined verification process

Peers themselves are encouraged to set up and run Cwtch servers where they can +guarantee more efficient properties by relaxing trust and security +assumptions - however, by default, we design the protocol to be secure without +these assumptions - sacrificing efficiency where necessary.

Detectable Faults

  • If a Cwtch server fails to relay a specific message to a subset of group +members then there will be a detectable gap in the message tree of certain +peers that can be discovered through peer-to-peer gossip.
  • A Cwtch server cannot modify any message without the key material known to +the group (any attempt to do so for a subset of group members will result in +identical behavior to failing to relay a message).
  • While a server can duplicate messages, these will have no impact on the +group message tree (because of encryption, nonces and message identities) - +the source of the duplication is not knowable to a peer. +

Efficiency

As of writing, only 1 protocol is known for achieving the desired properties, +naive PIR or "the server sends everything, and the peers sift through it".

This has an obvious impact on bandwidth efficiency, especially for peers using +mobile devices, as such we are actively developing new protocols in which the +privacy and efficiency guarantees can be traded-off in different ways.

As of writing, the servers allow both a complete download of all stored messages, and a +request to download messages from a certain specified message.

All peers when they first join a group on a new server download all messages from the server, and +from then on download only new messages.

Note: This behaviour does permit a mild form of metadata analysis. The server can new messages for each +suspected unique profile, and then use these unique message signatures to track unique sessions over time ( +via requests for new messages).

This is mitigated by 2 confounding factors:

  1. Profiles can refresh their connections at any time - resulting in fresh server session.
  2. Profiles can "resync" from a server at any time - resulting in a new call to download all messages. The most +common usecase for this behaviour is to fetch older messages from a group. +

In combination, these 2 mitigations place bounds on what the server is able to infer however we still cannot +provide full metadata-resistance.

For potential future solutions to this problem see Niwl

Protecting the Server from Malicious Peers

The main risk to servers come in the form of spam generated by peers. In the +prototype of Cwtch a spamguard mechanism was put in place that required +peers to conduct some arbitrary proof of work given a server-specified +parameter.

This is not a robust solution in the presence of a determined adversary with +a significant amount of resources, and thus one of the main external risks to +the Cwtch system becomes censorship-via-resource exhaustion.

We have outlined a potential solution to this in +token based services but note +that this also requires further development.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/ecosystem-overview/index.html b/build-staging/security/components/ecosystem-overview/index.html new file mode 100644 index 00000000..45b717c6 --- /dev/null +++ b/build-staging/security/components/ecosystem-overview/index.html @@ -0,0 +1,33 @@ + + + + + +Component Ecosystem Overview | The Cwtch Handbook + + + + + + + + + + + + +
+

Component Ecosystem Overview

Cwtch is made up of several smaller component libraries. This chapter will provide a brief overview of +each component and how it relates to the wider Cwtch ecosystem.

openprivacy/connectivity

Summary: A library providing an ACN (Anonymous Communication Network ) networking abstraction.

The goal of connectivity is to abstract away the underlying libraries/software needed to communicate with a +specific ACN. Right now we only support Tor and so the job of connectivity is to:

  • Start and Stop the Tor Process
  • Provide configuration to the Tor process
  • Allow raw connections to endpoints via the Tor process (e.g. connect to onion services)
  • Host endpoints via the Tor process (e.g. host onion services)
  • Provide status updates about the underlying Tor process

For more information see connectivity

cwtch.im/tapir

Summary: Tapir is a small library for building p2p applications over anonymous communication systems.

The goal of tapir is to abstract away applications over a particular ACN. Tapir supports:

For more information see tapir

cwtch.im/cwtch

Summary: Cwtch is the main library for implementing the Cwtch protocol / system.

The goal of Cwtch is to provide implementations for cwtch-specific applications e.g. +message sending, groups, and file sharing(implemented as Tapir applications), provide interfaces for managing and storing Cwtch profiles, provide an event bus for subsystem splutting and building plugins with new functionality, in addition to managing other core functionality.

The Cwtch library is also responsible for maintaining canonical model representations for wire formats and overlays.

cwtch.im/libcwtch-go

Summary: libcwtch-go provides C (including Android) bindings for Cwtch for use in UI implementations.

The goal of libcwtch-go is to bridge the gap between the backend Cwtch library and any front end systems which +may be written in a different language.

The API provided by libcwtch is much more restricted than the one provided by Cwtch directly, each libcwtch API typically +packages up several calls to Cwtch.

libcwtch-go is also responsible for managing UI settings and experimental gating. It is also often used as a staging ground +for experimental features and code that may eventually end up in Cwtch.

cwtch-ui

Summary: A flutter based UI for Cwtch.

Cwtch UI uses libcwtch-go to provide a complete UI for Cwtch, allowing people to create and manage profiles, +add contacts and groups, message people, share files (coming soon) and more.

The UI is also responsible for managing localization and translations.

For more information see Cwtch UI

Auxiliary Components

Occasionally, Open Privacy will factor out parts of Cwtch into standalone libraries that are not Cwtch specific. +These are briefly summarized here:

openprivacy/log

An Open Privacy specific logging framework that is used throughout Cwtch packages.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/intro/index.html b/build-staging/security/components/intro/index.html new file mode 100644 index 00000000..b95ca9a7 --- /dev/null +++ b/build-staging/security/components/intro/index.html @@ -0,0 +1,40 @@ + + + + + +Cwtch Technical Basics | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Technical Basics

This page presents a brief technical overview of the Cwtch protocol.

A Cwtch Profile

Users can create one of more Cwtch Profiles. Each profile generates a random ed25519 keypair compatible with +Tor.

In addition to the cryptographic material, a profile also contains a list of Contacts (other Cwtch profile public keys + +associated data about that profile like nickname and (optionally) historical messages), a list of Groups (containing the group cryptographic material in addition to other associated data like the group nickname and historical messages).

2-party conversions: Peer to Peer

For 2 parties to engage in a peer-to-peer conversation both must be online, but only one needs to be reachable via +their onion service. For the sake of clarity we often label one party the "inbound peer" (the one who hosts the onion service) and the other party the +"outbound peer" (the one that connects to the onion service).

After connection both parties engage in an authentication protocol which:

  • Asserts that each party has access to the private key associated with their public identity.
  • Generates an ephemeral session key used to encrypt all further communication during the session.

This exchange (documented in further detail in authentication protocol) is offline deniable +i.e. it is possible for any party to forge transcripts of this protocol exchange after the fact, and as such - after the +fact - it is impossible to definitely prove that the exchange happened at all.

After, the authentication protocol the two parties may exchange messages with each other freely.

Multi-party conversations: Groups and Peer to Server Communication

Note: Metadata Resistant Group Communication is still an active research area and what is documented here +will likely change in the future.

When a person wants to start a group conversation they first randomly generate a secret Group Key. All group communication will be encrypted using this key.

Along with the Group Key, the group creator also decides on a Cwtch Server to use as the host of the group. +For more information on how Servers authenticate themselves see key bundles.

A Group Identifier is generated using the group key and the group server and these three elements are packaged up +into an invite that can be sent to potential group members (e.g. over existing peer-to-peer connections).

To send a message to the group, a profile connects to the server hosting the group (see below), and encrypts +their message using the Group Key and generates a cryptographic signature over the Group Id, Group Server +and the decrypted message (see: wire formats for more information).

To receive message from the group, a profile connected to the server hosting the group and downloads all messages (since +their previous connection). Profiles then attempt to decrypt each message using the Group Key and if successful attempt +to verify the signature (see Cwtch Servers Cwtch Groups for an overview of attacks and mitigations).

Servers are Peers

In many respects communication with a server is identical to communication with a regular Cwtch peer, +all the same steps above are taken however the server always acts as the inbound peer, and the outbound +peer always uses newly generated ephemeral keypair as their "longterm identity".

As such peer-server conversations only differ in the kinds of messages that are sent between the two parties, +with the server relaying all messages that it receives and also allowing any client to query for older messages.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/tapir/authentication_protocol/index.html b/build-staging/security/components/tapir/authentication_protocol/index.html new file mode 100644 index 00000000..081133c1 --- /dev/null +++ b/build-staging/security/components/tapir/authentication_protocol/index.html @@ -0,0 +1,37 @@ + + + + + +Authentication Protocol | The Cwtch Handbook + + + + + + + + + + + + +
+

Authentication Protocol

Each peer, given an open connection CC:

I=InitializeIdentity()Ie=InitializeEphemeralIdentity()I,IeCP,PeCk=KDF(Pei+Pie+Peie)c=E(k,transcript.Commit())cCcpCD(k,cp)=?transcript.LatestCommit()I = \mathrm{InitializeIdentity()} \\ I_e = \mathrm{InitializeEphemeralIdentity()} \\ I,I_e \rightarrow C \\ P,P_e \leftarrow C \\ k = \mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\ c = \mathrm{E}(k, transcript.Commit()) \\ c \rightarrow C \\ c_p \leftarrow C\\ \mathrm{D}(k, c_p) \stackrel{?}{=} transcript.LatestCommit()

The above represents a sketch protocol, in reality there are a few +implementation details worth pointing out:

Once derived from the key derivation function (KDF\mathrm{KDF}) the key +(kk) is set on the connection, meaning the authentication app doesn't +do the encryption or decryption explicitly.

The concatenation of parts of the 3DH exchange is strictly ordered:

  • DH of the Long term identity of the outbound connection by the ephemeral +key of the inbound connection.
  • DH of the Long term identity of the inbound connection by the ephemeral +key of the outbound connection.
  • DH of the two ephemeral identities of the inbound and outbound connections.

This strict ordering ensures both sides of the connection derive the same +session key.

Cryptographic Properties

During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come +from their peer (or at least, someone with possession of their peers secret key as it related to their onion address).

Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and +all encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant +repudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied +that a single message in the transcript must have originated from a peer, there is no way of linking any other message to +the session.

Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the +session key is made public it can be used to forge new messages in the transcript - and as such, any standalone +transcript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/tapir/packet_format/index.html b/build-staging/security/components/tapir/packet_format/index.html new file mode 100644 index 00000000..a946b0d1 --- /dev/null +++ b/build-staging/security/components/tapir/packet_format/index.html @@ -0,0 +1,26 @@ + + + + + +Packet Format | The Cwtch Handbook + + + + + + + + + + + + +
+

Packet Format

All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message, +len bytes of data, and the rest zero padded:

| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|

Once encrypted, the entire 8192 byte data packet is encrypted using libsodium secretbox using the standard structure ( +note in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)

For information on how the secret key is derived see the authentication protocol

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/ui/android/index.html b/build-staging/security/components/ui/android/index.html new file mode 100644 index 00000000..0946f664 --- /dev/null +++ b/build-staging/security/components/ui/android/index.html @@ -0,0 +1,24 @@ + + + + + +Android Service | The Cwtch Handbook + + + + + + + + + + + + +
+

Android Service

Adapted from: Discreet Log #11: Integrating FFI processes with Android services

In addition to needing to make plain ol’ method calls into the Cwtch library, we also need to be able to communicate with (and receive events from) long-running Cwtch goroutines that keep the Tor process running in the background, manage connection and conversation state for all your contacts, and handle a few other monitoring and upkeep tasks as well. This isn’t really a problem on traditionally multitasking desktop operating systems, but on mobile devices running Android we have to contend with shorter sessions, frequent unloads, and network and power restrictions that can vary over time. As Cwtch is intended to be metadata resistant and privacy-centric, we also want to provide notifications without using the Google push notification service.

The solution for long-running network apps like Cwtch is to put our FFI code into an Android Foreground Service. (And no, it’s not lost on me that the code for our backend is placed in something called a ForegroundService.) With a big of finagling, the WorkManager API allows us to create and manage various types of services including ForegroundServices. This turned out to be a great choice for us, as our gomobile FFI handler happened to already be written in Kotlin, and WorkManager allows us to specify a Kotlin coroutine to be invoked as the service.

If you’d like to follow along, our WorkManager specifications are created in the handleCwtch() method of MainActivity.kt, and the workers themselves are defined in FlwtchWorker.kt.

Our plain ol’ method calls to FFI routines are also upgraded to be made as WorkManager work requests, which allows us to conveniently pass the return values back via the result callback.

One initial call (aptly named Start) gets hijacked by FlwtchWorker to become our eventbus loop. Since FlwtchWorker is a coroutine, it’s easy for it to yield and resume as necessary while waiting for events to be generated. Cwtch’s goroutines can then emit events, which will be picked up by FlwtchWorker and dispatched appropriately.

FlwtchWorker’s eventbus loop is not just a boring forwarder. It needs to check for certain message types that affect the Android state; for example, new message events should typically display notifications that the user can click to go to the appropriate conversation window, even when the app isn’t running in the foreground. When the time does come to forward the event to the app, we use LocalBroadcastManager to get the notification to MainActivity.onIntent. From there, we in turn use Flutter MethodChannels to forward the event data from Kotlin into the frontend’s Flutter engine, where the event finally gets parsed by Dart code that updates the UI as necessary.

Messages and other permanent state are stored on disk by the service, so the frontend doesn’t need to be updated if the app isnt open. However, some things (like dates and unread messages) can then lead to desyncs between the front and back ends, so we check for this at app launch/resume to see if we need to reinitialize Cwtch and/or resync the UI state.

Finally, while implementing these services on Android we observed that WorkManager is very good at persisting old enqueued work, to the point that old workers were even being resumed after app reinstalls! Adding calls to pruneWork() helps mitigate this, as long as the app was shut down gracefully and old jobs were properly canceled. This frequently isn’t the case on Android, however, so as an additional mitigation we found it useful to tag the work with the native library directory name:

private fun getNativeLibDir(): String {
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
"im.cwtch.flwtch", // Must be app name
PackageManager.GET_SHARED_LIBRARY_FILES)
return ainfo.nativeLibraryDir
}

…then, whenever the app is launched, we cancel any jobs that aren’t tagged with the correct current library directory. Since this directory name changes between app installs, this technique prevents us from accidentally resuming with an outdated service worker.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/ui/image_previews/index.html b/build-staging/security/components/ui/image_previews/index.html new file mode 100644 index 00000000..3c8c42d4 --- /dev/null +++ b/build-staging/security/components/ui/image_previews/index.html @@ -0,0 +1,30 @@ + + + + + +Image Previews | The Cwtch Handbook + + + + + + + + + + + + +
+

Image Previews

Built on the back of filesharing in Cwtch 1.3, image previews are keyed by the suggested filename’s extension (and no, we’re not interested in using MIME types or magic numbers) and advertised size. If enabled, the preview system will automatically download shared images to a configured downloads folder and display them as part of the message itself. (Due to limitations on Android, they’ll go to the app’s private storage cache, and give you the option to save them elsewhere later instead.) The file size limit is TBD but will obviously be much lower than the overall filesharing size limit, which is currently 10 gigabytes.

For now, we only support single-image messages, and any image editing/cropping will have to be done in a separate application. As we mention in the filesharing FAQ, image files also frequently contain significant hidden metadata, and you should only share them with people you trust.

KnownRisks

Other Applications and/or the OS Inferring Information from Images

Images must be stored somewhere, and for now we have chosen to store them unencrypted on the file system. We have done this +for 2 reasons:

  1. In order to support more powerful file sharing schemes like rehosting we require the ability to efficiently +scan files and deliver chunks - doing this through an encrypted database layer would harm performance.
  2. This information always has to transit the application boundary (either via display drivers, or storing and viewing +the file in an external application) - there is nothing that Cwtch can do after that point in any case.

Malicious Images Crashing or otherwise Compromising Cwtch

Flutter uses Skia to render Images. While the underlying code is memory unsafe, it is extensively fuzzed as part of regular development.

We also conduct our own fuzz testing of Cwtch components. In that analysis we found a single crash bug related +to a malformed GIF file that caused the renderer to allocate a ridiculous amount of memory (and eventually be refused +by the kernel). To prevent this from impacting Cwtch we have adopted the policy of always enabling a maximum cacheWidth +and/or cacheHeight for Image widgets.

Malicious Images Rendering Differently on Different Platforms, Potentially Exposing Metadata

Recently a bug was found in Apple's png parser which would cause an image to render differently on Apple devices as it would on non-Apple devices.

We conducted a few tests on our Mac builds and could not replicate this issue for Flutter (because all Flutter builds use Skia for rendering), however we will continue to include such cases in our testing corpus.

For now image previews will remain experimental and opt-in.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/ui/input/index.html b/build-staging/security/components/ui/input/index.html new file mode 100644 index 00000000..900b2e34 --- /dev/null +++ b/build-staging/security/components/ui/input/index.html @@ -0,0 +1,31 @@ + + + + + +Input | The Cwtch Handbook + + + + + + + + + + + + +
+

Input

Risk: Interception of Cwtch content or metadata through an IME on Mobile Devices

Status: Partially Mitigated

Any component that has the potential to intercept data between a person, and the Cwtch app is a +potential security risk.

One of the most likely interceptors is a 3rd party IME (Input Method Editor) commonly used +by people to generate characters not natively supported by their device.

Even benign and stock IME apps may unintentionally leak information about the contents of a persons message e.g. +through cloud synchronization, cloud translation or personal dictionaries.

Ultimately, this problem cannot be solved by Cwtch alone, and is a wider risk impacting the entire mobile +ecosystem.

A similar risk exists on desktop through the use of similar input applications (in addition to software keyloggers), +however we consider that fully outside the scope of Cwtch risk assessment (in line with other attacks on the security of the underlying +operating system itself).

This is partially mitigated in Cwtch 1.2 through the use of enableIMEPersonalizedLearning: false. See +this PR for more information.

+ + + + \ No newline at end of file diff --git a/build-staging/security/components/ui/overlays/index.html b/build-staging/security/components/ui/overlays/index.html new file mode 100644 index 00000000..2e79e79a --- /dev/null +++ b/build-staging/security/components/ui/overlays/index.html @@ -0,0 +1,39 @@ + + + + + +Message Overlays | The Cwtch Handbook + + + + + + + + + + + + +
+

Message Overlays

Adapted from: Discreet Log #8: Notes on the Cwtch Chat API

Note: This section covers overlay protocols on-top of the Cwtch protcol. For information on the Cwtch Protocol +messages themselves please see Message Formats

We envision Cwtch as a platform for providing an authenticated transport layer to higher-level applications. +Developers are free to make their own choices about what application layer protocols to use, +whether they want bespoke binary message formats or just want to throw an HTTP library on top and call it a +day. Cwtch can generate new keypairs for you (which become onion addresses; no need for any DNS registrations!) +and you can REST assured that any data your application receives from the (anonymous communication) +network has been authenticated already.

For our current stack, messages are wrapped in a minimal JSON frame that adds +some contextual information about the message type. +And because serialised JSON objects are just dictionaries, we can easily add more metadata later on as needed.

Chat overlays, lists, and bulletins

The original Cwtch alpha demoed "overlays": different ways of interpreting the same data channel, +depending on the structure of the atomic data itself. We included simple checklists and BBS/classified ads as overlays that could be viewed +and shared with any Cwtch contact, be it a single peer or a group. The wire format looked like this:

{o:1,d:"hey there!"}
{o:2,d:"bread",l:"groceries"}
{o:3,d:"garage sale",p:"[parent message signature]"}

Overlay field o determined if it was a chat (1), list (2), or bulletin (3) message. +The data field d is overloaded, and lists/bulletins need additional information about what +group/post they belong to. (We use message signatures in place of IDs to avoid things like message +ordering problems and maliciously crafted IDs. This is also how the Cwtch protocol communicates to the +front end which message is being acked.)

Data structure

Implementing tree-structured data on top of a sequential message store comes with obvious +performance disadvantages. For example, consider the message view, which loads most-recent-messages first and only goes back far enough to fetch enough messages to fill the current viewport, in comparison with a (somewhat pathological) forum where almost every message is a child of the very first message in the history, which could have been gigs and gigs of data-ago. If the UI only displays top-level posts until the user expands them, we have to parse the entire history before we get enough info to display anything at all.

Another problem is that multiplexing all these overlays into one data store creates "holes" in the data that confuse lazy-loaded listviews and scrollbars. The message count may indicate there is a ton more information to display if the user simply scrolls, but when it actually gets fetched and parsed we might realize that none of it is relevant to the current overlay.

None of these problems are insurmountable, but they demonstrate a flaw in our initial assumptions about the nature of collaborative message flows and how we should be handling that data.

Overlay Types

As stated above, overlays are specified in a very simple JSON format with the following structure:

type ChatMessage struct {
O int `json:"o"`
D string `json:"d"`
}

Where O stands for Overlay with the current supported overlays documented below:

1: data is a chat string
2: data is a list state/delta
3: data is a bulletin state/delta
100: contact suggestion; data is a peer onion address
101: contact suggestion; data is a group invite string

Chat Messages (Overlay 1)

The most simple over is a chat message which simply contains raw, unprocessed chat message information.

{o:1,d:"got milk?"}

Invitations (Overlays 100 and 101)

Instead of receiving the invite as an incoming contact request at the profile level, new inline invites are shared with a particular contact/group, where they can be viewed and/or accepted later, even if they were initially rejected (potentially by accident).

The wire format for these are equally simple:

{o:100,d:"u4ypg7yyyrrvf2aceeclq5dgwtkirzletltbqofnb6km7u542qqk4jyd"}
{o:101,d:"torv3eyJHcm91cElEIjoiOWY3MWExYmFhNDkzNTAzMzAyZDFmODRhMzI2ODY2OWUiLCJHcm91cE5hbWUiOiI5ZjcxYTFiYWE0OTM1MDMzMDJkMWY4NGEzMjY4NjY5ZSIsIlNpZ25lZEdyb3VwSUQiOiJyVGY0dlJKRkQ2LzFDZjFwb2JQR0xHYzdMNXBKTGJTelBLRnRvc3lvWkx6R2ZUd2Jld0phWllLUWR5SGNqcnlmdXVRcjk3ckJ2RE9od0NpYndKbCtCZz09IiwiVGltZXN0YW1wIjowLCJTaGFyZWRLZXkiOiJmZVVVQS9OaEM3bHNzSE9lSm5zdDVjNFRBYThvMVJVOStPall2UzI1WUpJPSIsIlNlcnZlckhvc3QiOiJ1cjMzZWRid3ZiZXZjbHM1dWU2anBrb3ViZHB0Z2tnbDViZWR6ZnlhdTJpYmY1Mjc2bHlwNHVpZCJ9"}

This represents a departure from our original "overlays" thinking to a more action-oriented representation. The chat "overlay" can communicate that someone did something, even if it's paraphrased down to "added an item to a list," and the lists and bulletins and other beautifully chaotic data can have their state precomputed and stored separately.

Lists / Bulletin Boards

Note: Expected to be Defined in Cwtch Beta 1.5

+ + + + \ No newline at end of file diff --git a/build-staging/security/deployment/index.html b/build-staging/security/deployment/index.html new file mode 100644 index 00000000..1089b84d --- /dev/null +++ b/build-staging/security/deployment/index.html @@ -0,0 +1,29 @@ + + + + + +Deployment | The Cwtch Handbook + + + + + + + + + + + + +
+

Deployment

Risk: Binaries are replaced on the website with malicious ones

Status: Partially-mitigated

While this process is now mostly automated, should this automation ever be +compromised then there is nothing in our current process that would detect this.

We need:

  • Reproducible Builds - we currently use public docker containers for all builds +which should allow anyone to compare distributed builds with ones built from source.
  • Signed Releases - Open Privacy does not yet maintain a public record of staff +public keys. This is likely a necessity for signing released builds and +creating an audit chain backed by the organization. This process must be +manual by definition.
+ + + + \ No newline at end of file diff --git a/build-staging/security/development/index.html b/build-staging/security/development/index.html new file mode 100644 index 00000000..c7cb83bb --- /dev/null +++ b/build-staging/security/development/index.html @@ -0,0 +1,36 @@ + + + + + +Development | The Cwtch Handbook + + + + + + + + + + + + +
+

Development

The main process to counter malicious actors in development of Cwtch is the +openness of the process.

To enhance this openness, automated builds, testing and packaging are defined +as part of the repositories - improving te robustness of the code base at every +stage.

While individual tests aren't perfect, and all processes have gaps, we should be +committed to make it as easy as possible to contribute to Cwtch while also +building pipelines and processes that catch errors (unintential or malicious) +as soon as possible.

Risk: Developer Directly Pushes Malicious Code

Status: Mitigated

trunk is currently locked and only 3 Open Privacy staff members have permission +to override it, in addition the responsibility of monitoring changes.

Further every new pull request and merge triggered automated builds & tests +which trigger emails and audit logs.

The code is also open source and inspectable by anyone.

Risk: Code Regressions

Status: Partially Mitigated (See individual project entries in this +handbook for more information)

Our automated pipelines have the ability to catch regressions when that +behaviour is detectable.

The greatest challenge is in defining how such regressions are detected for the +ui - where behaviour isn't as strictly defined as it is for the +individual libraries.

+ + + + \ No newline at end of file diff --git a/build-staging/security/intro/index.html b/build-staging/security/intro/index.html new file mode 100644 index 00000000..ea73ed2d --- /dev/null +++ b/build-staging/security/intro/index.html @@ -0,0 +1,50 @@ + + + + + +Cwtch Security Handbook | The Cwtch Handbook + + + + + + + + + + + + +
+

Cwtch Security Handbook

Welcome to the Cwtch Secure Development Handbook! The purpose of this +handbook is to provide a guide to the various components of the Cwtch +ecosystem, to document the known risks and mitigations, and to enable +discussion about improvements and updates to Cwtch secure development +processes.

What is Cwtch?

Cwtch (/kʊtʃ/ - a Welsh word roughly translating to “a hug that creates a safe place”) is a decentralized, privacy-preserving, multi-party messaging protocol that can be used to build metadata resistant applications.

  • Decentralized and Open: There is no “Cwtch service” or “Cwtch network”. Participants in Cwtch can host their own safe spaces, or lend their infrastructure to others seeking a safe space. The Cwtch protocol is open, and anyone is free to build bots, services and user interfaces and integrate and interact with Cwtch.
  • Privacy Preserving: All communication in Cwtch is end-to-end encrypted and takes place over Tor v3 onion services.
  • Metadata Resistant: Cwtch has been designed such that no information is exchanged or available to anyone without their explicit consent, including on-the-wire messages and protocol metadata.

A (Brief) History of Metadata Resistant Chat

In recent years, public awareness of the need and benefits of end-to-end +encrypted solutions has increased with applications like Signal, +Whatsapp and Wire now providing +users with secure communications.

However, these tools require various levels of metadata exposure to function, +and much of this metadata can be used to gain details about how and why a person +is using a tool to communicate. [rottermanner2015privacy].

One tool that did seek to reduce metadata is Ricochet first released in 2014. +Ricochet used Tor v2 onion services to provide secure end-to-end encrypted communication, +and to protect the metadata of communications.

There were no centralized servers that assist in routing Ricochet +conversations. No one other than the parties involved in a conversation could +know that such a conversation is taking place.

Ricochet wasn't without limitations; there was no multi-device support, nor is +there a mechanism for supporting group communication or for a user to send +messages while a contact is offline.

This made adoption of Ricochet a difficult proposition; with even those in +environments that would be served best by metadata resistance unaware that it +exists [ermoshina2017can] +[renaud2014doesn].

Additionally, any solution to decentralized, metadata resistant communication faces fundamental problems +when it comes to efficiency, privacy and group security (as defined by transcript consensus and consistency).

Modern alternatives to Ricochet include Briar, Zbay +and Ricochet Refresh - each tool seeks to optimize for a different +set of trade-offs e.g. Briar seeks to allow people to communicate even when underlying network infrastructure +is down while providing resistant to metadata surveillance.


The Cwtch project began in 2017 as an extension protocol for Ricochet providing group conversations via +untrusted servers, with an eye to enabling decentralized, metadata resistant applications (like shared lists +and bulletin board)

An alpha version of Cwtch was was launched in February 2019, and +since then the Cwtch team (run by the Open Privacy Research Society) has conducted +research and development into Cwtch and the underlying protocols and libraries and problem spaces.

+ + + + \ No newline at end of file diff --git a/build-staging/security/references/index.html b/build-staging/security/references/index.html new file mode 100644 index 00000000..9f3d306b --- /dev/null +++ b/build-staging/security/references/index.html @@ -0,0 +1,25 @@ + + + + + +References | The Cwtch Handbook + + + + + + + + + + + + +
+

References

  • Atwater, Erinn, and Sarah Jamie Lewis. "Token Based Services-Differences from Privacy Pass."

  • Brooks, John. Ricochet: Anonymous instant messaging for real privacy. https://ricochet.im. Accessed: 2018-03-10

  • Ermoshina K, Halpin H, Musiani F. Can johnny build a protocol? co-ordinating developer and user intentions for privacy-enhanced secure messaging protocols. In European Workshop on Usable Security 2017.

  • Ermoshina, K., Musiani, F. and Halpin, H., 2016, September. End-to-end encrypted messaging protocols: An overview. In International Conference on Internet Science (pp. 244-254). Springer, Cham.

  • Farb, M., Lin, Y.H., Kim, T.H.J., McCune, J. and Perrig, A., 2013, September. Safeslinger: easy-to-use and secure public-key exchange. In Proceedings of the 19th annual international conference on Mobile computing & networking (pp. 417-428).

  • Greschbach, B., Kreitz, G. and Buchegger, S., 2012, March. The devil is in the metadata—New privacy challenges in Decentralised Online Social Networks. In 2012 IEEE international conference on pervasive computing and communications workshops (pp. 333-339). IEEE.

  • Langley, Adam. Pond. https://github.com/agl/pond. Accessed: 2018-05-21.

  • Le Blond, S., Zhang, C., Legout, A., Ross, K. and Dabbous, W., 2011, November. I know where you are and what you are sharing: exploiting p2p communications to invade users' privacy. In Proceedings of the 2011 ACM SIGCOMM conference on Internet measurement conference (pp. 45-60).

  • Lewis, Sarah Jamie. "Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized, Multi-Party and Metadata Resistant Applications." (2018).

  • Kalysch, A., Bove, D. and Müller, T., 2018, November. How Android's UI Security is Undermined by Accessibility. In Proceedings of the 2nd Reversing and Offensive-oriented Trends Symposium (pp. 1-10).

  • Renaud, K., Volkamer, M. and Renkema-Padmos, A., 2014, July. Why doesn’t Jane protect her privacy?. In International Symposium on Privacy Enhancing Technologies Symposium (pp. 244-262). Springer, Cham.

  • Rottermanner, C., Kieseberg, P., Huber, M., Schmiedecker, M. and Schrittwieser, S., 2015, December. Privacy and data protection in smartphone messengers. In Proceedings of the 17th International Conference on Information Integration and Web-based Applications & Services (pp. 1-10).

  • Unger, Nik et al. “SoK: secure messaging”. In: Security and Privacy (SP +), 2015 IEEE Sympo-sium on. IEEE. 2015, pp. 232–249 link

+ + + + \ No newline at end of file diff --git a/build-staging/security/risk/index.html b/build-staging/security/risk/index.html new file mode 100644 index 00000000..46fb3df5 --- /dev/null +++ b/build-staging/security/risk/index.html @@ -0,0 +1,58 @@ + + + + + +Risk Model | The Cwtch Handbook + + + + + + + + + + + + +
+

Risk Model

Communications metadata is known to be exploited by various adversaries to +undermine the security of systems, to track victims +and to conduct large scale social network analysis to feed mass surveillance. +Metadata resistant tools are in their infancy and research into the construction +and user experience of such tools is lacking.

Cwtch was originally conceived as an extension of the metadata resistant protocol +Ricochet to support asynchronous, multi-peer group communications through the +use of discardable, untrusted, anonymous infrastructure.

Since then, Cwtch has evolved into a protocol in its own right, this section +will outline the various known risks that Cwtch attempts to mitigate and will +be heavily referenced throughout the rest of the document when discussing the +various sub-components of the Cwtch Architecture.

Threat Model

It is important to identify and understand that metadata is ubiquitous in +communication protocols, it is indeed necessary for such protocols to +function efficiently and at scale. However, information that is useful to +facilitating peers and servers is also highly relevant to adversaries +wishing to exploit such information.

For our problem definition, we will assume that the content of a communication is +encrypted in such a way that an adversary is practically unable to break +(see tapir and cwtch for details on the +encryption that we use, a +and as such we will focus to the context to the communication metadata.

We seek to protect the following communication contexts:

  • Who is involved in a communication? It may be possible to identify +people or simply device or network identifiers. E.g., “this communication involves Alice, a journalist, and Bob a government employee.”.
  • Where are the participants of the conversation? E.g., “during this +communication Alice was in France and Bob was in Canada.”
  • When did a conversation take place? The timing and length of communication +can reveal a large amount about the nature of a call, e.g., “Bob a government employee, talked to Alice on the phone for an hour yesterday evening. This is the first time they have communicated.” +*How was the conversation mediated? Whether a conversation took place over an +encrypted or unencrypted email can provide useful intelligence. E.g., “Alice sent an encrypted email to Bob yesterday, whereas they usually only send plaintext emails to each other.”
  • What is the conversation about? Even if the content of the communication is +encrypted it is sometimes possible to derive a probable context of a conversation without knowing exactly what is said, e.g. “a person called a pizza store at dinner time” or “someone called a known suicide hotline number at 3am.”

Beyond individual conversations, we also seek to defend against context correlation attacks, whereby multiple conversations are analyzed to derive higher level information:

  • Relationships: Discovering social relationships between a pair of entities +by analyzing the frequency and length of their communications over a period of time. E.g. Carol and Eve call each other every single day for multiple hours at a time.
  • Cliques: Discovering social relationships between a group of entities that +all interact with each other. E.g. Alice, Bob and Eve all communicate with each other.
  • Loosely Connected Cliques and Bridge Individuals: Discovering groups that +communicate to each other through intermediaries by analyzing communication chains (e.g. everytime Alice talks to Bob she talks to Carol almost immediately after; Bob and Carol never communicate.)
  • Pattern of Life: Discovering which communications are cyclical and +predictable. E.g. Alice calls Eve every Monday evening for around an hour.

Active Attacks

Misrepresentation Attacks

Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks +based around misrepresentation i.e. people pretending to be other people:

A basic flow of one of these attacks is as follows, although other flows also exist:

  • Alice has a friend named Bob and another called Eve
  • Eve finds out Alice has a friend named Bob
  • Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)
  • Eve calls this new account "Eve New Account" and adds Alice as a friend.
  • Eve then changes her name on "Eve New Account" to "Bob"
  • Alice sends messages intended for "Bob" to Eve's fake Bob account

Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them +is for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply won't-happen.

As such we aim to provide some user-experience hints in the ui to guide people in making choices around whether +to trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users.

A note on Physical Attacks

Cwtch does not consider attacks that require physical access (or equivalent) to +the users machine as practically defendable. However, in the interests of good +security engineering, throughout this document we will still +refer to attacks or conditions that require such privilege and point out +where any mitigations we have put in place will fail.

+ + + + \ No newline at end of file diff --git a/build-staging/sitemap.xml b/build-staging/sitemap.xml new file mode 100644 index 00000000..3858a041 --- /dev/null +++ b/build-staging/sitemap.xml @@ -0,0 +1 @@ +https://docs.cwtch.im/blogweekly0.5https://docs.cwtch.im/blog/archiveweekly0.5https://docs.cwtch.im/blog/autobindingsweekly0.5https://docs.cwtch.im/blog/autobindings-iiweekly0.5https://docs.cwtch.im/blog/availability-status-profile-attributesweekly0.5https://docs.cwtch.im/blog/cwtch-android-reproducibilityweekly0.5https://docs.cwtch.im/blog/cwtch-bindings-reproducibleweekly0.5https://docs.cwtch.im/blog/cwtch-developer-documentationweekly0.5https://docs.cwtch.im/blog/cwtch-documentationweekly0.5https://docs.cwtch.im/blog/cwtch-nightly-1-11weekly0.5https://docs.cwtch.im/blog/cwtch-nightly-1-12weekly0.5https://docs.cwtch.im/blog/cwtch-nightly-v.11-74weekly0.5https://docs.cwtch.im/blog/cwtch-platform-supportweekly0.5https://docs.cwtch.im/blog/cwtch-stable-api-designweekly0.5https://docs.cwtch.im/blog/cwtch-stable-roadmap-updateweekly0.5https://docs.cwtch.im/blog/cwtch-stable-roadmap-update-juneweekly0.5https://docs.cwtch.im/blog/cwtch-testing-iweekly0.5https://docs.cwtch.im/blog/cwtch-testing-iiweekly0.5https://docs.cwtch.im/blog/page/2weekly0.5https://docs.cwtch.im/blog/path-to-cwtch-stableweekly0.5https://docs.cwtch.im/blog/tagsweekly0.5https://docs.cwtch.im/blog/tags/apiweekly0.5https://docs.cwtch.im/blog/tags/autobindingsweekly0.5https://docs.cwtch.im/blog/tags/bindingsweekly0.5https://docs.cwtch.im/blog/tags/cwtchweekly0.5https://docs.cwtch.im/blog/tags/cwtch-stableweekly0.5https://docs.cwtch.im/blog/tags/cwtch-stable/page/2weekly0.5https://docs.cwtch.im/blog/tags/cwtch/page/2weekly0.5https://docs.cwtch.im/blog/tags/developer-documentationweekly0.5https://docs.cwtch.im/blog/tags/documentationweekly0.5https://docs.cwtch.im/blog/tags/libcwtchweekly0.5https://docs.cwtch.im/blog/tags/nightlyweekly0.5https://docs.cwtch.im/blog/tags/planningweekly0.5https://docs.cwtch.im/blog/tags/releaseweekly0.5https://docs.cwtch.im/blog/tags/repliqateweekly0.5https://docs.cwtch.im/blog/tags/reproducible-buildsweekly0.5https://docs.cwtch.im/blog/tags/security-handbookweekly0.5https://docs.cwtch.im/blog/tags/supportweekly0.5https://docs.cwtch.im/blog/tags/testingweekly0.5https://docs.cwtch.im/developing/building-a-cwtch-app/building-an-echobotweekly0.5https://docs.cwtch.im/developing/building-a-cwtch-app/core-conceptsweekly0.5https://docs.cwtch.im/developing/building-a-cwtch-app/introweekly0.5https://docs.cwtch.im/developing/category/building-a-cwtch-appweekly0.5https://docs.cwtch.im/developing/introweekly0.5https://docs.cwtch.im/developing/releaseweekly0.5https://docs.cwtch.im/docs/category/appearanceweekly0.5https://docs.cwtch.im/docs/category/behaviourweekly0.5https://docs.cwtch.im/docs/category/contributeweekly0.5https://docs.cwtch.im/docs/category/conversationsweekly0.5https://docs.cwtch.im/docs/category/experimentsweekly0.5https://docs.cwtch.im/docs/category/getting-startedweekly0.5https://docs.cwtch.im/docs/category/groupsweekly0.5https://docs.cwtch.im/docs/category/platformsweekly0.5https://docs.cwtch.im/docs/category/profilesweekly0.5https://docs.cwtch.im/docs/category/serversweekly0.5https://docs.cwtch.im/docs/category/settingsweekly0.5https://docs.cwtch.im/docs/chat/accept-deny-new-conversationweekly0.5https://docs.cwtch.im/docs/chat/add-contactweekly0.5https://docs.cwtch.im/docs/chat/block-contactweekly0.5https://docs.cwtch.im/docs/chat/conversation-settingsweekly0.5https://docs.cwtch.im/docs/chat/delete-contactweekly0.5https://docs.cwtch.im/docs/chat/introductionweekly0.5https://docs.cwtch.im/docs/chat/message-formattingweekly0.5https://docs.cwtch.im/docs/chat/reply-to-messageweekly0.5https://docs.cwtch.im/docs/chat/save-conversation-historyweekly0.5https://docs.cwtch.im/docs/chat/share-address-with-friendsweekly0.5https://docs.cwtch.im/docs/chat/share-fileweekly0.5https://docs.cwtch.im/docs/chat/unblock-contactweekly0.5https://docs.cwtch.im/docs/contribute/developingweekly0.5https://docs.cwtch.im/docs/contribute/documentationweekly0.5https://docs.cwtch.im/docs/contribute/stickersweekly0.5https://docs.cwtch.im/docs/contribute/testingweekly0.5https://docs.cwtch.im/docs/contribute/translateweekly0.5https://docs.cwtch.im/docs/getting-started/supported_platformsweekly0.5https://docs.cwtch.im/docs/groups/accept-group-inviteweekly0.5https://docs.cwtch.im/docs/groups/create-groupweekly0.5https://docs.cwtch.im/docs/groups/edit-group-nameweekly0.5https://docs.cwtch.im/docs/groups/introductionweekly0.5https://docs.cwtch.im/docs/groups/leave-groupweekly0.5https://docs.cwtch.im/docs/groups/manage-known-serversweekly0.5https://docs.cwtch.im/docs/groups/send-inviteweekly0.5https://docs.cwtch.im/docs/introweekly0.5https://docs.cwtch.im/docs/platforms/tailsweekly0.5https://docs.cwtch.im/docs/profiles/availability-statusweekly0.5https://docs.cwtch.im/docs/profiles/change-nameweekly0.5https://docs.cwtch.im/docs/profiles/change-passwordweekly0.5https://docs.cwtch.im/docs/profiles/change-profile-imageweekly0.5https://docs.cwtch.im/docs/profiles/create-a-profileweekly0.5https://docs.cwtch.im/docs/profiles/delete-profileweekly0.5https://docs.cwtch.im/docs/profiles/exporting-profileweekly0.5https://docs.cwtch.im/docs/profiles/importing-a-profileweekly0.5https://docs.cwtch.im/docs/profiles/introductionweekly0.5https://docs.cwtch.im/docs/profiles/profile-infoweekly0.5https://docs.cwtch.im/docs/profiles/unlock-profileweekly0.5https://docs.cwtch.im/docs/servers/create-serverweekly0.5https://docs.cwtch.im/docs/servers/delete-serverweekly0.5https://docs.cwtch.im/docs/servers/edit-serverweekly0.5https://docs.cwtch.im/docs/servers/introductionweekly0.5https://docs.cwtch.im/docs/servers/share-keyweekly0.5https://docs.cwtch.im/docs/servers/unlock-serverweekly0.5https://docs.cwtch.im/docs/settings/appearance/change-languageweekly0.5https://docs.cwtch.im/docs/settings/appearance/light-dark-modeweekly0.5https://docs.cwtch.im/docs/settings/appearance/streamer-modeweekly0.5https://docs.cwtch.im/docs/settings/appearance/ui-columnsweekly0.5https://docs.cwtch.im/docs/settings/behaviour/block-unknown-connectionsweekly0.5https://docs.cwtch.im/docs/settings/behaviour/notification-contentweekly0.5https://docs.cwtch.im/docs/settings/behaviour/notification-policyweekly0.5https://docs.cwtch.im/docs/settings/experiments/clickable-linksweekly0.5https://docs.cwtch.im/docs/settings/experiments/file-sharingweekly0.5https://docs.cwtch.im/docs/settings/experiments/group-experimentweekly0.5https://docs.cwtch.im/docs/settings/experiments/image-previews-and-profile-picturesweekly0.5https://docs.cwtch.im/docs/settings/experiments/message-formattingweekly0.5https://docs.cwtch.im/docs/settings/experiments/qrcodesweekly0.5https://docs.cwtch.im/docs/settings/experiments/server-hostingweekly0.5https://docs.cwtch.im/docs/settings/introductionweekly0.5https://docs.cwtch.im/docs/torweekly0.5https://docs.cwtch.im/security/category/connectivity--torweekly0.5https://docs.cwtch.im/security/category/cwtchweekly0.5https://docs.cwtch.im/security/category/cwtch-componentsweekly0.5https://docs.cwtch.im/security/category/cwtch-uiweekly0.5https://docs.cwtch.im/security/category/tapirweekly0.5https://docs.cwtch.im/security/components/connectivity/introweekly0.5https://docs.cwtch.im/security/components/cwtch/groupsweekly0.5https://docs.cwtch.im/security/components/cwtch/key_bundlesweekly0.5https://docs.cwtch.im/security/components/cwtch/message_formatsweekly0.5https://docs.cwtch.im/security/components/cwtch/serverweekly0.5https://docs.cwtch.im/security/components/ecosystem-overviewweekly0.5https://docs.cwtch.im/security/components/introweekly0.5https://docs.cwtch.im/security/components/tapir/authentication_protocolweekly0.5https://docs.cwtch.im/security/components/tapir/packet_formatweekly0.5https://docs.cwtch.im/security/components/ui/androidweekly0.5https://docs.cwtch.im/security/components/ui/image_previewsweekly0.5https://docs.cwtch.im/security/components/ui/inputweekly0.5https://docs.cwtch.im/security/components/ui/overlaysweekly0.5https://docs.cwtch.im/security/deploymentweekly0.5https://docs.cwtch.im/security/developmentweekly0.5https://docs.cwtch.im/security/introweekly0.5https://docs.cwtch.im/security/referencesweekly0.5https://docs.cwtch.im/security/riskweekly0.5https://docs.cwtch.im/weekly0.5 \ No newline at end of file diff --git a/build-staging/video/Group_Create.mp4 b/build-staging/video/Group_Create.mp4 new file mode 100644 index 00000000..ae82be93 Binary files /dev/null and b/build-staging/video/Group_Create.mp4 differ diff --git a/build-staging/video/Group_Invite.mp4 b/build-staging/video/Group_Invite.mp4 new file mode 100644 index 00000000..cae8629e Binary files /dev/null and b/build-staging/video/Group_Invite.mp4 differ diff --git a/build-staging/video/Group_Leave.mp4 b/build-staging/video/Group_Leave.mp4 new file mode 100644 index 00000000..ecc5a20b Binary files /dev/null and b/build-staging/video/Group_Leave.mp4 differ diff --git a/build-staging/video/Group_acceptinvite.mp4 b/build-staging/video/Group_acceptinvite.mp4 new file mode 100644 index 00000000..a5d4c740 Binary files /dev/null and b/build-staging/video/Group_acceptinvite.mp4 differ diff --git a/build-staging/video/Server_Delete.mp4 b/build-staging/video/Server_Delete.mp4 new file mode 100644 index 00000000..14831661 Binary files /dev/null and b/build-staging/video/Server_Delete.mp4 differ diff --git a/build-staging/video/Server_Keys.mp4 b/build-staging/video/Server_Keys.mp4 new file mode 100644 index 00000000..d9498451 Binary files /dev/null and b/build-staging/video/Server_Keys.mp4 differ diff --git a/build-staging/video/Server_Manage.mp4 b/build-staging/video/Server_Manage.mp4 new file mode 100644 index 00000000..3c812baa Binary files /dev/null and b/build-staging/video/Server_Manage.mp4 differ diff --git a/build-staging/video/Server_New.mp4 b/build-staging/video/Server_New.mp4 new file mode 100644 index 00000000..af57ff12 Binary files /dev/null and b/build-staging/video/Server_New.mp4 differ diff --git a/build-staging/video/group_edit.mp4 b/build-staging/video/group_edit.mp4 new file mode 100644 index 00000000..55f6af2b Binary files /dev/null and b/build-staging/video/group_edit.mp4 differ diff --git a/build-staging/video/server_edit.mp4 b/build-staging/video/server_edit.mp4 new file mode 100644 index 00000000..4ef7b18c Binary files /dev/null and b/build-staging/video/server_edit.mp4 differ